WPF Standard Control Demo App › StackPanel

StackPanel Layout

StackPanel places its children one after another in a single row or column. It is the simplest panel, and the one whose sizing most often surprises.

Unlimited space in the stacking direction

A StackPanel gives each child unlimited space in the stacking direction. In a vertical panel 200 × 100, a child was measured with 200 × Infinity; in a horizontal one, with Infinity × 100. In the other direction the child is stretched: a child that wanted 40 × 20 was arranged 200 wide in the vertical panel and 100 high in the horizontal one.

Why a list in a vertical StackPanel stops scrolling

Because of the unlimited space, a list in a vertical StackPanel does not get a limited height. A ListBox of 1000 items in an area 200 high was 200 high, could scroll by 991, and created 10 items. Put inside a vertical StackPanel in the same area, it grew to 19964 high, could not scroll, and created all 1000 items. The article linked below shows the same for a ScrollViewer. Give a list that should scroll a limited height instead, for example a Grid row.

A StackPanel itself does not virtualize either. With 1000 children in a StackPanel inside a ScrollViewer 200 high, all 1000 were measured, while a ListBox with a limited height created only the items it showed. Use a ListBox rather than a StackPanel for long lists.

Children never wrap, and the overflow is cut off

The default Orientation is Vertical, and children never wrap. With the demo app’s three labels in a horizontal StackPanel 80 wide, the third label started at 94.69, past the panel’s edge. The part beyond the edge is cut off: ClipToBounds was False, but WPF’s layout clip limited the panel to its 80, and a hit test on the third label beyond that edge found nothing. Use WrapPanel to wrap. There is also no Spacing property; space children with their Margin.

The empty area and ZIndex

The demo app shows an empty StackPanel 30 high. With the default Background of null, a hit test in its middle found nothing, so clicks there go to what is behind it. With Transparent or a color, the same hit test found the panel.

Where children overlap, Panel.ZIndex decides which one is drawn on top. In the demo app, the second label overlaps the first by 15. With ZIndex 1 and 2, the second label was on top at the overlap; with 3 and 2, the first. It only orders children of the same panel: a child of an inner panel with ZIndex="100" stayed under a sibling of that inner panel whose ZIndex was 0.

case measured
default Orientation / Spacing property Vertical / none
Vertical, panel 200 x 100: size given to the child / child's arranged size (desired 40 x 20) 200 x Infinity / 200 x 20
Horizontal, panel 200 x 100: size given to the child / child's arranged size (desired 40 x 20) Infinity x 100 / 40 x 100
Horizontal, the demo's 3 labels, Width 80: last label x / ClipToBounds / layout clip width 94.69 / False / 80
hit test on the last label, outside the 80 (nothing)
1000 children in a StackPanel in a ScrollViewer 200 high: children measured 1000
1000-item ListBox in 200 high, directly: height / ScrollableHeight / items created 200 / 991 / 10
1000-item ListBox in 200 high, inside a vertical StackPanel: height / ScrollableHeight / items created 19964 / 0 / 1000
empty StackPanel 30 high, Background=null: hit test in the middle (nothing)
empty StackPanel 30 high, Background=Transparent: hit test in the middle Panel
empty StackPanel 30 high, Background=AliceBlue: hit test in the middle Panel
demo labels, ZIndex Item1=1, Item2=2: element on top where they overlap Item2
demo labels, ZIndex Item1=3, Item2=2: element on top where they overlap Item1
child of an inner panel with ZIndex=100 vs the inner panel's sibling (ZIndex 0): on top OuterSibling

Sizes given to children, overflow, background, and ZIndex. Measured on .NET 10 / Windows 11.

Trying it in the demo app

The StackPanel page of the demo app, with the control list on the left and the first section, Orientation

The StackPanel page of the demo app has three sections: Orientation, Background, and ZIndex. The “Show Code” link under each section displays its XAML. The following XAML is the ZIndex section (StackPanelUsageControl.xaml), with the styles and the surrounding GroupBoxes left out and the namespace declarations added:

<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <TextBox x:Name="ZIndexItem1Text" Text="1" />
  <TextBox x:Name="ZIndexItem2Text" Text="2" />

  <StackPanel x:Name="ZIndexStackPanel">
    <Label VerticalAlignment="Top"
           Panel.ZIndex="{Binding Text, ElementName=ZIndexItem1Text}"
           Background="LightBlue" BorderBrush="Black" BorderThickness="1"
           Content="Item1" />
    <Label Margin="0,-15,0,0" VerticalAlignment="Top"
           Panel.ZIndex="{Binding Text, ElementName=ZIndexItem2Text}"
           Background="SkyBlue" BorderBrush="Black" BorderThickness="1"
           Content="Item2" />
  </StackPanel>
</StackPanel>

Source code and how it was measured

Every behavior on this page was measured by running it on .NET 10 / Windows 11, using StackPanelDemoScene in this site’s screenshot tool. The panels were laid out with Measure and Arrange, and the element on top was found by a hit test at the given point. Sizes are the values on the measuring machine.

View StackPanel source code on GitHub →