如何在WPF中获取控件以填充可用空间?

时间:2008-08-30 16:39:28

标签: wpf user-interface layout

如果你没有指定它的高度,某些WPF控件(比如Button)似乎很乐意消耗其容器中的所有可用空间。

有些人,就像我现在需要使用的那些,(多线)TextBoxListBox似乎更担心只是占用适合其内容所需的空间,而不是更多。

如果你将这些人放在UniformGrid的单元格中,他们会扩展以适应可用空间。但是,UniformGrid个实例并不适合所有情况。如果你有一个网格,其中一些行设置为*高度,以划分自身与其他*行之间的高度,该怎么办?如果你有一个StackPanel而且你有一个Label,一个List和一个Button怎么办?如何获取该列表以占用所有未被其占用的空间标签和按钮?

我认为这确实是一个基本的布局要求,但我无法弄清楚如何让它们填充他们可以填充的空间(将它们放入DockPanel并将其设置为填充也不会似乎工作,因为DockPanel只占用了'子控件'所需的空间。

如果您必须使用HeightWidthMinHeightMinWidth等,那么可调整大小的GUI会非常糟糕。

您可以将HeightWidth属性绑定到您占用的网格单元吗?还是有另一种方法可以做到这一点吗?

4 个答案:

答案 0 :(得分:214)

还有一些属性可以设置为强制控件填充其可用空间,否则不会这样做。例如,您可以说:

HorizontalContentAlignment="Stretch"

...强制控件的内容水平拉伸。或者你可以说:

HorizontalAlignment="Stretch"

...强制控件本身水平拉伸以填充其父级。

答案 1 :(得分:151)

源自 Panel 的每个控件都实现了在Measure()Arrange()中执行的不同布局逻辑:

  • Measure()确定面板及其每个子项的大小
  • Arrange()确定每个控件呈现的矩形

DockPanel 的最后一个孩子填补剩余空间。您可以通过将LastChild属性设置为false来禁用此行为。

StackPanel 会询问每个孩子所需的大小,然后将其叠加。堆栈面板会为每个孩子调用Measure(),其可用大小为Infinity,然后使用孩子所需的大小。

Grid 占用所有可用空间,但是,它会将每个孩子设置为所需的大小,然后将其置于单元格中。

您可以通过从Panel派生,然后覆盖MeasureOverride()ArrangeOverride()来实现您自己的布局逻辑。

有关简单示例,请参阅this article

答案 2 :(得分:17)

嗯,我发布后就知道了,这是最令人尴尬的方式。 :)

似乎StackPanel的每个成员都会填充其最小请求大小。

在DockPanel中,我以错误的顺序停靠了东西。如果TextBox或ListBox是唯一没有对齐的停靠项,或者它们是最后添加的,它们将按需填充剩余空间。

我希望看到一种更优雅的方法来处理这个问题,但它会做到。

答案 3 :(得分:1)

使用 Horizo​​ntalAlignment VerticalAlignment 布局属性。它们控制元素在可用空间多于元素所需的空间时如何使用它在父节点内的空间。

例如,StackPanel的宽度将与它包含的最宽元素一样宽。因此,所有较窄的元素都有一些过剩的空间。对齐属性控制子元素对额外空间的作用。

两个属性的默认值是Stretch,因此子元素被拉伸以填充所有可用空间。其他选项包括 Horizo​​ntalAlignment 的Left,Center和Right以及 VerticalAlignment 的Top,Center和Bottom。