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


303

Button如果不指定高度,某些WPF控件(如)似乎会很高兴地消耗其容器中的所有可用空间。

还有一些,例如我现在需要使用的(多行)TextBox,并且ListBox似乎更担心仅占用必要的空间以适合其内容,而不再担心。

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

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

一个可调整大小的GUI将是相当可怕的,如果你有一起玩HeightWidthMinHeightMinWidth等。

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


1
UniformGrid很棒,我的新默认goto标签。我喜欢Stackpanels的简单性(使我想起了div),但是Uniform Grid正是我所需要的。
Terrance'8

重新UniformGrid。重点是制服。似乎您无法调整列宽或行高。仅当每个内容的大小相同时才适用。我用网格替换了StackPanel,然后Stretch按照我的预期工作了。
pdschuller

本文帮助我拉伸了文本框。
jpaugh

Answers:


162

每个派生自的控件都Panel实现在Measure()和中执行的独特布局逻辑Arrange()

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

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

StackPanel要求每个孩子的所需的大小,然后堆叠它们。堆栈面板调用Measure()每个可用大小为Infinity的孩子,然后使用孩子的所需大小。

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

您可以通过派生Panel然后重写MeasureOverride()和来实现自己的布局逻辑ArrangeOverride()

请参阅本文中的一个简单示例。


8
链接现已
消失

6
@ user3690202 Archive.org是您的朋友。链接已恢复。
鲁芬

4
主题仍然存在于MSDN,但链接改成这样:docs.microsoft.com/en-us/dotnet/framework/wpf/controls/...
安德烈Antonangeli

2
The last child of the DockPanel fills the remaining space:这是我无法理解的关键。我总是将没有显式Dock的元素填满整个空间。
斑点

238

您还可以设置一些属性,以强制控件填充它的可用空间,否则它就不会填充。例如,您可以说:

HorizontalContentAlignment="Stretch"

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

HorizontalAlignment="Stretch"

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


88
在所有这些情况下,最臭名昭著的面板是StackPanel。它不包含ContentAlignment属性,并且将其子级设置为Stretch将不会在星形网格内起作用。非常沮丧。这几乎就像StackPanel是WPF团队编写的第一个容器一样,情况确实如此。
布伦特Schooley

4
@Brent-啊!我一直试图使我的stackpanel的内容正确填充。谢谢!我以为那是我做错的事情。
Ashley Grenon 2010年

8
@townsean堆栈面板是非常有限的,你可以得到类似的行为与使用UniformGrid行或列拉伸和设置为0
ForbesLindesay

2
@ Tuskan360 UniformGrid仅允许像元大小相同。我最终使用了Grid,似乎可以正常工作。令人讨厌的StackPanel如何不执行它的设计目标。
TarkaDaal 2012年

4
@TarkaDaal是的,如果一切都相同,则使用UniformGrid;如果要指定复杂的相对大小,则使用Grid;将堆栈面板设置为仅基于内容的大小,并忽略可用空间。
福布斯林德赛(ForbesLindesay)2012年

18

好吧,我是在发帖后自己弄清楚的,这是最令人尴尬的方式。:)

看来StackPanel的每个成员都会简单地填充其最小请求大小。

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

我希望看到一种更优雅的处理方法,但是可以。


我只想指出(关于这个老问题!)“无对齐”是这里的关键短语,至少对我来说是这样。
MikeBaz-MSFT

4

使用Horizo​​ntalAlignmentVerticalAlignment布局属性。它们控制元素在可用空间超出元素所需的空间时如何使用其父元素中的空间。

例如,StackPanel的宽度将与其包含的最宽元素一样宽。因此,所有较窄的元素都有一些多余的空间。对齐属性控制子元素使用多余的空间做什么。

这两个属性的默认值为Stretch,因此子元素将被拉伸以填充所有可用空间。其他选项包括左,中,右为的Horizo​​ntalAlignment和顶部,中部和底部VerticalAlignment


31
如果始终都是这样,那么就不会提出原始问题。以带有标签和文本框的水平StackPanel为例。在文本框的右边有多余的空间。文本框设置为自动宽度。设置“ Horizo​​ntalAlignment”的“拉伸”将不会使文本框填充剩余空间。
布伦特Schooley

并非总是如此,但是这个答案可以满足我的需求:DockPanel,Image。
alehro
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.