fc2ブログ

antsk blog

WPFパネルの使い方まとめ

しばらくWPFを触ってて、当初はWinFormとかなり異なる作り方に難儀したけど
だいぶ理解してきたのでレイアウト(というか、パネルの使い方)の基本(と、自分が勝手に思っていること)をメモ。

基本



レイアウトはGridが基本。
Gridにできないことなど、あんまりない。
いろいろと試行錯誤した結果、少なくともWinFormのダイアログと同じような画面を作る場合は
以下の単純なルールが良さそう。


ようするに、


というのを再帰的に行っていけば、WPFがうまい具合に要素を配置してくれる。

パターン



2分割



縦か横に2分割する場合、上(左)部のサイズを固定にするか、下(右)部のサイズを固定にするかでちょっと違う。

上または左が固定



例:
fixtop.jpgfixleft.jpg

テンプレート

上が固定の場合:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<SubPanel Grid.Row="0">
上のほうのコントロール
</SubPanel>
<SubPanel Grid.Row="1">
下のほうのコントロール
</SubPanel>
</Grid>


左が固定の場合:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<SubPanel Grid.Column="0">
左側のコントロール
</SubPanel>
<SubPanel Grid.Column="1">
右側のコントロール
</SubPanel>
</Grid>


一般的な「上から下」、「左から右」へのコントロール配置。

このパターンでは常に DockPanel をかわりに使うことができる。

上が固定の場合:
<DockPanel>
<SubPanel DockPanel.Dock="Top">

</SubPanel>
<SubPanel>

</SubPanel>
</DockPanel>


左が固定の場合:
<DockPanel>
<SubPanel DockPanel.Dock="Left">

</SubPanel>
<SubPanel>

</SubPanel>
</DockPanel>


DockPanelの方が記述量が減るのでオススメ。

下または右が固定



例:
fixbuttom.jpgfixright.jpg

下が固定の場合:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<SubPanel Grid.Row="0">
上のほうのコントロール
</SubPanel>
<SubPanel Grid.Row="1">
下のほうのコントロール
</SubPanel>
</Grid>


右が固定の場合:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<SubPanel Grid.Column="0">
左側のコントロール
</SubPanel>
<SubPanel Grid.Column="1">
右側のコントロール
</SubPanel>
</Grid>


「OK」「キャンセル」などのボタンは、
たいていダイアログウインドウの下 or 右に配置するのでこのパターンになる。

このパターンではDockPanelを使えない場合が多いことに注意。

DockPanelは「最後の要素」を残りの領域全体に割り当てるので、どうしても
<DockPanel>
<SubPanel DockPanel.Dock="Buttom">
下のほうのコントロール
</SubPanel>
<SubPanel>
上のほうのコントロール
</SubPanel>
</DockPanel>

と、下や右のコントロールを先に書かなければいけない。

タブオーダーは明示的にTabIndexを指定しなければXAMLの記述順になるから、
これだとTabキーで移動したときの動きがわけわからなくなる。

結局、ステータスバーやコンボボックスのドロップダウンボタンのように、
下や右のコントロールがフォーカスを受け取らない場合にのみDockPanelが使える。

3分割



3分割では、中央を * 幅にする。

menuandstatus.jpg
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<SubPanel Grid.Row="0">
上のほうのコントロール
</SubPanel>
<SubPanel Grid.Row="1">
中央のコントロール
</SubPanel>
<SubPanel Grid.Row="2">
下のほうのコントロール
</SubPanel>
</Grid>


やはりこれも、下や右のコントロールがフォーカスを受け取らなければDockPanelを使うことができる。
<DockPanel>
<SubPanel DockPanel.Dock="Top">
上のほうのコントロール
</SubPanel>
<SubPanel DockPanel.Dock="Buttom">
下のほうのコントロール
</SubPanel>
<SubPanel>
中央のコントロール
</SubPanel>
</DockPanel>


ただ、このパターンは


という形で使うことがほとんどなので、
普通にDockPanelでいい場合のほうが多いかも。

いっぱい



単純に縦または横に並べるだけなら、幅Autoで必要な行数・列数だけ作る。

itemlist.jpg
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<SubPanel Grid.Row="0" >

</SubPanel>
<SubPanel Grid.Row="1" >

</SubPanel>
<SubPanel Grid.Row="2" >

</SubPanel>
<SubPanel Grid.Row="3">

