Как использовать DockStyle.Fill для стандартных элементов управления в WPF? - PullRequest
87 голосов
/ 09 июля 2010

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

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

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

Ответы [ 4 ]

174 голосов
/ 11 июля 2010

WPF-эквивалент WinForms DockStyle.Fill:

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>

Просто удалите атрибуты ширины и высоты:

<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>

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

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

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

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

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

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

Удивительно, сколько раз я вижу Grid или DockPanel с заданной высотой и шириной, например:

<Grid Width="200" Height="100">
  <Button Content="I am unnecessarily constrainted by my containing panel" />
</Grid>

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

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

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

7 голосов
/ 10 июля 2010

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

Grid - это зверь макета, который вы можете сделать практически любым, но DockPanel обычно является правильным выбором для вашей внешней панели макетов. Вот пример psuedocode:

<DockPanel LastChildFill="True">
    <MyMenuBar DockPanel.Dock="Top"/>
    <MyStatus DockPanel.Dock="Bottom"/>

    <MyFillingTabControl />
</DockPanel>
5 голосов
/ 09 июля 2010

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

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

  <Ribbon Grid.Row="0" />

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

Добавляя атрибут «Grid.Row = ..» к дочерним элементам управления сетки, они назначаются для строк сетки. Затем сетка будет иметь размер дочерних элементов в соответствии с определениями строк.

0 голосов
/ 24 ноября 2016

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

Пока я не нашел это

<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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...