Как использовать DockStyle.Заполнение для стандартных элементов управления в WPF?


Я привык из windows forms, что я создаю панель, помещаю в нее элементы управления и даю им DockStyle.Fill максимально увеличить их размер для окружающей панели.

В WPF я хочу иметь то же самое. У меня есть TabControl, и я хочу, чтобы его размер заполнял как можно больше формы. У меня есть ленточный элемент управления (RibbonControlsLibrary), и я хочу, чтобы остальная часть формы была заполнена TabControl в максимальном размере.

(я не хочу закреплять элементы управления, как закрепление в Visual Studio, просто старое закрепление механизмы)

4 78

4 ответа:

WPF-эквивалент DockStyle WinForms.Заполнить это:

HorizontalAlignment="Stretch" VerticalAlignment="Stretch"

Это значение по умолчанию для почти всех элементов управления, поэтому В общем случае вам не нужно ничего делать, чтобы элемент управления WPF заполнил свой родительский контейнер: они делают это автоматически. Это справедливо для всех контейнеров, которые не сжимают своих детей до минимального размера.

Распространенные Ошибки

Теперь я объясню несколько распространенных ошибок, которые мешают HorizontalAlignment="Stretch" VerticalAlignment="Stretch" работать должным образом.

1. Явная высота или ширина

Одной из распространенных ошибок является явное указание ширины или высоты элемента управления. Итак, если у вас есть это:
<Grid>
  <Button Content="Why am I not filling the window?" Width="200" Height="20" />
  ...
</Grid>

Просто удалите атрибуты Width и Height:

<Grid>
  <Button Content="Ahhh... problem solved" />
  ...
</Grid>

2. Содержащая панель сжимает управление до минимального размера

Еще одна распространенная ошибка заключается в том, что содержащая панель сжимает Ваш контроль так сильно, как только может. Например вертикальная панель StackPanel всегда будет сжимать свое содержимое вертикально как можно меньше пойдет:

<StackPanel>
  <Button Content="Why am I squished flat?" />
</StackPanel>

Переключитесь на другую панель, и вам будет хорошо:

<DockPanel>
  <Button Content="I am no longer squished." />
</DockPanel>

Кроме того, любая строка или столбец сетки, высота которых равна "Auto", будет точно так же сжимать свое содержимое в этом направлении.

Вот некоторые примеры контейнеров, которые не сжимают своих детей:

  • ContentControls никогда не сжимают своих детей (это включает в себя границы, кнопки, флажки, ScrollViewer и многие другие)
  • сетка с одной строкой и столбцом
  • сетка со строками размера"*" и колонны
  • DockPanel не сжимает своего последнего ребенка
  • TabControl не сжимает свое содержимое

Вот некоторые примеры контейнеров, которые сжимают своих детей:

  • Стекпанель сжимается в направлении своей ориентации
  • сетка с" авто " размером строки или столбца сжимается в этом направлении
  • DockPanel сжимает все, кроме своего последнего ребенка, в направлении их дока
  • TabControl сжимает свой заголовок (что отображается на tab)

3. Явная высота или ширина далее

Удивительно, сколько раз я вижу сетку или DockPanel, заданную явно по высоте и ширине, например:
<Grid Width="200" Height="100">
  <Button Content="I am unnecessarily constrainted by my containing panel" />
</Grid>

В общем случае вы никогда не хотите давать какой-либо панели явную высоту или ширину. Мой первый шаг при диагностике проблем компоновки-удалить все явные высоты или ширины, которые я могу найти.

4. Окно является SizeToContent, когда оно не должно быть

Когда вы используете SizeToContent, ваш содержимое будет сжато до минимального размера. Во многих приложениях это очень полезно и является правильным выбором. Но если ваш контент не имеет "естественного" размера, то вы, вероятно, захотите опустить SizeToContent.

Вы можете делать все, что хотите, просто сказав:DockPanel LastChildFill="True" а затем убедиться, что то, что вы хотите быть наполнителем, на самом деле является последним ребенком!

Сетка-это зверь макета, который вы можете сделать почти все, но панель DockPanel обычно является правильным выбором для вашей самой внешней панели макета. Вот пример psuedocode:
<DockPanel LastChildFill="True">
    <MyMenuBar DockPanel.Dock="Top"/>
    <MyStatus DockPanel.Dock="Bottom"/>

    <MyFillingTabControl />
</DockPanel>

Просто оберните элементы управления в сетку с двумя рядами. Сетка будет автоматически использовать все пространство, предоставленное ей, и вы можете определить строки, чтобы занять все оставшееся пространство, дав им высоту"*". Первая строка в моем примере (Height= "Auto") займет столько места, сколько нужно ленте. Надеюсь, это поможет.

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>

  <Ribbon Grid.Row="0" />

  <TabPage Grid.Row="1" />
</Grid>

Путем добавления " сетки.Ряд=.."приписывайте дочерним элементам управления сетки, которым они присваиваются в строках сетки. Тогда размер сетки будет соответствовать размеру дочерних элементов, определяемому строкой определение.

Я пробовал много методов здесь, но не могу решить свою проблему. (Заполните другой элемент управления в control)

Пока я не нашел его

<Name_Control Height="auto" Width="auto"/>
//default
//HorizontalAlignment="Stretch" 
//VerticalAlignment="Stretch"

Пример:

//UserControl:
<UserControl Name="UC_Test" Height="auto" Width="auto" />
//Grid: 
<Grid Name="Grid_test" Grid.ColumnSpan="2" Grid.Row="2" />
//Code: 
Grid_test.Children.Add(UC_Test);

Для удобства проектирования

<UserControl Name="UC_Test" Height="100" Width="100" />
//Code
Grid_test.Children.Add(UC_Test);
UC_Test.Width = Double.NaN;
UC_Test.Height = Double.NaN;