UIパーツの自動レイアウトはWPFの特徴の一つです。
個人的にはWinFormsに対してWPFが優れている部分だと考えています。
この自動レイアウトは以下で述べるパネル系コントロール上で配置することで実現されますが、
どのコントロールを使えばよいのか悩む場面に遭遇したので少し整理してみたいと思います。
主要なパネル系とそれぞれの特徴
パネル名,特徴,主な用途
・StackPanel
要素を一列(垂直または水平)に並べます。
フォームのコントロールやメニューなど、単純なリスト状のレイアウト。
・WrapPanel
要素が一行または一列に収まらない場合、自動的に折り返して次の行/列に配置します。
ボタンのグループやタグの一覧など、流動的なコンテンツの配置。
・DockPanel
要素を上下左右の端に固定(ドッキング)して配置します。最後の要素は残りの領域を埋めます。
メニューバー、ステータスバー、サイドバーなどを持つ標準的なウィンドウレイアウト。
・Grid
要素を行と列で構成されるセルに配置します。柔軟なサイズ調整や位置指定が可能です。
複雑なフォームや表形式のデータ表示、レスポンシブなレイアウト。 WPFで最も多用されるパネルです。
・Canvas
“要素を絶対座標 (X, Y) で配置します。要素のサイズや位置は、他の要素や親のサイズに影響されません。”
図形描画やゲームの画面など、座標ベースの精密な配置。
配置するコントロールのサイズ、座標を絶対値で指定したい場合
Canvasを使う。
WinFormsの様に幅や高さ、座標を指定してコントロールを配置するため、親コントロール(ウィンドウ)のサイズ変更に合わせて、
自動レイアウト変更がされない。
WPFのパネル的には特殊の部類なので、必要に迫られて初めて使うぐらいの心づもりで。
最初に試すべきパネル
とりあえずGridを使う。
コントロールを配置する幅や高さを、親コントロール(ウィンドウなど)基準に相対的な割合で指定できる。
相対的な割合は親要素の幅や高さの動的変動に連動するため、Gridで配置されたコントロールの幅や高さも自動的に連動する。
また、Gridは比較的自由なレイアウトを組むことが出来る点でも基本と言えるでしょう。
理屈は抜きにして、レイアウトに悩むのであれば、とりあえずGridで格子を作成しコントロールを配置すると良いでしょう。
メニューやステータスバーを配置する場合
ウィンドウに対しヘッダー、フッター、左領域、右領域、メイン領域など、レイアウトが決まっている場合はDockPanelを使うと良いです。
メイン領域以外は、コントロールに配置するために最低限必要な幅や高さを指定することが出来ます。
メイン領域は最後に定義し、残りの領域全体が確保されることになります。
メニューやステータスバーをレイアウトするようなアプリケーションを作成する場合に向いているパネルと言えます。
単純な「積み上げ」
StackPanelは縦または横方向にコントロールを積み上げるパネルになります。
理解はしやすいコントロールですが、幅や高さが自動的に設定されるので、細かなサイズをコントロールすることには向いていないコントロールかもしれません。
自動的な「折り返し」
WrapPanelは、任意の幅と高さを設定したコントロールを、自動レイアウトするためのコントロールで、ウィンドウ内に収まるように自動的に改行される感じになります。
ある意味SatckPanelの対極となるパネルと言えるのでは無いでしょうか?
推奨されるレイアウトパネルの検討順位
Grid → DockPanel → (StackPanel / WrapPanel) → 例外…Canvas
1. Grid:
理由: ほとんどすべての複雑なレイアウト(フォーム、ダッシュボード、複合的なセクション)に対応でき、相対的なサイズ調整(*)による自動レイアウトの核心を担うため。悩んだらまずGridを使います。
2. DockPanel:
理由: アプリケーションの枠組み(ヘッダー、フッター、サイドバー)が固定されている場合に非常に強力です。Gridでセクションを分けた後、個別のセクション内でDockPanelを使用して、ツールバーなどを配置することもよくあります。
3. StackPanel / WrapPanel (部分的な配置に):
理由: これらは単独でアプリケーション全体をレイアウトするのには不向きですが、GridやDockPanelで分割された小さな領域内で、ボタンやリストを整列させるなど、局所的な配置に優れています。
4. Canvas (最後の例外):
理由: 絶対座標での配置が必要な特別な描画用途に限ります。
結論
WPFでGUIアプリを作る場合、自動レイアウトの機能を活かすことを考えると、使うべきパネルはGridだと思います。

コメント