パネルの概要
更新 : 2007 年 11 月
Panel 要素は、要素のレンダリング (サイズ、次元、位置、および子コンテンツの配置) を制御するコンポーネントです。Windows Presentation Foundation (WPF) は、定義済みの多数の Panel 要素と共に、カスタム Panel 要素の作成機能を提供します。
このトピックは、次のセクションで構成されています。
パネル クラス
パネル要素の一般的なメンバ
派生パネル要素
ユーザー インターフェイス パネル
入れ子になったパネル要素
カスタム パネル要素
ローカリゼーション/グローバリゼーション サポート
関連トピック
パネル クラス
Panel は、Windows Presentation Foundation (WPF) でのレイアウト サポートを提供するすべての要素の基本クラスです。派生 Panel 要素は、Extensible Application Markup Language (XAML) とコードにおいて UIElements を配置して整列する際に使用されます。
WPF には、多くの複雑なレイアウトを可能にする派生パネル実装の総合的なスイートが含まれます。これらの派生クラスは、標準 ユーザー インターフェイス (UI) シナリオのほとんどを可能にするプロパティとメソッドを公開します。ニーズを満たす子整列動作を見つけることができない開発者は、ArrangeOverride と MeasureOverride メソッドをオーバーライドすることにより、新しいレイアウトを作成できます。カスタム レイアウト動作の詳細については、「カスタム パネル要素」を参照してください。
XAMLPad
XAMLPad は、リアルタイムでマークアップを解析して結果をウィンドウに表示することにより、Extensible Application Markup Language (XAML) ベースのユーザー インターフェイスの開発を容易にするツールです。このツールは、レイアウトをテストする際に非常に役立ちます。このトピックに記載されているさまざまな Extensible Application Markup Language (XAML) サンプルの結果を表示するために、アプリケーションを開いておいても構いません。詳細については、「XAMLPad」を参照してください。
パネルの一般的なメンバ
すべての Panel 要素は、FrameworkElementによって定義されているベースのサイズ変更と位置プロパティ (Height、Width、HorizontalAlignment、VerticalAlignment、Margin、LayoutTransform など) をサポートします。FrameworkElement によって定義される位置プロパティの詳細については、「配置、余白、パディングの概要」を参照してください。
Panel は、レイアウトを理解して使用するうえできわめて重要なその他のプロパティを公開します。Background プロパティは、Brush で派生パネル要素の境界の間の領域を塗り潰すために使用されます。Children は、Panel を構成する UIElements の子コレクションを表します。InternalChildren は、Children コレクションの内容に加えて、データ バインディングによって生成されるメンバを表します。どちらも、親 Panel 内にホストされた子要素の UIElementCollection で構成されます。
パネルは、派生 Panel のレイヤー化された順序を実現するために使用される ZIndex プロパティも公開します。大きい ZIndex 値を持つパネルの Children コレクションのメンバは、小さい ZIndex 値を持つメンバの前に表示されます。これは、子に同じ座標領域を共有できるようにする Canvas および Grid などのパネルに特に役立ちます。
また、Panel は OnRender メソッドも定義しており、これを使用して Panel の既定のプレゼンテーション動作をオーバーライドできます。
添付プロパティ
派生パネル要素は、添付プロパティを広く活用しています。添付プロパティは、従来の共通言語ランタイム (CLR) プロパティ "ラッパー" を持たない特殊な形式の依存関係プロパティです。添付プロパティは、下記の例に見られるとおり、Extensible Application Markup Language (XAML) 内に特殊な構文を持ちます。
添付プロパティの目的の 1 つは、親要素によって実際に定義されたプロパティの一意の値を子要素が格納できるようにすることです。この機能の応用方法の 1 つは、子要素から親要素に ユーザー インターフェイス (UI) でどのように表示したいかを通知させることで、これはアプリケーション レイアウトに非常に役立ちます。詳細については、「添付プロパティの概要」を参照してください。
派生パネル要素
Panel から多くのオブジェクトが派生しますが、それらのすべてがルート レイアウト プロバイダとして使用されません。UI アプリケーション専用に作成された、6 つの定義済みパネル クラス (Canvas、DockPanel、Grid、StackPanel、VirtualizingStackPanel、およびWrapPanel)があります。
次の表に各パネル要素でカプセル化されているそれぞれの特殊機能を示します。
要素名 |
UI パネル? |
説明 |
---|---|---|
○ |
Canvas 領域に対する座標により子要素を明示的に配置できる領域を定義します。 |
|
○ |
子要素を互いに水平方向または垂直方向に整列する領域を定義します。 |
|
○ |
列と行で構成されている柔軟なグリッド領域を定義します。Grid の子要素は、Margin プロパティを正確に使用して配置できます。 |
|
○ |
単一行に子要素を整列します。行は水平方向または垂直方向にできます。 |
|
× |
TabControl でタブ ボタンのレイアウトを処理します。 |
|
× |
ToolBar コントロール内のコンテンツを整列します。 |
|
× |
UniformGrid は、グリッド内の子をすべて同じセル サイズで整列する際に使用されます。 |
|
× |
子コレクションを "仮想化" できるパネルに基本クラスを提供します。 |
|
○ |
水平方向または垂直方向に向けた単一行上にコンテンツを整列して仮想化します。 |
|
○ |
WrapPanel は、左から右へ順に子要素を配置し、ボックスの端で改行してコンテンツを次の行へ送ります。後続の配置は、Orientation プロパティの値に応じて、上から下または右から左に向かって行われます。 |
ユーザー インターフェイス パネル
WPF には、UI シナリオをサポートするために最適化された次の 6 つのパネル クラスがあります。それは、Canvas、DockPanel、Grid、StackPanel、VirtualizingStackPanel、および WrapPanel です。これらのパネル要素は使いやすく、用途が広く、ほとんどのアプリケーションに対する拡張性があります。
各派生 Panel 要素で、サイズ制約の処理方法が異なります。Panel が水平または垂直方向のどちらで制約を処理するかを理解することにより、レイアウトの予測がより可能となります。
パネル名 |
x-Dimension |
y-Dimension |
---|---|---|
コンテンツに対する制約あり。 |
コンテンツに対する制約あり。 |
|
制約あり。 |
制約あり。 |
|
StackPanel (垂直方向) |
制約あり。 |
コンテンツに対する制約あり。 |
StackPanel (水平方向) |
コンテンツに対する制約あり。 |
制約あり。 |
制約あり。 |
制約あり。ただし、Auto が行と列に適用される場合を除きます。 |
|
コンテンツに対する制約あり。 |
コンテンツに対する制約あり。 |
これらの各要素の詳細な説明と使用例については、以下を参照してください。
キャンバス
Canvas 要素は、x- および y- の絶対座標に従って、コンテンツの位置を設定できます。要素は一意の場所に描画できます。または、要素が同じ座標を占める場合、マークアップに表示される順序が要素の描画順序を決定します。
Canvas は、Panel のレイアウトを最も柔軟にサポートします。Height および Width プロパティがキャンバスの領域の定義に使用され、内側の要素には、親の Canvas 領域に対する絶対座標が割り当てられます。4 つの添付プロパティ (Bottom、Left、Top、および Right) により、Canvas 内のオブジェクトの配置を緻密に制御できるので、開発者は画面上で要素の配置と整列を正確に行うことができます。
キャンバス内の ClipToBounds
Canvas は、独自に定義したHeight と Width の外側にある座標でも、画面の任意の位置に子要素を配置できます。また、Canvas は子要素のサイズの影響を受けません。その結果、子要素は親の Canvas の外接する四角形の外側に他の要素を描画できます。Canvas の既定動作により、親の Canvas の境界の外側に子要素を描画できます。この動作が必要でない場合は、ClipToBounds プロパティを true に設定します。これにより、Canvas が独自のサイズに切り取られます。Canvas は、境界の外側に子要素を描画できる唯一のレイアウト要素です。
この動作は、「Width のプロパティの比較のサンプル」に図示されています。
キャンバスの定義と使用
Canvas は、Extensible Application Markup Language (XAML) またはコードを使用して、容易にインスタンス化できます。次の例に、Canvas を使用してコンテンツを絶対的に配置する方法を示します。このコードでは、100 ピクセルの四角形を 3 つ生成します。最初の四角形は赤色で、左上 (x, y) の位置が (0, 0) に指定されます。2 番目の四角形は緑色で、左上の位置は (100, 100) となり、最初の四角形の右下になります。3 番目の四角形は青色で、左上の位置は (50, 50) となるため、最初の四角形の右下の象限および 2 番目の四角形の左上の象限を囲む状態になります。3 番目の四角形が最後にレイアウトされるため、他の 2 つの四角形の上に重なっているように見えます。つまり、重複している部分は 3 番目の四角形の色とみなされます。
WindowTitle = "Canvas Sample"
'Create a Canvas as the root Panel
Dim myParentCanvas As New Canvas()
myParentCanvas.Width = 400
myParentCanvas.Height = 400
' Define child Canvas elements
Dim myCanvas1 As New Canvas()
myCanvas1.Background = Brushes.Red
myCanvas1.Height = 100
myCanvas1.Width = 100
Canvas.SetTop(myCanvas1, 0)
Canvas.SetLeft(myCanvas1, 0)
Dim myCanvas2 As New Canvas()
myCanvas2.Background = Brushes.Green
myCanvas2.Height = 100
myCanvas2.Width = 100
Canvas.SetTop(myCanvas2, 100)
Canvas.SetLeft(myCanvas2, 100)
Dim myCanvas3 As New Canvas()
myCanvas3.Background = Brushes.Blue
myCanvas3.Height = 100
myCanvas3.Width = 100
Canvas.SetTop(myCanvas3, 50)
Canvas.SetLeft(myCanvas3, 50)
' Add child elements to the Canvas' Children collection
myParentCanvas.Children.Add(myCanvas1)
myParentCanvas.Children.Add(myCanvas2)
myParentCanvas.Children.Add(myCanvas3)
' Add the parent Canvas as the Content of the Window Object
Me.Content = myParentCanvas
// Create the application's main window
mainWindow = new Window ();
mainWindow.Title = "Canvas Sample";
// Create the Canvas
myParentCanvas = new Canvas();
myParentCanvas.Width = 400;
myParentCanvas.Height = 400;
// Define child Canvas elements
myCanvas1 = new Canvas();
myCanvas1.Background = Brushes.Red;
myCanvas1.Height = 100;
myCanvas1.Width = 100;
Canvas.SetTop(myCanvas1, 0);
Canvas.SetLeft(myCanvas1, 0);
myCanvas2 = new Canvas();
myCanvas2.Background = Brushes.Green;
myCanvas2.Height = 100;
myCanvas2.Width = 100;
Canvas.SetTop(myCanvas2, 100);
Canvas.SetLeft(myCanvas2, 100);
myCanvas3 = new Canvas();
myCanvas3.Background = Brushes.Blue;
myCanvas3.Height = 100;
myCanvas3.Width = 100;
Canvas.SetTop(myCanvas3, 50);
Canvas.SetLeft(myCanvas3, 50);
// Add child elements to the Canvas' Children collection
myParentCanvas.Children.Add(myCanvas1);
myParentCanvas.Children.Add(myCanvas2);
myParentCanvas.Children.Add(myCanvas3);
// Add the parent Canvas as the Content of the Window Object
mainWindow.Content = myParentCanvas;
mainWindow.Show ();
<Page WindowTitle="Canvas Sample" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Canvas Height="400" Width="400">
<Canvas Height="100" Width="100" Top="0" Left="0" Background="Red"/>
<Canvas Height="100" Width="100" Top="100" Left="100" Background="Green"/>
<Canvas Height="100" Width="100" Top="50" Left="50" Background="Blue"/>
</Canvas>
</Page>
コンパイルされたアプリケーションは、これと同様の新しい UI を生成します。
DockPanel
DockPanel 要素は、添付 Dock プロパティを使用して、コンテナの端に沿ってコンテンツを配置します。Dock を Top または Bottom に設定すると、子要素は互いの上または下に配置されます。Dock を Left または Right に設定すると、子要素は互いの左または右に配置されます。LastChildFill プロパティは、 DockPanel の子として追加された最終要素の位置を決定します。
DockPanel を使用して、一連のボタンなど、関連コントロールのグループを配置できます。または、これを使用して、Microsoft Outlook に見られるのと同様の "ウィンドウ形式の" UI を作成できます。
コンテンツに合わせたサイズの変更
Height と Width プロパティが指定されていない場合、DockPanel はコンテンツに合わせてサイズを変更します。サイズは、子要素のサイズに合うように、増減させることができます。ただし、これらのプロパティが指定されており、次に指定する子要素のためのスペースがない場合、DockPanel はその子要素または後続の子要素を表示せず、後続の子要素を計測しません。
LastChildFill
既定では、DockPanel 要素の最後の子は、残りの未割り当て領域の "塗り潰し" を実行します。この動作が必要でない場合、LastChildFill プロパティを false に設定します。
DockPanel の定義と使用
次の例に、DockPanel を使用してスペースを分割する方法を示します。親 DockPanel の子として、5 つの Border 要素が追加されます。それぞれ DockPanel の異なる位置プロパティを使用して、スペースを分割します。最後の要素が、残っている未割り当て領域の "塗り潰し" を実行します。
WindowTitle = "DockPanel Sample"
'Create a DockPanel as the root Panel
Dim myDockPanel As New DockPanel()
myDockPanel.LastChildFill = True
' Define the child content
Dim myBorder1 As New Border()
myBorder1.Height = 25
myBorder1.Background = Brushes.SkyBlue
myBorder1.BorderBrush = Brushes.Black
myBorder1.BorderThickness = New Thickness(1)
DockPanel.SetDock(myBorder1, Dock.Top)
Dim myTextBlock1 As New TextBlock()
myTextBlock1.Foreground = Brushes.Black
myTextBlock1.Text = "Dock = Top"
myBorder1.Child = myTextBlock1
Dim myBorder2 As New Border()
myBorder2.Height = 25
myBorder2.Background = Brushes.SkyBlue
myBorder2.BorderBrush = Brushes.Black
myBorder2.BorderThickness = New Thickness(1)
DockPanel.SetDock(myBorder2, Dock.Top)
Dim myTextBlock2 As New TextBlock()
myTextBlock2.Foreground = Brushes.Black
myTextBlock2.Text = "Dock = Top"
myBorder2.Child = myTextBlock2
Dim myBorder3 As New Border()
myBorder3.Height = 25
myBorder3.Background = Brushes.LemonChiffon
myBorder3.BorderBrush = Brushes.Black
myBorder3.BorderThickness = New Thickness(1)
DockPanel.SetDock(myBorder3, Dock.Bottom)
Dim myTextBlock3 As New TextBlock()
myTextBlock3.Foreground = Brushes.Black
myTextBlock3.Text = "Dock = Bottom"
myBorder3.Child = myTextBlock3
Dim myBorder4 As New Border()
myBorder4.Width = 200
myBorder4.Background = Brushes.PaleGreen
myBorder4.BorderBrush = Brushes.Black
myBorder4.BorderThickness = New Thickness(1)
DockPanel.SetDock(myBorder4, Dock.Left)
Dim myTextBlock4 As New TextBlock()
myTextBlock4.Foreground = Brushes.Black
myTextBlock4.Text = "Dock = Left"
myBorder4.Child = myTextBlock4
Dim myBorder5 As New Border()
myBorder5.Background = Brushes.White
myBorder5.BorderBrush = Brushes.Black
myBorder5.BorderThickness = New Thickness(1)
Dim myTextBlock5 As New TextBlock()
myTextBlock5.Foreground = Brushes.Black
myTextBlock5.Text = "This content will Fill the remaining space"
myBorder5.Child = myTextBlock5
' Add child elements to the DockPanel Children collection
myDockPanel.Children.Add(myBorder1)
myDockPanel.Children.Add(myBorder2)
myDockPanel.Children.Add(myBorder3)
myDockPanel.Children.Add(myBorder4)
myDockPanel.Children.Add(myBorder5)
Me.Content = myDockPanel
// Create the application's main window
mainWindow = new Window ();
mainWindow.Title = "DockPanel Sample";
// Create the DockPanel
DockPanel myDockPanel = new DockPanel();
myDockPanel.LastChildFill = true;
// Define the child content
Border myBorder1 = new Border();
myBorder1.Height = 25;
myBorder1.Background = Brushes.SkyBlue;
myBorder1.BorderBrush = Brushes.Black;
myBorder1.BorderThickness = new Thickness(1);
DockPanel.SetDock(myBorder1, Dock.Top);
TextBlock myTextBlock1 = new TextBlock();
myTextBlock1.Foreground = Brushes.Black;
myTextBlock1.Text = "Dock = Top";
myBorder1.Child = myTextBlock1;
Border myBorder2 = new Border();
myBorder2.Height = 25;
myBorder2.Background = Brushes.SkyBlue;
myBorder2.BorderBrush = Brushes.Black;
myBorder2.BorderThickness = new Thickness(1);
DockPanel.SetDock(myBorder2, Dock.Top);
TextBlock myTextBlock2 = new TextBlock();
myTextBlock2.Foreground = Brushes.Black;
myTextBlock2.Text = "Dock = Top";
myBorder2.Child = myTextBlock2;
Border myBorder3 = new Border();
myBorder3.Height = 25;
myBorder3.Background = Brushes.LemonChiffon;
myBorder3.BorderBrush = Brushes.Black;
myBorder3.BorderThickness = new Thickness(1);
DockPanel.SetDock(myBorder3, Dock.Bottom);
TextBlock myTextBlock3 = new TextBlock();
myTextBlock3.Foreground = Brushes.Black;
myTextBlock3.Text = "Dock = Bottom";
myBorder3.Child = myTextBlock3;
Border myBorder4 = new Border();
myBorder4.Width = 200;
myBorder4.Background = Brushes.PaleGreen;
myBorder4.BorderBrush = Brushes.Black;
myBorder4.BorderThickness = new Thickness(1);
DockPanel.SetDock(myBorder4, Dock.Left);
TextBlock myTextBlock4 = new TextBlock();
myTextBlock4.Foreground = Brushes.Black;
myTextBlock4.Text = "Dock = Left";
myBorder4.Child = myTextBlock4;
Border myBorder5 = new Border();
myBorder5.Background = Brushes.White;
myBorder5.BorderBrush = Brushes.Black;
myBorder5.BorderThickness = new Thickness(1);
TextBlock myTextBlock5 = new TextBlock();
myTextBlock5.Foreground = Brushes.Black;
myTextBlock5.Text = "This content will Fill the remaining space";
myBorder5.Child = myTextBlock5;
// Add child elements to the DockPanel Children collection
myDockPanel.Children.Add(myBorder1);
myDockPanel.Children.Add(myBorder2);
myDockPanel.Children.Add(myBorder3);
myDockPanel.Children.Add(myBorder4);
myDockPanel.Children.Add(myBorder5);
// Add the parent Canvas as the Content of the Window Object
mainWindow.Content = myDockPanel;
mainWindow.Show ();
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" WindowTitle="DockPanel Sample">
<DockPanel LastChildFill="True">
<Border Height="25" Background="SkyBlue" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Top">
<TextBlock Foreground="Black">Dock = "Top"</TextBlock>
</Border>
<Border Height="25" Background="SkyBlue" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Top">
<TextBlock Foreground="Black">Dock = "Top"</TextBlock>
</Border>
<Border Height="25" Background="LemonChiffon" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Bottom">
<TextBlock Foreground="Black">Dock = "Bottom"</TextBlock>
</Border>
<Border Width="200" Background="PaleGreen" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Left">
<TextBlock Foreground="Black">Dock = "Left"</TextBlock>
</Border>
<Border Background="White" BorderBrush="Black" BorderThickness="1">
<TextBlock Foreground="Black">This content will "Fill" the remaining space</TextBlock>
</Border>
</DockPanel>
</Page>
コンパイルされたアプリケーションは、これと同様の新しい UI を生成します。
[グリッド]
Grid 要素は、絶対配置と表データ コントロールの機能をマージします。Grid により、容易に要素を配置して体裁を整えることができます。Grid では、行と列のグループを柔軟に定義でき、複数の Grid 要素間でサイズ情報を共有するメカニズムも提供されます。
グリッドとテーブルを区別する方法
Table と Grid には共通の機能がいくつかありますが、それぞれが最も適している状況は異なります。Table は、フロー コンテンツ内で使用するために設計されています (フロー コンテンツの詳細については、「フロー ドキュメントの概要」を参照してください)。グリッドは、フォーム内 (基本的にはフロー コンテンツ外の任意の場所) で使用するのに最適です。FlowDocument 内では、Table は改ページ位置の自動修正、列の再配置、およびコンテンツの選択をサポートしますが、Grid はサポートしません。一方、Grid は、さまざまな理由から FlowDocument の外で使用するのに適しています。たとえば、Grid は行と列のインデックスに基づいて要素を追加しますが、Table は追加しません。Grid 要素により、子のコンテンツのレイヤを表示でき、1 つの "セル" 内に複数の要素を含むことができます。Table は、レイヤ表示をサポートしません。Grid の子要素は、"セル" 境界の領域に対して絶対位置で配置できます。Table は、この機能をサポートしていません。最後に、Grid は Table より軽量です。
列と行のサイズ変更動作
Grid 内で定義された列と行は、Star サイズ変更機能を利用して、残りのスペースを比率に応じて分配できます。Star が行または列の高さまたは幅として選択された場合、その列または行は、使用可能な残りのスペースの領域を加重比率分を受け取ります。これは、列または行内のコンテンツのサイズに基づいてスペースを均等に分配する Auto とは対照的です。Extensible Application Markup Language (XAML) を使用する場合、この値は * または 2* と表現されます。最初のケースでは、行または列は使用可能なスペース領域を 1 回受け取り、2 番目のケースでは 2 回受け取ることになります。スター サイズ変更の詳細については、「スター サイズ変更の使用のサンプル」のサンプルを参照してください。HorizontalAlignment を使用してスペースを比率に応じて分配する方法と、Stretch の VerticalAlignment 値を組み合わせることにより、画面スペースのパーセンテージ単位でレイアウト スペースを分割できます。Grid は、この方法でスペースを分配できる唯一のレイアウト パネルです。
グリッドの定義と使用
次の例に、Windows スタート メニューで使用可能な「ファイル名を指定して実行」ダイアログに見られるのと同様の UI を構築する方法を示します。
'Create a Grid as the root Panel element.
Dim myGrid As New Grid()
myGrid.Height = 165
myGrid.Width = 425
myGrid.Background = Brushes.Gainsboro
myGrid.ShowGridLines = True
myGrid.HorizontalAlignment = Windows.HorizontalAlignment.Left
myGrid.VerticalAlignment = Windows.VerticalAlignment.Top
' Define and Add the Rows and Columns.
Dim colDef1 As New ColumnDefinition
colDef1.Width = New GridLength(1, GridUnitType.Auto)
Dim colDef2 As New ColumnDefinition
colDef2.Width = New GridLength(1, GridUnitType.Star)
Dim colDef3 As New ColumnDefinition
colDef3.Width = New GridLength(1, GridUnitType.Star)
Dim colDef4 As New ColumnDefinition
colDef4.Width = New GridLength(1, GridUnitType.Star)
Dim colDef5 As New ColumnDefinition
colDef5.Width = New GridLength(1, GridUnitType.Star)
myGrid.ColumnDefinitions.Add(colDef1)
myGrid.ColumnDefinitions.Add(colDef2)
myGrid.ColumnDefinitions.Add(colDef3)
myGrid.ColumnDefinitions.Add(colDef4)
myGrid.ColumnDefinitions.Add(colDef5)
Dim rowDef1 As New RowDefinition
rowDef1.Height = New GridLength(1, GridUnitType.Auto)
Dim rowDef2 As New RowDefinition
rowDef2.Height = New GridLength(1, GridUnitType.Auto)
Dim rowDef3 As New Controls.RowDefinition
rowDef3.Height = New GridLength(1, GridUnitType.Star)
Dim rowDef4 As New RowDefinition
rowDef4.Height = New GridLength(1, GridUnitType.Auto)
myGrid.RowDefinitions.Add(rowDef1)
myGrid.RowDefinitions.Add(rowDef2)
myGrid.RowDefinitions.Add(rowDef3)
myGrid.RowDefinitions.Add(rowDef4)
' Add the Image.
Dim img1 As New Image
img1.Source = New System.Windows.Media.Imaging.BitmapImage(New Uri("runicon.png", UriKind.Relative))
Grid.SetRow(img1, 0)
Grid.SetColumn(img1, 0)
myGrid.Children.Add(img1)
' Add the main application dialog.
Dim txt1 As New TextBlock
txt1.Text = "Type the name of a program, document, or Internet resource, and Windows will open it for you."
txt1.TextWrapping = TextWrapping.Wrap
Grid.SetColumnSpan(txt1, 4)
Grid.SetRow(txt1, 0)
Grid.SetColumn(txt1, 1)
myGrid.Children.Add(txt1)
' Add the second TextBlock Cell to the Grid.
Dim txt2 As New TextBlock
txt2.Text = "Open:"
Grid.SetRow(txt2, 1)
Grid.SetColumn(txt2, 0)
myGrid.Children.Add(txt2)
' Add the TextBox control.
Dim tb1 As New TextBox
Grid.SetRow(tb1, 1)
Grid.SetColumn(tb1, 1)
Grid.SetColumnSpan(tb1, 5)
myGrid.Children.Add(tb1)
' Add the Button controls.
Dim button1 As New Button
Dim button2 As New Button
Dim button3 As New Button
button1.Content = "OK"
button1.Margin = New Thickness(10, 0, 10, 15)
button2.Content = "Cancel"
button2.Margin = New Thickness(10, 0, 10, 15)
button3.Content = "Browse ..."
button3.Margin = New Thickness(10, 0, 10, 15)
Grid.SetRow(button1, 3)
Grid.SetColumn(button1, 2)
Grid.SetRow(button2, 3)
Grid.SetColumn(button2, 3)
Grid.SetRow(button3, 3)
Grid.SetColumn(button3, 4)
myGrid.Children.Add(button1)
myGrid.Children.Add(button2)
myGrid.Children.Add(button3)
Me.Content = myGrid
// Create the Grid.
grid1 = new Grid ();
grid1.Background = Brushes.Gainsboro;
grid1.HorizontalAlignment = HorizontalAlignment.Left;
grid1.VerticalAlignment = VerticalAlignment.Top;
grid1.ShowGridLines = true;
grid1.Width = 425;
grid1.Height = 165;
// Define the Columns.
colDef1 = new ColumnDefinition();
colDef1.Width = new GridLength(1, GridUnitType.Auto);
colDef2 = new ColumnDefinition();
colDef2.Width = new GridLength(1, GridUnitType.Star);
colDef3 = new ColumnDefinition();
colDef3.Width = new GridLength(1, GridUnitType.Star);
colDef4 = new ColumnDefinition();
colDef4.Width = new GridLength(1, GridUnitType.Star);
colDef5 = new ColumnDefinition();
colDef5.Width = new GridLength(1, GridUnitType.Star);
grid1.ColumnDefinitions.Add(colDef1);
grid1.ColumnDefinitions.Add(colDef2);
grid1.ColumnDefinitions.Add(colDef3);
grid1.ColumnDefinitions.Add(colDef4);
grid1.ColumnDefinitions.Add(colDef5);
// Define the Rows.
rowDef1 = new RowDefinition();
rowDef1.Height = new GridLength(1, GridUnitType.Auto);
rowDef2 = new RowDefinition();
rowDef2.Height = new GridLength(1, GridUnitType.Auto);
rowDef3 = new RowDefinition();
rowDef3.Height = new GridLength(1, GridUnitType.Star);
rowDef4 = new RowDefinition();
rowDef4.Height = new GridLength(1, GridUnitType.Auto);
grid1.RowDefinitions.Add(rowDef1);
grid1.RowDefinitions.Add(rowDef2);
grid1.RowDefinitions.Add(rowDef3);
grid1.RowDefinitions.Add(rowDef4);
// Add the Image.
img1 = new Image();
img1.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("runicon.png", UriKind.Relative));
Grid.SetRow(img1, 0);
Grid.SetColumn(img1, 0);
// Add the main application dialog.
txt1 = new TextBlock();
txt1.Text = "Type the name of a program, folder, document, or Internet resource, and Windows will open it for you.";
txt1.TextWrapping = TextWrapping.Wrap;
Grid.SetColumnSpan(txt1, 4);
Grid.SetRow(txt1, 0);
Grid.SetColumn(txt1, 1);
// Add the second text cell to the Grid.
txt2 = new TextBlock();
txt2.Text = "Open:";
Grid.SetRow(txt2, 1);
Grid.SetColumn(txt2, 0);
// Add the TextBox control.
tb1 = new TextBox();
Grid.SetRow(tb1, 1);
Grid.SetColumn(tb1, 1);
Grid.SetColumnSpan(tb1, 5);
// Add the buttons.
button1 = new Button();
button2 = new Button();
button3 = new Button();
button1.Content = "OK";
button2.Content = "Cancel";
button3.Content = "Browse ...";
Grid.SetRow(button1, 3);
Grid.SetColumn(button1, 2);
button1.Margin = new Thickness(10, 0, 10, 15);
button2.Margin = new Thickness(10, 0, 10, 15);
button3.Margin = new Thickness(10, 0, 10, 15);
Grid.SetRow(button2, 3);
Grid.SetColumn(button2, 3);
Grid.SetRow(button3, 3);
Grid.SetColumn(button3, 4);
grid1.Children.Add(img1);
grid1.Children.Add(txt1);
grid1.Children.Add(txt2);
grid1.Children.Add(tb1);
grid1.Children.Add(button1);
grid1.Children.Add(button2);
grid1.Children.Add(button3);
mainWindow.Content = grid1;
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowTitle="Grid Run Dialog Sample"
WindowWidth="425"
WindowHeight="225">
<Grid Background="#DCDCDC"
Width="425"
Height="165"
HorizontalAlignment="Left"
VerticalAlignment="Top"
ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" Source="RunIcon.png" />
<TextBlock Grid.Column="1" Grid.ColumnSpan="4" Grid.Row="0" TextWrapping="Wrap">
Type the name of a program, folder, document, or
Internet resource, and Windows will open it for you.
</TextBlock>
<TextBlock Grid.Column="0" Grid.Row="1">Open:</TextBlock>
<TextBox Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="5" />
<Button Margin="10, 0, 10, 15" Grid.Row="3" Grid.Column="2">OK</Button>
<Button Margin="10, 0, 10, 15" Grid.Row="3" Grid.Column="3">Cancel</Button>
<Button Margin="10, 0, 10, 15" Grid.Row="3" Grid.Column="4">Browse ...</Button>
</Grid>
</Page>
コンパイルされたアプリケーションは、これと同様の新しい UI を生成します。
StackPanel
StackPanel により、割り当てられた方向に要素を "スタック" できます。既定のスタック方向は、縦です。Orientation プロパティを使用して、コンテンツ フローを制御できます。
StackPanel 対 DockPanel
DockPanel でも子要素を "スタック" できますが、DockPanel と StackPanel を同じ状況で使用しても、同様の結果は生成されません。たとえば、DockPanel では、子要素の順序がサイズに影響を与えますが、StackPanel では影響しません。これは、StackPanel が PositiveInfinity でスタック方向に計測するのに対し、DockPanel は使用可能なサイズだけを計測するためです。
この主な相違点を次の例に示します。
'Add root Grid
Dim myGrid As New Grid
myGrid.Width = 175
myGrid.Height = 150
Dim myRowDef1 As New RowDefinition
Dim myRowDef2 As New RowDefinition
myGrid.RowDefinitions.Add(myRowDef1)
myGrid.RowDefinitions.Add(myRowDef2)
'Define the DockPanel
Dim myDockPanel As New DockPanel
Grid.SetRow(myDockPanel, 0)
'Define an Image and Source.
Dim myImage As New Image
Dim bi As New BitmapImage
bi.BeginInit()
bi.UriSource = New Uri("smiley_stackpanel.png", UriKind.Relative)
bi.EndInit()
myImage.Source = bi
Dim myImage2 As New Image
Dim bi2 As New BitmapImage
bi2.BeginInit()
bi2.UriSource = New Uri("smiley_stackpanel.png", UriKind.Relative)
bi2.EndInit()
myImage2.Source = bi2
Dim myImage3 As New Image
Dim bi3 As New BitmapImage
bi3.BeginInit()
bi3.UriSource = New Uri("smiley_stackpanel.PNG", UriKind.Relative)
bi3.EndInit()
myImage3.Stretch = Stretch.Fill
myImage3.Source = bi3
'Add the images to the parent DockPanel.
myDockPanel.Children.Add(myImage)
myDockPanel.Children.Add(myImage2)
myDockPanel.Children.Add(myImage3)
'Define a StackPanel.
Dim myStackPanel As New StackPanel
myStackPanel.Orientation = Orientation.Horizontal
Grid.SetRow(myStackPanel, 1)
Dim myImage4 As New Image
Dim bi4 As New BitmapImage
bi4.BeginInit()
bi4.UriSource = New Uri("smiley_stackpanel.png", UriKind.Relative)
bi4.EndInit()
myImage4.Source = bi4
Dim myImage5 As New Image
Dim bi5 As New BitmapImage
bi5.BeginInit()
bi5.UriSource = New Uri("smiley_stackpanel.png", UriKind.Relative)
bi5.EndInit()
myImage5.Source = bi5
Dim myImage6 As New Image
Dim bi6 As New BitmapImage
bi6.BeginInit()
bi6.UriSource = New Uri("smiley_stackpanel.PNG", UriKind.Relative)
bi6.EndInit()
myImage6.Stretch = Stretch.Fill
myImage6.Source = bi6
'Add the images to the parent StackPanel.
myStackPanel.Children.Add(myImage4)
myStackPanel.Children.Add(myImage5)
myStackPanel.Children.Add(myImage6)
'Add the layout panels as children of the Grid
myGrid.Children.Add(myDockPanel)
myGrid.Children.Add(myStackPanel)
// Create the application's main window
mainWindow = new Window ();
mainWindow.Title = "StackPanel vs. DockPanel";
// Add root Grid
myGrid = new Grid();
myGrid.Width = 175;
myGrid.Height = 150;
RowDefinition myRowDef1 = new RowDefinition();
RowDefinition myRowDef2 = new RowDefinition();
myGrid.RowDefinitions.Add(myRowDef1);
myGrid.RowDefinitions.Add(myRowDef2);
// Define the DockPanel
myDockPanel = new DockPanel();
Grid.SetRow(myDockPanel, 0);
//Define an Image and Source
Image myImage = new Image();
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri("smiley_stackpanel.png", UriKind.Relative);
bi.EndInit();
myImage.Source = bi;
Image myImage2 = new Image();
BitmapImage bi2 = new BitmapImage();
bi2.BeginInit();
bi2.UriSource = new Uri("smiley_stackpanel.png", UriKind.Relative);
bi2.EndInit();
myImage2.Source = bi2;
Image myImage3 = new Image();
BitmapImage bi3 = new BitmapImage();
bi3.BeginInit();
bi3.UriSource = new Uri("smiley_stackpanel.PNG", UriKind.Relative);
bi3.EndInit();
myImage3.Stretch = Stretch.Fill;
myImage3.Source = bi3;
// Add the images to the parent DockPanel
myDockPanel.Children.Add(myImage);
myDockPanel.Children.Add(myImage2);
myDockPanel.Children.Add(myImage3);
//Define a StackPanel
myStackPanel = new StackPanel();
myStackPanel.Orientation = Orientation.Horizontal;
Grid.SetRow(myStackPanel, 1);
Image myImage4 = new Image();
BitmapImage bi4 = new BitmapImage();
bi4.BeginInit();
bi4.UriSource = new Uri("smiley_stackpanel.png", UriKind.Relative);
bi4.EndInit();
myImage4.Source = bi4;
Image myImage5 = new Image();
BitmapImage bi5 = new BitmapImage();
bi5.BeginInit();
bi5.UriSource = new Uri("smiley_stackpanel.png", UriKind.Relative);
bi5.EndInit();
myImage5.Source = bi5;
Image myImage6 = new Image();
BitmapImage bi6 = new BitmapImage();
bi6.BeginInit();
bi6.UriSource = new Uri("smiley_stackpanel.PNG", UriKind.Relative);
bi6.EndInit();
myImage6.Stretch = Stretch.Fill;
myImage6.Source = bi6;
// Add the images to the parent StackPanel
myStackPanel.Children.Add(myImage4);
myStackPanel.Children.Add(myImage5);
myStackPanel.Children.Add(myImage6);
// Add the layout panels as children of the Grid
myGrid.Children.Add(myDockPanel);
myGrid.Children.Add(myStackPanel);
// Add the Grid as the Content of the Parent Window Object
mainWindow.Content = myGrid;
mainWindow.Show ();
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowTitle="StackPanel vs. DockPanel">
<Grid Width="175" Height="150">
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<DockPanel Grid.Column="0" Grid.Row="0">
<Image Source="smiley_stackpanel.png" />
<Image Source="smiley_stackpanel.png" />
<Image Source="smiley_stackpanel.png" Stretch="Fill"/>
</DockPanel>
<StackPanel Grid.Column="0" Grid.Row="1" Orientation="Horizontal">
<Image Source="smiley_stackpanel.png" />
<Image Source="smiley_stackpanel.png" />
<Image Source="smiley_stackpanel.png" Stretch="Fill"/>
</StackPanel>
</Grid>
</Page>
このイメージにはレンダリング動作の違いが見られます。
StackPanel の定義と使用
次の例に、StackPanel を使用して一連の縦方向配置ボタンを作成する方法を示します。横方向に配置する場合は、Orientation プロパティをHorizontal に設定します。
WindowTitle = "StackPanel Sample"
' Define the StackPanel
Dim myStackPanel As New StackPanel()
myStackPanel.HorizontalAlignment = Windows.HorizontalAlignment.Left
myStackPanel.VerticalAlignment = Windows.VerticalAlignment.Top
' Define child content
Dim myButton1 As New Button()
myButton1.Content = "Button 1"
Dim myButton2 As New Button()
myButton2.Content = "Button 2"
Dim myButton3 As New Button()
myButton3.Content = "Button 3"
' Add child elements to the parent StackPanel
myStackPanel.Children.Add(myButton1)
myStackPanel.Children.Add(myButton2)
myStackPanel.Children.Add(myButton3)
Me.Content = myStackPanel
// Create the application's main window
mainWindow = new Window ();
mainWindow.Title = "StackPanel Sample";
// Define the StackPanel
myStackPanel = new StackPanel();
myStackPanel.HorizontalAlignment = HorizontalAlignment.Left;
myStackPanel.VerticalAlignment = VerticalAlignment.Top;
// Define child content
Button myButton1 = new Button();
myButton1.Content = "Button 1";
Button myButton2 = new Button();
myButton2.Content = "Button 2";
Button myButton3 = new Button();
myButton3.Content = "Button 3";
// Add child elements to the parent StackPanel
myStackPanel.Children.Add(myButton1);
myStackPanel.Children.Add(myButton2);
myStackPanel.Children.Add(myButton3);
// Add the StackPanel as the Content of the Parent Window Object
mainWindow.Content = myStackPanel;
mainWindow.Show ();
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" WindowTitle="StackPanel Sample">
<StackPanel HorizontalAlignment="Left"
VerticalAlignment="Top">
<Button>Button 1</Button>
<Button>Button 2</Button>
<Button>Button 3</Button>
</StackPanel>
</Page>
コンパイルされたアプリケーションは、これと同様の新しい UI を生成します。
VirtualizingStackPanel
WPF もデータ バインド子コンテンツを自動的に "仮想化する" StackPanel 要素のバリエーションを提供します。ここで、"仮想化" は、どの項目を画面に表示するかに基づいて、UIElements のサブセットを多数のデータ項目から生成する手法を指します。特定の時間に画面に UI 要素が少ししか表示されていない場合に多数の UI 要素を生成すると、メモリおよびプロセッサの両方に負荷がかかります。(VirtualizingPanel によって提供される機能を介する) VirtualizingStackPanel は、表示される項目を計算して、ItemsControl (ListBox、ListView など) の ItemContainerGenerator と共に機能することで、表示される項目から UIElements の作成のみを行います。
VirtualizingStackPanel 要素は、ListBox などのコントロール用の項目ホストとして自動的に設定されます。データ バインド コレクションをホストした場合、ScrollViewer の境界内にコンテンツがあれば、コンテンツは自動的に仮想化されます。これにより、多くの子項目をホストする際のパフォーマンスが大幅に向上します。
次のマークアップは、項目ホストとして VirtualizingStackPanel を使用する方法を示します。IsVirtualizing 添付プロパティを True (既定値) に設定して、仮想化が行われるようにする必要があります。
<StackPanel DataContext="{Binding Source={StaticResource Leagues}}">
<TextBlock Text="{Binding XPath=@name}" FontFamily="Arial" FontSize="18" Foreground="Black"/>
<ListBox VirtualizingStackPanel.IsVirtualizing="True"
ItemsSource="{Binding XPath=Team}"
ItemTemplate="{DynamicResource NameDataStyle}"/>
</StackPanel>
WrapPanel
WrapPanel を使用して、子要素を左から右に順に配置し、親コンテナの端に達すると、次の行に改行させます。コンテンツは横または縦に配置できます。WrapPanel は、単純な流れの ユーザー インターフェイス (UI) シナリオに役立ちます。また、子要素すべてに均等なサイズを適用する際にも使用できます。
次の例には、コンテナの端に達した時点でラップする Button コントロールを表示するための WrapPanel の作成方法を示します。
WindowTitle = "WrapPanel Sample"
' Instantiate a new WrapPanel and set properties
Dim myWrapPanel As New WrapPanel()
myWrapPanel.Background = Brushes.Azure
myWrapPanel.Orientation = Orientation.Horizontal
myWrapPanel.ItemHeight = 25
myWrapPanel.ItemWidth = 75
myWrapPanel.Width = 150
myWrapPanel.HorizontalAlignment = Windows.HorizontalAlignment.Left
myWrapPanel.VerticalAlignment = Windows.VerticalAlignment.Top
' Define 3 button elements. Each button is sized at width of 75, so the third button wraps to the next line.
Dim btn1 As New Button()
btn1.Content = "Button 1"
Dim btn2 As New Button()
btn2.Content = "Button 2"
Dim btn3 As New Button()
btn3.Content = "Button 3"
' Add the buttons to the parent WrapPanel using the Children.Add method.
myWrapPanel.Children.Add(btn1)
myWrapPanel.Children.Add(btn2)
myWrapPanel.Children.Add(btn3)
' Add the WrapPanel to the Page as Content
Me.Content = myWrapPanel
// Create the application's main window
mainWindow = new System.Windows.Window();
mainWindow.Title = "WrapPanel Sample";
// Instantiate a new WrapPanel and set properties
myWrapPanel = new WrapPanel();
myWrapPanel.Background = System.Windows.Media.Brushes.Azure;
myWrapPanel.Orientation = Orientation.Horizontal;
myWrapPanel.ItemHeight = 25;
myWrapPanel.ItemWidth = 75;
myWrapPanel.Width = 150;
myWrapPanel.HorizontalAlignment = HorizontalAlignment.Left;
myWrapPanel.VerticalAlignment = VerticalAlignment.Top;
// Define 3 button elements. Each button is sized at width of 75, so the third button wraps to the next line.
btn1 = new Button();
btn1.Content = "Button 1";
btn2 = new Button();
btn2.Content = "Button 2";
btn3 = new Button();
btn3.Content = "Button 3";
// Add the buttons to the parent WrapPanel using the Children.Add method.
myWrapPanel.Children.Add(btn1);
myWrapPanel.Children.Add(btn2);
myWrapPanel.Children.Add(btn3);
// Add the WrapPanel to the MainWindow as Content
mainWindow.Content = myWrapPanel;
mainWindow.Show();
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" WindowTitle="WrapPanel Sample">
<Border HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="2">
<WrapPanel Background="LightBlue" Width="200" Height="100">
<Button Width="200">Button 1</Button>
<Button>Button 2</Button>
<Button>Button 3</Button>
<Button>Button 4</Button>
</WrapPanel>
</Border>
</Page>
コンパイルされたアプリケーションは、これと同様の新しい UI を生成します。
入れ子になったパネル要素
Panel 要素を互いに入れ子にして、複雑なレイアウトを生成することができます。これは、Panel が UI のある部分には適しているが、UI の別の部分のニーズに合致しない場合に、役立つことがあります。
アプリケーションがサポートできる入れ子の量に決められた制限はありませんが、一般的に、目的のレイアウトに必要なパネルのみを使用するようアプリケーションを制限することをお勧めします。多くの場合、Grid 要素はレイアウト コンテナとしての柔軟性を持つため、入れ子になったパネルの代用として使用できます。これにより、ツリーから不要な要素が排除され、アプリケーションのパフォーマンスが向上します。
次の例に、特定のレイアウトを達成するために、入れ子になった Panel 要素を利用する UI を作成する方法を示します。このような特定のケースでは、DockPanel 要素を使用して UI 構造を提供し、入れ子になった StackPanel 要素、Grid、および Canvas を使用して、親の DockPanel 内で子要素を正しく配置します。
Dim myDockPanel As New DockPanel()
Dim myBorder2 As New Border()
myBorder2.BorderThickness = New Thickness(1)
myBorder2.BorderBrush = Brushes.Black
DockPanel.SetDock(myBorder2, Dock.Left)
Dim myStackPanel As New StackPanel()
Dim myButton1 As New Button()
myButton1.Content = "Left Docked"
myButton1.Margin = New Thickness(5)
Dim myButton2 As New Button()
myButton2.Content = "StackPanel"
myButton2.Margin = New Thickness(5)
myStackPanel.Children.Add(myButton1)
myStackPanel.Children.Add(myButton2)
myBorder2.Child = myStackPanel
Dim myBorder3 As New Border()
myBorder3.BorderThickness = New Thickness(1)
myBorder3.BorderBrush = Brushes.Black
DockPanel.SetDock(myBorder3, Dock.Top)
Dim myGrid As New Grid()
myGrid.ShowGridLines = True
Dim myRowDef1 As New RowDefinition()
Dim myRowDef2 As New RowDefinition()
Dim myColDef1 As New ColumnDefinition()
Dim myColDef2 As New ColumnDefinition()
Dim myColDef3 As New ColumnDefinition()
myGrid.ColumnDefinitions.Add(myColDef1)
myGrid.ColumnDefinitions.Add(myColDef2)
myGrid.ColumnDefinitions.Add(myColDef3)
myGrid.RowDefinitions.Add(myRowDef1)
myGrid.RowDefinitions.Add(myRowDef2)
Dim myTextBlock1 As New TextBlock()
myTextBlock1.FontSize = 20
myTextBlock1.Margin = New Thickness(10)
myTextBlock1.Text = "Grid Element Docked at the Top"
Grid.SetRow(myTextBlock1, 0)
Grid.SetColumnSpan(myTextBlock1, 3)
Dim myButton3 As New Button()
myButton3.Margin = New Thickness(5)
myButton3.Content = "A Row"
Grid.SetColumn(myButton3, 0)
Grid.SetRow(myButton3, 1)
Dim myButton4 As New Button()
myButton4.Margin = New Thickness(5)
myButton4.Content = "of Button"
Grid.SetColumn(myButton4, 1)
Grid.SetRow(myButton4, 1)
Dim myButton5 As New Button()
myButton5.Margin = New Thickness(5)
myButton5.Content = "Elements"
Grid.SetColumn(myButton5, 2)
Grid.SetRow(myButton5, 1)
myGrid.Children.Add(myTextBlock1)
myGrid.Children.Add(myButton3)
myGrid.Children.Add(myButton4)
myGrid.Children.Add(myButton5)
myBorder3.Child = myGrid
Dim myBorder4 As New Border()
myBorder4.BorderBrush = Brushes.Black
myBorder4.BorderThickness = New Thickness(1)
DockPanel.SetDock(myBorder4, Dock.Bottom)
Dim myStackPanel2 As New StackPanel()
myStackPanel2.Orientation = Orientation.Horizontal
Dim myTextBlock2 As New TextBlock()
myTextBlock2.Text = "This StackPanel is Docked to the Bottom"
myTextBlock2.Margin = New Thickness(5)
myStackPanel2.Children.Add(myTextBlock2)
myBorder4.Child = myStackPanel2
Dim myBorder5 As New Border()
myBorder5.BorderBrush = Brushes.Black
myBorder5.BorderThickness = New Thickness(1)
Dim myCanvas As New Canvas()
myCanvas.ClipToBounds = True
Dim myTextBlock3 As New TextBlock()
myTextBlock3.Text = "Content in the Canvas will Fill the remaining space."
Canvas.SetTop(myTextBlock3, 50)
Canvas.SetLeft(myTextBlock3, 50)
Dim myEllipse As New Ellipse()
myEllipse.Height = 100
myEllipse.Width = 125
myEllipse.Fill = Brushes.CornflowerBlue
myEllipse.Stroke = Brushes.Aqua
Canvas.SetTop(myEllipse, 100)
Canvas.SetLeft(myEllipse, 150)
myCanvas.Children.Add(myTextBlock3)
myCanvas.Children.Add(myEllipse)
myBorder5.Child = myCanvas
myDockPanel.Children.Add(myBorder2)
myDockPanel.Children.Add(myBorder3)
myDockPanel.Children.Add(myBorder4)
myDockPanel.Children.Add(myBorder5)
// Define the DockPanel.
myDockPanel = new DockPanel();
// Add the Left Docked StackPanel
Border myBorder2 = new Border();
myBorder2.BorderThickness = new Thickness(1);
myBorder2.BorderBrush = Brushes.Black;
DockPanel.SetDock(myBorder2, Dock.Left);
StackPanel myStackPanel = new StackPanel();
Button myButton1 = new Button();
myButton1.Content = "Left Docked";
myButton1.Margin = new Thickness(5);
Button myButton2 = new Button();
myButton2.Content = "StackPanel";
myButton2.Margin = new Thickness(5);
myStackPanel.Children.Add(myButton1);
myStackPanel.Children.Add(myButton2);
myBorder2.Child = myStackPanel;
// Add the Top Docked Grid.
Border myBorder3 = new Border();
myBorder3.BorderThickness = new Thickness(1);
myBorder3.BorderBrush = Brushes.Black;
DockPanel.SetDock(myBorder3, Dock.Top);
Grid myGrid = new Grid();
myGrid.ShowGridLines = true;
RowDefinition myRowDef1 = new RowDefinition();
RowDefinition myRowDef2 = new RowDefinition();
ColumnDefinition myColDef1 = new ColumnDefinition();
ColumnDefinition myColDef2 = new ColumnDefinition();
ColumnDefinition myColDef3 = new ColumnDefinition();
myGrid.ColumnDefinitions.Add(myColDef1);
myGrid.ColumnDefinitions.Add(myColDef2);
myGrid.ColumnDefinitions.Add(myColDef3);
myGrid.RowDefinitions.Add(myRowDef1);
myGrid.RowDefinitions.Add(myRowDef2);
TextBlock myTextBlock1 = new TextBlock();
myTextBlock1.FontSize = 20;
myTextBlock1.Margin = new Thickness(10);
myTextBlock1.Text = "Grid Element Docked at the Top";
Grid.SetRow(myTextBlock1, 0);
Grid.SetColumnSpan(myTextBlock1, 3);
Button myButton3 = new Button();
myButton3.Margin = new Thickness(5);
myButton3.Content = "A Row";
Grid.SetColumn(myButton3, 0);
Grid.SetRow(myButton3, 1);
Button myButton4 = new Button();
myButton4.Margin = new Thickness(5);
myButton4.Content = "of Button";
Grid.SetColumn(myButton4, 1);
Grid.SetRow(myButton4, 1);
Button myButton5 = new Button();
myButton5.Margin = new Thickness(5);
myButton5.Content = "Elements";
Grid.SetColumn(myButton5, 2);
Grid.SetRow(myButton5, 1);
myGrid.Children.Add(myTextBlock1);
myGrid.Children.Add(myButton3);
myGrid.Children.Add(myButton4);
myGrid.Children.Add(myButton5);
myBorder3.Child = myGrid;
// Add the Bottom Docked StackPanel.
Border myBorder4 = new Border();
myBorder4.BorderBrush = Brushes.Black;
myBorder4.BorderThickness = new Thickness(1);
DockPanel.SetDock(myBorder4, Dock.Bottom);
StackPanel myStackPanel2 = new StackPanel();
myStackPanel2.Orientation = Orientation.Horizontal;
TextBlock myTextBlock2 = new TextBlock();
myTextBlock2.Text = "This StackPanel is Docked to the Bottom";
myTextBlock2.Margin = new Thickness(5);
myStackPanel2.Children.Add(myTextBlock2);
myBorder4.Child = myStackPanel2;
// Add the Canvas, that fills remaining space.
Border myBorder5 = new Border();
myBorder4.BorderBrush = Brushes.Black;
myBorder5.BorderThickness = new Thickness(1);
Canvas myCanvas = new Canvas();
myCanvas.ClipToBounds = true;
TextBlock myTextBlock3 = new TextBlock();
myTextBlock3.Text = "Content in the Canvas will Fill the remaining space.";
Canvas.SetTop(myTextBlock3, 50);
Canvas.SetLeft(myTextBlock3, 50);
Ellipse myEllipse = new Ellipse();
myEllipse.Height = 100;
myEllipse.Width = 125;
myEllipse.Fill = Brushes.CornflowerBlue;
myEllipse.Stroke = Brushes.Aqua;
Canvas.SetTop(myEllipse, 100);
Canvas.SetLeft(myEllipse, 150);
myCanvas.Children.Add(myTextBlock3);
myCanvas.Children.Add(myEllipse);
myBorder5.Child = myCanvas;
// Add child elements to the parent DockPanel.
myDockPanel.Children.Add(myBorder2);
myDockPanel.Children.Add(myBorder3);
myDockPanel.Children.Add(myBorder4);
myDockPanel.Children.Add(myBorder5);
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" WindowTitle="Nested Panels">
<Border Background="AliceBlue"
Width="400"
Height="300"
BorderBrush="DarkSlateBlue"
BorderThickness="2"
HorizontalAlignment="Left"
VerticalAlignment="Top">
<DockPanel>
<Border BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Left">
<StackPanel>
<Button Margin="5">Left Docked</Button>
<Button Margin="5">StackPanel</Button>
</StackPanel>
</Border>
<Border BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Top">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock FontSize="20" Margin="10" Grid.ColumnSpan="3" Grid.Row="0">Grid Element Docked to the Top.</TextBlock>
<Button Grid.Row="1" Grid.Column="0" Margin="5">A Row</Button>
<Button Grid.Row="1" Grid.Column="1" Margin="5">of Button</Button>
<Button Grid.Row="1" Grid.Column="2" Margin="5">Elements</Button>
</Grid>
</Border>
<Border BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Bottom">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="5">This StackPanel is Docked to the Bottom.</TextBlock>
</StackPanel>
</Border>
<Border BorderBrush="Black" BorderThickness="1">
<Canvas ClipToBounds="True">
<TextBlock Canvas.Top="50" Canvas.Left="50">
Content in the Canvas will Fill the remaining Space.
</TextBlock>
<Ellipse Height="100" Width="125" Fill="CornflowerBlue" Stroke="Aqua" Canvas.Top="100" Canvas.Left="150"/>
</Canvas>
</Border>
</DockPanel>
</Border>
</Page>
コンパイルされたアプリケーションは、これと同様の新しい UI を生成します。
カスタム パネル要素
WPF により柔軟なレイアウト コントロール配列が提供されますが、ArrangeOverride および MeasureOverride メソッドをオーバーライドすることにより、カスタム レイアウト動作も実行できます。このオーバーライド メソッド内で新しい配置動作を定義することにより、カスタムのサイズ変更と配置が実行されます。
同様に、派生クラス (Canvas、Grid など) に基づくカスタム レイアウト動作は、ArrangeOverride および MeasureOverride メソッドをオーバーライドすることにより定義できます。
次のマークアップは、C# を使用して、カスタム Panel 要素を作成する方法を示します。PlotPanel として定義されたこの新しい Panel では、ハードコーディングされた x- および y- 座標を使って子要素の位置付けがサポートされます。この例では、Rectangle 要素 (表示されていません) は、プロット位置 50 (x) と 50 (y) に配置されます。
Public Class PlotPanel
Inherits Panel
'Override the default Measure method of Panel.
Protected Overrides Function MeasureOverride(ByVal availableSize As System.Windows.Size) As System.Windows.Size
Dim childSize As Size = CType(availableSize, Size)
For Each child As UIElement In InternalChildren
child.Measure(childSize)
Next
Return MyBase.MeasureOverride(availableSize)
End Function
Protected Overrides Function ArrangeOverride(ByVal finalSize As System.Windows.Size) As System.Windows.Size
For Each child As UIElement In InternalChildren
Dim x As Double = 50
Dim y As Double = 50
child.Arrange(New Rect(New System.Windows.Point(x, y), child.DesiredSize))
Next
Return MyBase.ArrangeOverride(finalSize)
End Function
End Class
public class PlotPanel : Panel
{
// Default public constructor
public PlotPanel()
: base()
{
}
// Override the default Measure method of Panel
protected override Size MeasureOverride(Size availableSize)
{
Size panelDesiredSize = new Size();
// In our example, we just have one child.
// Report that our panel requires just the size of its only child.
foreach (UIElement child in InternalChildren)
{
child.Measure(availableSize);
panelDesiredSize = child.DesiredSize;
}
return panelDesiredSize ;
}
protected override Size ArrangeOverride(Size finalSize)
{
foreach (UIElement child in InternalChildren)
{
double x = 50;
double y = 50;
child.Arrange(new Rect(new Point(x, y), child.DesiredSize));
}
return finalSize; // Returns the final Arranged size
}
}
サンプル全体を確認するには、「簡単なカスタム パネルの作成のサンプル」を参照してください。
より複雑なカスタム パネルの実装を確認するには、「カスタム コンテンツ折り返しパネルの作成のサンプル」を参照してください。
ローカリゼーション/グローバリゼーション サポート
WPF は、ローカライズ可能な UI の作成を支援する多数の機能をサポートしています。
すべてのパネル要素は、FlowDirection プロパティをサポートしており、ユーザーのロケールまたは言語設定に基づいて内容を動的に再フローする際に使用できます。詳細については、FlowDirection を参照してください。
SizeToContent プロパティは、アプリケーション開発者がローカライズされた UI のニーズを予測できるメカニズムを提供します。親 Window は、このプロパティの WidthAndHeight 値を使用することにより、コンテンツに合わせて常に動的にサイズを変更し、シミュレート用の高さまたは幅制限による制限を受けません。
DockPanel、Grid、および StackPanel はすべて、ローカライズ可能な UI に適しています。ただし Canvas は、コンテンツを絶対的に配置してローカライズを困難にするため、適切ではありません。
ローカライズ可能な ユーザー インターフェイス (UI) を備えた WPF アプリケーションの作成方法の詳細については、「自動レイアウトの使用の概要」を参照してください。