为什么StackPanel不会垂直伸展它的孩子?

时间:2014-01-30 23:01:45

标签: 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 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>

MS中的备注说明:

  

Horizo​​ntalAlignment和的默认值都是拉伸   StackPanel中包含的内容的VerticalAlignment。

然而,结果看起来与我期待的不同。 ButtonLabel不是垂直延伸,而只是水平延伸(即它们不会在两个方向上填充Window的整个空间)为什么?

2 个答案:

答案 0 :(得分:10)

  

按钮和标签不是垂直拉伸,而是仅水平拉伸(即它们不会在两个方向上填充窗口的整个空间)为什么?

要了解原因,您至少需要对Panels有一个基本的了解。任何面板(如StackPanel)都使用度量排列周期来决定其子元素的布局:

  • 在“测量”周期中,它为每个孩子分配一个大小
  • 在“排列”周期中,它将每个孩子定位在其视图中

StackPanel的关键特征是它具有无限空间 - 如果其方向为Horizontal则为无限水平空间,如果为Vertical则为无限垂直空间。换句话说,它实际上并没有注意它可用的尺寸(朝向它的方向),而是声称一个无限的空间。因此,回到你的例子,即使孩子的VerticalAlignment可能是Stretch,他们实际上也无法伸展到无限大。

如果您需要一个可以伸展其子项以填充可用空间的面板,那么Grid就是一个很好的例子(默认情况下,网格将为每个孩子分配相等的总高度 - 或者您可以使用star sizing来调整比例)。如果您需要专门的布局行为,也可以考虑创建自己的自定义面板。


修改

澄清“无限空间”:我的意思是StackPanel告诉孩子们有无限空间可用。如果你是一个Button,Label等,你会怎么做?并且有无限的可用空间?你可能只占用你需要的最小空间,即使你的VerticalAlignment是“拉伸”,对吧?这就是发生的事情。与Grid对比,它告诉子控件它们有x(有限)空间量 - 在这种情况下,Button,Label等将填充所有该空间(如果它们的VerticalAlignment是“拉伸”)。

为了说明上述情况,请以此自定义控件为例:

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);
    }
}

这实际上并没有做任何事情,只是报告已经分配了多少空间。现在,将测试控件放在GridStackPanel中,然后比较:

<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>

您会看到Grid将其CustomPanel(上面的第一个)指定为25(高度的一半)的高度。但是,StackPanel会将其CustomPanel指定为无限高度。

答案 1 :(得分:1)

虽然HorizontalAlignment中包含的VerticalAlignmentContent的{​​{1}}和StackPanel的默认值都已延长。但伸展的方向由Orientation属性控制。

如果Orientation设置为Vertical,那么堆栈中没有定义宽度值的所有项目都将被拉伸。