C# 为什么StackPanel不垂直拉伸其子对象?
(WPF新手)我正在查看WPF示例:C# 为什么StackPanel不垂直拉伸其子对象?,c#,.net,wpf,C#,.net,Wpf,(WPF新手)我正在查看WPF示例: <Window x:Class="Attempt_XAML.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <StackPanel> <Label Hor
<Window x:Class="Attempt_XAML.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<Label HorizontalAlignment="Center">A Button Stack</Label>
<Button HorizontalAlignment="Left">Button 1</Button>
<Button HorizontalAlignment="Right">Button 2</Button>
<Button Background="#FFA29494">Button 3</Button>
<Button>Button 4</Button>
</StackPanel>
</Window>
按钮堆
按钮1
按钮2
按钮3
按钮4
MS中的备注指出:
水平对齐和垂直对齐的默认值均为“拉伸”
StackPanel中包含的内容的垂直对齐
然而,结果看起来和我期望的不一样<代码>按钮和
标签
不是垂直伸展的,而是水平伸展的(即它们不会在两个方向上填满窗口
的整个空间),为什么 尽管堆栈面板中包含的内容的水平对齐
和垂直对齐
的默认值均为拉伸。但拉伸方向由方向属性控制
如果Orientation
设置为Vertical
,则堆栈中没有定义宽度值的所有项目仅拉伸
按钮和标签不是垂直延伸的,而是水平延伸的(即它们不会在两个方向上填满整个窗口空间),为什么
要理解原因,您至少需要对以下方面有一个基本的了解。任何面板(如StackPanel
使用测量-排列循环来决定其子元素的布局:
- 在“测量”循环中,它为每个子对象指定一个大小
- 在“排列”循环中,它在视图中定位每个子对象
StackPanel
的关键特性是它有无限的空间——如果方向是水平
,则水平空间无限,如果方向是垂直
,则垂直空间无限。换句话说,它实际上并不关注可用的大小(在其方向上),而是声称拥有无限的空间。因此,回到您的示例,即使子对象的垂直对齐可能是拉伸,但它们实际上无法拉伸到无限大
如果您需要一个延伸其子面板以填充可用空间的面板,那么栅格
就是一个很好的例子(默认情况下,栅格将为每个子面板分配相等的总高度份额,或者您可以使用来调整比例)。如果需要特殊的布局行为,也可以考虑创建自己的自定义面板。
编辑
澄清“无限空间”:我的意思是StackPanel
告诉它的子级有无限的可用空间。如果你是一个按钮、标签等,并且有无限的可用空间,你会怎么做?你可能只需要占用你所需要的最小空间,即使你的垂直排列是“伸展”的,对吗?事情就是这样。与网格不同,网格告诉子控件它们有x(有限)的空间——在这种情况下,按钮、标签等将填满所有空间(如果它们的垂直对齐是“拉伸”)
为了说明上述内容,以此自定义控件为例:
public class TestControl : ContentControl
{
public string Description { get; set; }
protected override Size MeasureOverride(Size availableSize)
{
System.Diagnostics.Debug.WriteLine("Size available for '" + Description + "': " + availableSize.Height);
return base.MeasureOverride(availableSize);
}
}
这实际上没有做任何事情,只是报告分配给它的空间大小。现在,将测试控件放置在网格
和堆栈面板
中,并比较:
<Grid Height="50">
<Grid.RowDefinition />
<Grid.RowDefinition />
<local:TestControl Description="in Grid" />
<StackPanel Grid.Row="1" Height="10">
<local:TestControl Description="in StackPanel" />
</StackPanel>
</Grid>
您将看到,网格
将其CustomPanel(上面的第一个)的高度指定为25(其高度的一半)。但是,StackPanel
为其CustomPanel指定了一个无限高。请查看StackPanel
的Orientation
属性。此外,请记住,此面板将只使用其内容所需的空间。当您说无限水平空间
,您的意思是它将最大宽度
和最大高度
设置为无限
?W/H设置为“自动”。@newprint否,这是不同的。“高度/宽度”属性可能会影响面板分配给其子面板的空间量——但在StackPanel的情况下,它总是为其子面板分配无限空间。请看我上面的编辑。感谢详细的回答。可惜这些信息都没有出现在官方文件中。全部信息。关于Orientation
property只是一句话。