WPF 標準コントロールデモアプリ › StackPanel
StackPanel Layout
StackPanel は、子を 1 列または 1 行に順に並べるパネルです。最も単純なパネルですが、大きさの決まり方で最もつまずきやすいパネルでもあります。
並べる方向には無限の大きさを渡す
StackPanel は、並べる方向には子に無限の大きさを渡します。200 × 100 の縦の StackPanel では子は 200 × Infinity で、横の StackPanel では Infinity × 100 で測られました。もう一方の方向では子は引き伸ばされ、40 × 20 を望んだ子は、縦のパネルでは幅 200、横のパネルでは高さ 100 に配置されました。
縦の StackPanel の中の一覧がスクロールしない理由
無限の大きさのため、縦の StackPanel の中の一覧は高さが限られません。高さ 200 の領域に置いた 1000 項目の ListBox は、高さ 200 で 991 スクロールでき、項目を 10 個作りました。同じ領域で縦の StackPanel に入れると、高さが 19964 になってスクロールできず、1000 個すべての項目を作りました。ScrollViewer でも同じことを、下にリンクした記事で示しています。スクロールさせたい一覧は、Grid の行などで高さを限ります。
StackPanel 自体も仮想化しません。高さ 200 の ScrollViewer の中の StackPanel に 1000 個の子を置くと、1000 個すべてが測られました。一方、高さを限った ListBox は、表示する分の項目だけを作りました。長い一覧には StackPanel ではなく ListBox を使います。
子は折り返さず、はみ出した部分は切れる
Orientation の既定値は Vertical で、子は折り返しません。デモアプリの 3 つのラベルを幅 80 の横の StackPanel に並べると、3 つ目のラベルは 94.69 から始まり、パネルの端を越えました。越えた部分は切れます。ClipToBounds は False でしたが、WPF のレイアウトによる切り抜きでパネルは 80 に限られ、端の外の 3 つ目のラベルをヒットテストしても何も当たりませんでした。折り返すには WrapPanel を使います。また、Spacing プロパティはないので、子の間隔は子の Margin で空けます。
空いた場所と ZIndex
デモアプリは高さ 30 の空の StackPanel を表示しています。Background が既定値の null では中央のヒットテストで何も当たらず、そこでのクリックは後ろの要素に届きます。Transparent や色を設定すると、同じヒットテストでパネルが当たりました。
子が重なったときは、Panel.ZIndex でどれを上に描くかが決まります。デモアプリでは 2 つ目のラベルが 1 つ目に 15 重なっています。ZIndex が 1 と 2 では重なった部分で 2 つ目が上に、3 と 2 では 1 つ目が上になりました。順序が決まるのは同じパネルの子どうしだけです。内側のパネルの子に ZIndex="100" を付けても、その内側のパネルの兄弟(ZIndex 0)より下のままでした。
| 条件 | 計測値 |
|---|---|
| Orientation の既定値 / Spacing プロパティ | Vertical / なし |
| Vertical、200 x 100 のパネル: 子に渡される大きさ / 配置された子の大きさ(希望は 40 x 20) | 200 x Infinity / 200 x 20 |
| Horizontal、200 x 100 のパネル: 子に渡される大きさ / 配置された子の大きさ(希望は 40 x 20) | Infinity x 100 / 40 x 100 |
| Horizontal、デモの 3 つの Label、Width 80: 最後の Label の x / ClipToBounds / レイアウトのクリップの幅 | 94.69 / False / 80 |
| 80 の外にある最後の Label のヒットテスト | (なし) |
| 高さ 200 の ScrollViewer の中の StackPanel に 1000 個の子: 測定された子の数 | 1000 |
| 高さ 200 に 1000 項目の ListBox、直接: 高さ / ScrollableHeight / 作られた項目の数 | 200 / 991 / 10 |
| 高さ 200 に 1000 項目の ListBox、縦の StackPanel の中: 高さ / ScrollableHeight / 作られた項目の数 | 19964 / 0 / 1000 |
| 高さ 30 の空の StackPanel、Background=null: 中央のヒットテスト | (なし) |
| 高さ 30 の空の StackPanel、Background=Transparent: 中央のヒットテスト | Panel |
| 高さ 30 の空の StackPanel、Background=AliceBlue: 中央のヒットテスト | Panel |
| デモの Label、ZIndex Item1=1、Item2=2: 重なった部分で上にある要素 | Item2 |
| デモの Label、ZIndex Item1=3、Item2=2: 重なった部分で上にある要素 | Item1 |
| ZIndex=100 の内側のパネルの子と、内側のパネルの兄弟(ZIndex 0): 上にあるもの | OuterSibling |
子に渡す大きさ、はみ出し、背景、ZIndex。.NET 10 / Windows 11 で計測。
デモアプリで試す

デモアプリの StackPanel のページには、Orientation、Background、ZIndex の 3 つの欄があります。各欄の下の「Show Code」リンクで、その欄の XAML を表示できます。次の XAML は、ZIndex の欄(StackPanelUsageControl.xaml)から、スタイルと周囲の GroupBox を省き、名前空間の宣言を加えたものです。
<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>
関連するコントロールと記事
- WrapPanel — 子を並べ、収まらなければ次の行へ折り返します。
- DockPanel — 子を端に沿って置き、最後の子で残りを埋めます。
- Grid — 大きさの限られた行と列で配置します。
- WPF で ScrollViewer がスクロールしない原因と解決方法 — StackPanel の無限の高さが ScrollViewer に与える影響を扱います。
ソースコードと計測の方法
このページの挙動の記述は、すべて .NET 10 / Windows 11 で実際に動かして確かめたものです。計測には、このサイトのスクリーンショット生成ツールの StackPanelDemoScene を使いました。パネルは Measure と Arrange でレイアウトし、上にある要素は指定した位置のヒットテストで調べました。大きさは、計測したマシンでの値です。