Как получить элементы управления в WPF для заполнения свободного пространства?

Некоторые элементы управления WPF (например, Button), похоже, с удовольствием потребляют все доступные пространства в своем контейнере, если вы не указали высоту, которую он должен иметь.

И некоторые, как те, которые мне нужно использовать прямо сейчас, (многострочные) TextBox и ListBox кажутся более тревожными, просто занимая пространство, необходимое для их содержимого, и не более того.

Если вы разместите этих парней в ячейке в UniformGrid, они будут расширяться, чтобы соответствовать доступному пространству. Однако экземпляры UniformGrid не подходят для всех ситуаций. Что делать, если у вас есть сетка с несколькими строками, установленными на высоту *, чтобы разделить высоту между собой и другими * строками? Что, если у вас есть StackPanel, и у вас есть Label, a List и Button, как вы можете получить список, чтобы занять все пространство, не съеденное ярлыком и кнопкой?

Я бы подумал, что это действительно будет основным требованием к макету, но я не могу понять, как заставить их заполнить пространство, которое они могли бы (помещая их в DockPanel и устанавливать его для заполнения также не кажется, работает, поскольку DockPanel занимает только пространство, необходимое для его "субконтроля".

Изменчивый GUI был бы ужасно, если бы вам пришлось играть с Height, Width, MinHeight, MinWidth и т.д.

Можете ли вы привязать свои свойства Height и Width к ячейке сетки, которую вы занимаете? Или есть другой способ сделать это?

Ответ 1

Каждый элемент управления, полученный из Panel, реализует различную логику компоновки, выполненную в Measure() и Arrange():

  • Measure() определяет размер панели и каждого из ее дочерних элементов
  • Arrange() определяет прямоугольник, в котором каждый элемент управления отображает

Последний дочерний элемент DockPanel заполняет оставшееся пространство. Вы можете отключить это поведение, установив для свойства LastChild значение false.

StackPanel запрашивает у каждого ребенка желаемый размер и затем складывает их. Панель стека вызывает Measure() для каждого дочернего элемента с доступным размером Infinity, а затем использует желаемый размер для ребенка.

A Grid занимает все свободное пространство, однако он будет устанавливать каждый дочерний элемент в желаемый размер, а затем центрировать их в ячейке.

Вы можете реализовать свою собственную логику компоновки, исходя из Panel, а затем переопределяя MeasureOverride() и ArrangeOverride().

См. эту статью для простого примера.

Ответ 2

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

HorizontalContentAlignment="Stretch"

... заставить содержимое элемента управления растягиваться горизонтально. Или вы можете сказать:

HorizontalAlignment="Stretch"

... заставить сам элемент управления растягиваться горизонтально, чтобы заполнить его родитель.

Ответ 3

Хорошо, я понял это сам, сразу после публикации, что является самым неудобным способом.:)

Кажется, каждый член StackPanel просто заполнит свой минимальный требуемый размер.

В DockPanel я состыковал вещи в неправильном порядке. Если TextBox или ListBox являются единственным прикрепленным элементом без выравнивания, или если они добавлены последним, они будут заполнять оставшееся пространство по мере необходимости.

Мне бы хотелось увидеть более элегантный способ справиться с этим, но он будет делать.

Ответ 4

Используйте свойства макета HorizontalAlignment и VerticalAlignment. Они контролируют, как элемент использует пространство, которое у него есть внутри своего родителя, когда доступно больше места, чем требуется элементу.

Ширина StackPanel, например, будет такой же широкой, как и самый широкий ее элемент. Таким образом, все более узкие элементы имеют немного избыточного пространства. Свойства выравнивания управляют тем, что делает дочерний элемент с дополнительным пространством.

Значением по умолчанию для обоих свойств является Stretch, поэтому дочерний элемент растягивается, чтобы заполнить все свободное пространство. Дополнительные параметры включают Left, Center и Right для HorizontalAlignment и Top, Center и Bottom для VerticalAlignment.