(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 ?
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:
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With