如何在WPF中获得控件以填充可用空间?
如果不指定高度,某些WPF控件(如"按钮")似乎会很高兴地消耗其容器中的所有可用空间。
还有一些,就像我现在需要使用的那样,(多行)TextBox
和ListBox
似乎更担心只占用必要的空间以适合其内容,而不再需要更多。
如果我们将这些人放在" UniformGrid"中的单元格中,它们将扩展以适应可用空间。但是,UniformGrid
实例并不适合所有情况。如果我们有一个网格,其中某些行设置为高度,以将自身与其他行之间的高度进行划分,该怎么办?如果我们有一个StackPanel,标签,列表和按钮,怎么办?如何获取列表以占用标签和按钮未占用的所有空间?
我认为这确实是一个基本的布局要求,但是我无法弄清楚如何让它们填充它们可以填充的空间(将它们放入DockPanel
并将其设置为填充也不起作用,它似乎是因为" DockPanel"仅占用其"子"控件所需的空间)。
如果我们不得不玩Height
,Width
,MinHeight
,`MinWidth等,那么可调整大小的GUI将非常可怕。
我们可以将"高度"和"宽度"属性绑定到我们占用的网格单元吗?还是有其他方法可以做到这一点?
解决方案
回答
好吧,我是在发帖后自己弄清楚的,这是最令人尴尬的方式。 :)
看来StackPanel的每个成员都会简单地填充其最小请求大小。
在DockPanel中,我以错误的顺序固定了东西。如果TextBox或者ListBox是唯一没有对齐的停靠项,或者它们是最后添加的项,则它们将根据需要填充剩余的空间。
我希望看到一种更优雅的处理方法,但是可以。
回答
我们还可以设置一些属性,以强制控件填充它的可用空间,否则它就不会填充。例如,我们可以说:
HorizontalContentAlignment="Stretch"
...强制控件的内容水平延伸。或者你可以说:
HorizontalAlignment="Stretch"
...强制控件本身水平拉伸以填充其父级。
回答
每个从" Panel"派生的控件都实现了在" Measure()"和" Arrange()"中执行的截然不同的布局逻辑:
- " Measure()"确定面板及其每个子面板的大小
Arrange()
确定每个控件渲染的矩形
DockPanel
的最后一个子元素将填充剩余的空间。我们可以通过将" LastChild"属性设置为" false"来禁用此行为。
StackPanel要求每个孩子提供所需的尺寸,然后堆叠它们。堆栈面板在每个孩子上调用Measure()
,可用大小为'Infinity',然后使用孩子所需的大小。
一个"网格"会占据所有可用空间,但是,它将把每个孩子设置为他们想要的大小,然后将它们居中放置在单元格中。
我们可以通过从"面板"派生然后覆盖" MeasureOverride()"和" ArrangeOverride()"来实现自己的布局逻辑。
请参阅本文中的一个简单示例。
回答
使用HorizontalAlignment和VerticalAlignment布局属性。他们控制元素如何使用它的父里面有空间时,更多的空间可以比它要求的元素。
例如,StackPanel的宽度将与其包含的最宽元素一样宽。因此,所有较窄的元素都有一些多余的空间。对齐属性控制子元素使用多余的空间做什么。
这两个属性的默认值为Stretch,因此子元素将被拉伸以填充所有可用空间。其他选项包括:HorizontalAlignment的左,中和右,VerticalAlignment的上,中和下。