简体   繁体   English

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

[英]Why StackPanel does not stretch its children vertically?

(new to WPF) I am looking over the WPF example: (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>

Remark in MS notes that: MS中的备注说明:

The default value is stretch for both HorizontalAlignment and VerticalAlignment of content that is contained in a StackPanel. 对于StackPanel中包含的内容的Horizo​​ntalAlignment和VerticalAlignment,默认值为stretch。

However, result looks different from what I am expecting. 但是,结果看起来与我期望的不同。 Button and Label are not stretched out vertically, but only horizontally(ie they don't fill the entire space of Window in both directions) Why ? ButtonLabel不是垂直拉伸,而是仅水平拉伸(即它们不会在两个方向上填充Window的整个空间)为什么?

Button and Label are not stretched out vertically, but only horizontally(ie they don't fill the entire space of Window in both directions) Why ? 按钮和标签不是垂直拉伸,而是仅水平拉伸(即它们不会在两个方向上填充窗口的整个空间)为什么?

To understand the reason, you really need at least a basic understanding of Panels . 要了解原因,您至少需要对Panels有一个基本的了解。 Any Panel such as a StackPanel uses a measure-arrange cycle to decide on a layout for its child elements: 任何Panel(如StackPanel使用度量排列周期来决定其子元素的布局:

  • in the "measure" cycle, it assigns a size to each child 在“测量”周期中,它为每个孩子分配一个大小
  • in the "arrange" cycle, it positions each child in its view 在“排列”循环中,它将每个孩子定位在其视图中

The key feature of a StackPanel is that it has infinite space -- infinite horizontal space if its orientation is Horizontal , and infinite vertical space if Vertical . 一的关键特征StackPanel是,它具有无限空间-无限的水平空间,如果它的方向是Horizontal和垂直的无限空间,如果Vertical In other words, it does not actually pay attention to the size available to it (in the direction of its orientation), but claims an infinite space. 换句话说,它实际上并没有注意它可用的尺寸(朝向它的方向),而是声称一个无限的空间。 So therefore, coming back to your example, even though the VerticalAlignment of the children may be Stretch , they cannot actually be stretched out to an infinite size. 因此,回到您的示例,即使子项的VerticalAlignment可能是Stretch ,它们实际上也不能伸展到无限大小。

If you need a panel that stretches out its children to fill the available space, then Grid is a good example (by default the Grid will assign an equal share of the total height to each child -- or you can use the star sizing to adjust the proportions). 如果你需要一个可以拉伸其子项以填充可用空间的面板,那么Grid就是一个很好的例子(默认情况下,Grid将为每个孩子分配相等的总高度 - 或者你可以使用星形大小来调整比例)。 You could also consider creating your own custom Panel, if you need a specialized layout behavior. 如果您需要专门的布局行为,还可以考虑创建自己的自定义面板。


Edit 编辑

To clarify "infinite space": what I mean is that the StackPanel tells its children that there is infinite space available. 澄清“无限空间”:我的意思是StackPanel告诉它的孩子有无限的可用空间。 What do you do if you are a Button, Label, etc, and there is infinite space available? 如果你是一个Button,Label等,你会怎么做?并且有无限的可用空间? You probably just take up the minimum space you need, even if your VerticalAlignment is "Stretch", right? 你可能只占用你需要的最小空间,即使你的VerticalAlignment是“拉伸”,对吧? That's what happens. 这就是发生的事情。 Contrast to a Grid, which tells the child controls that they have x (finite) amount of space -- in that case, a Button, Label, etc, will fill up all that space (if their VerticalAlignment is "Stretch"). 与Grid对比,它告诉子控件它们具有x(有限)空间量 - 在这种情况下,Button,Label等将填满所有空间(如果它们的VerticalAlignment是“Stretch”)。

To illustrate the above, take this custom control as an example: 为了说明上述情况,请以此自定义控件为例:

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

This doesn't actually do anything, just reports how much space has been allocated to it. 这实际上没有做任何事情,只报告已经分配了多少空间。 Now, place the test control in a Grid and a StackPanel , and compare: 现在,将测试控件放在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>

You'll see that the Grid assigns its CustomPanel (the first one above) a height of 25 (half its height). 您将看到Grid将其CustomPanel(上面的第一个)指定为25(高度的一半)的高度。 The StackPanel , though, assigns its CustomPanel a height of Infinity. 但是, StackPanel将其CustomPanel指定为Infinity的高度。

Although default value is stretch for both HorizontalAlignment and VerticalAlignment of Content that is contained in a StackPanel . 虽然默认值是两个拉伸HorizontalAlignmentVerticalAlignmentContent包含在一个StackPanel But in which direction to stretch is controlled by Orientation Property. 但拉伸的方向由Orientation Property控制。

If Orientation is set to Vertical then all the items of the stack with no defined width value are stretched only. 如果“ Orientation设置为“ Vertical则仅拉伸没有定义宽度值的堆栈的所有项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM