Why StackPanel does not stretch its children vertically?
.net, c#, wpf
Solution
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.
Problem
(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 ?