ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

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

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

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

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

M
Matt Hamilton

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

HorizontalContentAlignment="Stretch"

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

HorizontalAlignment="Stretch"

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


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

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 的元素填充了空间。
R
RJFalconer

好吧,我自己在发帖后就自己想出来了,这是最尴尬的方式。 :)

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

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

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


我只想指出(关于这个老问题!)“没有对齐”是这里的一个关键词,至少对我来说是这样。
u
urini

使用 HorizontalAlignment 和 VerticalAlignment 布局属性。当可用空间多于元素所需的空间时,它们控制元素如何使用其父元素内部的空间。

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

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


如果这总是正确的,那么最初的问题就不会被问到。以带有标签和文本框的水平 StackPanel 为例。文本框右侧有额外的空间。文本框设置为自动宽度。为 HorizontalAlignment 设置 Stretch 不会使 TextBox 填充剩余空间。
没有什么总是正确的,但这个答案适合我的需要:DockPanel,Image。