Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why StackPanel does not stretch its children vertically?

Tags:

c#

.net

wpf

(new to WPF) I am looking over the WPF example:

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

The default value is stretch for both HorizontalAlignment and VerticalAlignment of content that is contained in a StackPanel.

However, result looks different from what I am expecting. Button and Label are not stretched out vertically, but only horizontally(i.e they don't fill the entire space of Window in both directions) Why ?

like image 722
newprint Avatar asked Jan 30 '14 23:01

newprint


2 Answers

Button and Label are not stretched out vertically, but only horizontally(i.e 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. Any Panel such as a StackPanel uses a measure-arrange cycle to decide on a layout for its child elements:

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

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). 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. What do you do if you are a Button, Label, etc, and there is infinite space available? You probably just take up the minimum space you need, even if your VerticalAlignment is "Stretch", right? 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").

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:

<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). The StackPanel, though, assigns its CustomPanel a height of Infinity.

like image 114
McGarnagle Avatar answered Sep 29 '22 16:09

McGarnagle


Although default value is stretch for both HorizontalAlignment and VerticalAlignment of Content that is contained in a StackPanel. But in which direction to stretch is controlled by Orientation Property.

If Orientation is set to Vertical then all the items of the stack with no defined width value are stretched only.

like image 38
Adnan Umer Avatar answered Sep 29 '22 16:09

Adnan Umer