【问题标题】:How to get controls in WPF to fill available space?如何在 WPF 中获取控件以填充可用空间?
【发布时间】:2010-09-07 08:35:59
【问题描述】:

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

还有一些,比如我现在需要使用的那些,(多行)TextBoxListBox 似乎更担心只占用适合其内容所需的空间,仅此而已。

如果你把这些家伙放在UniformGrid 的一个单元格中,它们会扩展以适应可用空间。但是,UniformGrid 实例并不适用于所有情况。如果您有一个网格,其中一些行设置为 * 高度以在其自身和其他 * 行之间划分高度怎么办?如果你有一个StackPanel,你有一个Label,一个List和一个Button,你怎么能让列表占据标签和按钮没有占用的所有空间?

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

如果你不得不使用HeightWidthMinHeightMinWidth 等,那么可调整大小的 GUI 将非常糟糕。

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

【问题讨论】:

  • UniformGrid 太棒了,我的新默认 goto 标签。我喜欢 Stackpanels 的简单性(让我想起了 div),但 Uniform Grid 正是我需要的。
  • 重新统一网格。重点是统一。似乎您无法调整列宽和行高。仅当每条内容的大小相同时才适用。我用一个 Grid 替换了我的 StackPanel,然后 Stretch 就按我的预期工作了。
  • This article 帮助我拉伸文本框。

标签: wpf user-interface layout


【解决方案1】:

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

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

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

StackPanel 询问每个孩子所需的尺寸,然后将它们堆叠起来。堆栈面板对每个孩子调用Measure(),可用大小为Infinity,然后使用孩子所需的大小。

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

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

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

【讨论】:

  • @user3690202 Archive.org 是您的朋友。链接已恢复。
  • 主题在MSDN中依然存在,但链接改为:docs.microsoft.com/en-us/dotnet/framework/wpf/controls/…
  • The last child of the DockPanel fills the remaining space:这是我理解的缺失的关键。我一直认为没有显式 Dock 的元素填充了空间。
【解决方案2】:

嗯,我自己在发帖后自己想通了,这是最尴尬的方式。 :)

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

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

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

【讨论】:

  • 我只想指出(关于这个老问题!)“没有对齐”是这里的一个关键词,至少对我来说是这样。
【解决方案3】:

使用 Horizo​​ntalAlignmentVerticalAlignment 布局属性。当可用空间超过元素所需时,它们控制元素如何使用其父元素内部的空间。

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

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

【讨论】:

  • 如果这总是正确的,那么原始问题就不会被问到。以带有标签和文本框的水平 StackPanel 为例。文本框右侧有额外的空间。文本框设置为自动宽度。为 Horizo​​ntalAlignment 设置 Stretch 不会使 TextBox 填充剩余空间。
  • 没有什么总是正确的,但这个答案可以满足我的需求:DockPanel、Image。
【解决方案4】:

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

HorizontalContentAlignment="Stretch"

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

HorizontalAlignment="Stretch"

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

【讨论】:

  • 在所有这些案例中提到的最臭名昭著的面板是 StackPanel。它不包含 ContentAlignment 属性,并且将其子级设置为 Stretch 将不会在星形网格内产生任何影响。非常令人沮丧。几乎就像 StackPanel 是 WPF 团队编写的第一个容器一样,它因此受到影响。
  • @Brent - 啊!我一直试图让我的堆栈面板的内容正确填充。谢谢!我认为这只是我做错了。
  • @townsean Stack 面板非常有限,您可以通过使用 UniformGrid 并将 Rows 或 Columns 设置为 0 进行拉伸来获得类似的行为
  • @Tuskan360 UniformGrid 只允许单元格大小相同。我最后使用了一个网格,似乎工作。恼人的是 StackPanel 并没有按照它的设计意图去做。
  • @TarkaDaal yeh,UniformGrid 如果所有内容的大小相同,则 Grid 如果您想指定复杂的相对大小,堆叠面板以根据内容调整大小并忽略可用空间。
猜你喜欢
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 2018-03-16
  • 1970-01-01
  • 2010-11-21
  • 1970-01-01
  • 2021-07-09
  • 1970-01-01
相关资源
最近更新 更多