How to: Choose between StackPanel and DockPanel
Although you can use either DockPanel or StackPanel to stack child elements, the two controls do not always produce the same results. For example, the order that you place child elements can affect the size of child elements in a DockPanel but not in a StackPanel. This different behavior occurs because StackPanel measures in the direction of stacking at Double.PositiveInfinity; however, DockPanel measures only the available size.
The examples in this article create a Grid with two panels, which looks like the following image:
XAML example
The following example demonstrates the key difference between DockPanel and StackPanel when designing a page in XAML.
<Grid Width="175" Height="150">
<Grid.Resources>
<ControlTemplate x:Key="EmojiViewBox" TargetType="{x:Type ContentControl}">
<Viewbox>
<Border Background="LightGray" BorderBrush="Black" BorderThickness="0.5">
<TextBlock Foreground="Red">💕</TextBlock>
</Border>
</Viewbox>
</ControlTemplate>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<DockPanel Grid.Column="0" Grid.Row="0">
<ContentControl Template="{StaticResource EmojiViewBox}" />
<ContentControl Template="{StaticResource EmojiViewBox}" />
<ContentControl Template="{StaticResource EmojiViewBox}" />
</DockPanel>
<StackPanel Grid.Column="0" Grid.Row="1" Orientation="Horizontal">
<ContentControl Template="{StaticResource EmojiViewBox}" />
<ContentControl Template="{StaticResource EmojiViewBox}" />
<ContentControl Template="{StaticResource EmojiViewBox}" />
</StackPanel>
</Grid>
Code-based example
The following example demonstrates the key difference between DockPanel and StackPanel. This code is run in the Window.Loaded
event handler:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Grid gridContainer = new Grid()
{
Width = 175,
Height = 150
};
// Template to generate the content
ControlTemplate viewBoxTemplate = (ControlTemplate)System.Windows.Markup.XamlReader.Parse(@"
<ControlTemplate TargetType=""ContentControl"" xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"">
<Viewbox>
<Border Background=""LightGray"" BorderBrush=""Black"" BorderThickness=""0.5"">
<TextBlock Foreground=""Red"">💕</TextBlock>
</Border>
</Viewbox>
</ControlTemplate>
");
gridContainer.RowDefinitions.Add(new RowDefinition());
gridContainer.RowDefinitions.Add(new RowDefinition());
// Dock panel
DockPanel panel1 = new DockPanel();
Grid.SetRow(panel1, 0);
// Create the three controls for the panel
panel1.Children.Add(new ContentControl() { Template = viewBoxTemplate });
panel1.Children.Add(new ContentControl() { Template = viewBoxTemplate });
panel1.Children.Add(new ContentControl() { Template = viewBoxTemplate });
// Add the dock panel to the grid
gridContainer.Children.Add(panel1);
// Stack panel
StackPanel panel2 = new StackPanel();
panel2.Orientation = Orientation.Horizontal;
Grid.SetRow(panel2, 1);
// Create the three controls for the panel
panel2.Children.Add(new ContentControl() { Template = viewBoxTemplate });
panel2.Children.Add(new ContentControl() { Template = viewBoxTemplate });
panel2.Children.Add(new ContentControl() { Template = viewBoxTemplate });
// Add the dock panel to the grid
gridContainer.Children.Add(panel2);
// Set the grid as the content of this window or page
Content = gridContainer;
}
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
Dim gridContainer As New Grid() With {.Width = 175, .Height = 150}
' Template to generate the content
Dim viewBoxTemplate As ControlTemplate = DirectCast(Markup.XamlReader.Parse("
<ControlTemplate TargetType=""ContentControl"" xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"">
<Viewbox>
<Border Background=""LightGray"" BorderBrush=""Black"" BorderThickness=""0.5"">
<TextBlock Foreground=""Red"">💕</TextBlock>
</Border>
</Viewbox>
</ControlTemplate>"), ControlTemplate)
gridContainer.RowDefinitions.Add(New RowDefinition())
gridContainer.RowDefinitions.Add(New RowDefinition())
' Dock panel
Dim panel1 As New DockPanel()
Grid.SetRow(panel1, 0)
' Create the three controls for the panel
panel1.Children.Add(New ContentControl() With {.Template = viewBoxTemplate})
panel1.Children.Add(New ContentControl() With {.Template = viewBoxTemplate})
panel1.Children.Add(New ContentControl() With {.Template = viewBoxTemplate})
' Add the dock panel to the grid
gridContainer.Children.Add(panel1)
' Stack panel
Dim panel2 As New StackPanel() With {.Orientation = Orientation.Horizontal}
Grid.SetRow(panel2, 1)
' Create the three controls for the panel
panel2.Children.Add(New ContentControl() With {.Template = viewBoxTemplate})
panel2.Children.Add(New ContentControl() With {.Template = viewBoxTemplate})
panel2.Children.Add(New ContentControl() With {.Template = viewBoxTemplate})
' Add the dock panel to the grid
gridContainer.Children.Add(panel2)
'Set the grid as the content of this window or page
Content = gridContainer
End Sub
See also
.NET Desktop feedback