</SubPanel>
....
</Grid>


このような場合は、StackPanelを代わりに使えばインデックスを指定しなくていいのでラクチン。
<StackPanel>
<SubPanel>

</SubPanel>
<SubPanel>

</SubPanel>
<SubPanel>

</SubPanel>
<SubPanel>

</SubPanel>
....
</StackPanel>


縦横揃え



左側にタイトルラベル、右側に入力コントロール、という形で縦に並んでいるパターン。

align.jpg
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<SubPanel Grid.Row="0" Grid.Column="0">
タイトル1
</SubPanel>
<SubPanel Grid.Row="0" Grid.Column="1">
入力1
</SubPanel>
<SubPanel Grid.Row="1" Grid.Column="0">
タイトル2
</SubPanel>
<SubPanel Grid.Row="1" Grid.Column="1">
入力2
</SubPanel>
....
</Grid>


恐るべき面倒くささを誇る。
何とかこれをうまい具合にRow/Column指定せずに済ませられればいいんだけど……。

位置あわせ



さて、上記のパネル指定だけだと、コントロールは隙間なくぴっちり配置されてしまう。

例:単にこれだけだと、
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0"
Orientation="Horizontal">
<Button Content="Button1" />
<Button Content="Button2" />
<Button Content="Button3" />
</StackPanel>
<DockPanel Grid.Row="1">
<TextBlock DockPanel.Dock="Top"
Text="一覧" />
<ListBox>
<ListBoxItem Content="Item1" />
<ListBoxItem Content="Item2" />
<ListBoxItem Content="Item3" />
<ListBoxItem Content="Item4" />
<ListBoxItem Content="Item5" />
<ListBoxItem Content="Item6" />
</ListBox>
</DockPanel>
</Grid>


こんな感じ。
nopadding.jpg

このためPaddingやMarginを指定して微調整する必要がある。

このとき、個々のButtonなどには直接レイアウト情報を設定せずに
パネルのMarginやResourceのスタイル指定で調整すると
複数のコントロールをきれいにあわせることができる。

コントロールレベルの要素にはバインディングなんかのデータ情報だけ書いて
表示とデータの分離を進めておくと何かと良いかも。

例:こんな感じにすると
<Grid Margin="6" > <!-- Margin指定で全体を内側に寄せる -->
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0"
Orientation="Horizontal">
<StackPanel.Resources>
<!-- ButtonのStyle指定で隙間と大きさを調整 -->
<Style TargetType="Button">
<Setter Property="Margin"
Value="3" />
<Setter Property="Padding"
Value="5 0" />
</Style>
</StackPanel.Resources>
<Button Content="Button1" />
<Button Content="Button2" />
<Button Content="Button3" />
</StackPanel>
<DockPanel Grid.Row="1"
Margin="0 3" ><!-- Margin指定でちょっとボタンと離す -->
<TextBlock DockPanel.Dock="Top"
Text="一覧" />
<ListBox>
<ListBoxItem Content="Item1" />
<ListBoxItem Content="Item2" />
<ListBoxItem Content="Item3" />
<ListBoxItem Content="Item4" />
<ListBoxItem Content="Item5" />
<ListBoxItem Content="Item6" />
</ListBox>
</DockPanel>
</Grid>


こうなる
padding.jpg

備考



ちなみに自分はBlendとか持ってないので
デザインツールを使用してXAMLを書くことはまったく考慮してない。

VSのWPFデザイナ?
あれは単にXAML編集結果をリアルタイムで表示してくれるビューです。

マウスでぺたぺたコントロールを貼り付けてUIを作る時代は終わった……。

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2009/09/10(木) 00:57:51|
  2. WPF
  3. | トラックバック:0
  4. | コメント:0
<<WPFコントロールのテンプレートをいじりたい | ホーム | MVVMでViewModelからダイアログを扱いたい・続き>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://antsk.blog99.fc2.com/tb.php/7-d284b810
この記事にトラックバックする(FC2ブログユーザー)

プロフィール

antsk

Author:antsk
主にC#のプログラマ。

最新記事

最新コメント

最新トラックバック

月別アーカイブ

カテゴリ

未分類 (0)
.net (1)
WPF (8)

検索フォーム

RSSリンクの表示

リンク

このブログをリンクに追加する

ブロとも申請フォーム

この人とブロともになる

QRコード

QRコード