WPFにはコントロールを配置するのにレイアウト用のコントロールがあります。
各コントロールをウィンドウにドラッグして、座標(Margin)指定で配置していくことも可能ですが、ある程度の情報量を持った画面を作成する際は、レイアウトコントロールを使うと便利です。
今回は、行と列を指定して配置することができるGridコントロールついて紹介したいと思います。
Gridコントロールについて
レイアウトイメージ
Gridレイアウトは、HTMLでのテーブルのようなイメージです。
列と行を作成して、そこにコントロールを配置していくことで、コントロールを揃えて表示したり、領域に合わせてサイズを配分したりすることができます。
Excelのようなイメージと考えていただいてもよいかと思います。
下記のように1列目にタイトルのテキストブロックを配置して、2列目に入力用のコントロールを配置するような、マスタ入力エリアに使用したりすると便利です。
| タイトル1 | ここにTextBox |
| タイトル2 | ここにComboBox |
| タイトル3 |
コントロールの配置指定方法
Gridのどこに子コントロールを配置するかは、WPFの添付プロパティという機構を使って、子コントロール側に指定します。
Gridを何列、何行にわけるかは、Gridコントロール自体に定義し、子コントロール側に列番号、行番号を指定します。
Gridコントロールを使用することで、整列されたレイアウトを作成することができます。
また、子コントロールの位置も簡単に変更することができますので、レイアウトを変更する際も便利です。
子コントロールの位置だけでなく、大きさも配置する列、行に依存させることもできるため、WindowやGridの大きさが変わったときに合わせて子コントロールも大きさも変更されるようにすることもできます。
それでは、サンプルで指定方法を紹介します。
使い方サンプル
それでは早速Gridコントロールを使用していきたいと思います。
前に作成したWPFのHello Worldプロジェクトに新しい画面を追加してサンプルを作成します。
メイン画面を下記のように修正します。

一番下の表示ボタンでGridコントロールを使用したサンプル画面を表示します。
ここではサンプル画面を「GridLayoutWindow.xaml」として、ウインドウを追加しておきます。
デザイナで表示ボタンをダブルクリックし、クリックイベントに下記を記載します。
private void ButtonDisplayGridSample_Click(object sender, RoutedEventArgs e)
{
GridLayoutWindow window = new GridLayoutWindow();
window.Show();
}
クリックイベントハンドラを「ButtonDisplayGridSample_Click」というメソッド名にしています。これで新しく追加したGridレイアウトサンプル用の画面が表示されます。
このウインドウにサンプルコードを記載していきます。
シンプル タイトルと値
実は、新しいウィンドウを追加すると、デフォルトでGridコントロールが追加してあります。
一番上のレイアウトコントロールとしてGridが配置されています。
今回は、このグリッドを3行2列に区切って、子コントロールを配置します。マスタ編集画面等で見るタイトルと値を入力するテキストボックスを配置したいと思います。
追加した「GridLayoutWindow.xaml」を下記のように記載します。
<Window x:Class="HelloWpfApp.GridLayoutWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:HelloWpfApp"
mc:Ignorable="d"
Title="GridLayoutWindow" Height="150" Width="400">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="36" />
<RowDefinition Height="36" />
<RowDefinition Height="36" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="名前" HorizontalAlignment="Right" VerticalAlignment="Center" FontSize="18" Margin="0,0,5,0" />
<TextBox Grid.Column="1" Grid.Row="0" Margin="1" FontSize="15" VerticalContentAlignment="Center" />
<TextBlock Grid.Column="0" Grid.Row="1" Text="住所" HorizontalAlignment="Right" VerticalAlignment="Center" FontSize="18" Margin="0,0,5,0" />
<TextBox Grid.Column="1" Grid.Row="1" Margin="1" FontSize="15" VerticalContentAlignment="Center" />
<TextBlock Grid.Column="0" Grid.Row="2" Text="電話番号" HorizontalAlignment="Right" VerticalAlignment="Center" FontSize="18" Margin="0,0,5,0" />
<TextBox Grid.Column="1" Grid.Row="2" Margin="1" FontSize="15" VerticalContentAlignment="Center" />
</Grid>
</Window>
列の定義を「Grid.ColumnDefinitions」で列の定義、「Grid.RowDefinitions」で行の定義を行います。「ColumnDefinition」のタグ数分列が、「RowDefinition」のタグ数分行ができます。
列の場合は、「Width」で幅を、行の場合は、「Height」で高さを定義します。
上記の場合は、列は2列で、1列目は120、残りを2列目に割り当てています。「*」を指定すると割合で指定になり、他に「*」がないので、2列目にすべてが割り当てられます。
同様の考え方で、行は3行で、すべて同じ高さ36になります。
次に子コントロールの配置ですが、Gridの添付プロパティで子コントロール側に「Grid.Column」で列を、「Grid.Row」で行を指定します。0始まりで、連番で指定します。
上記の場合、名前、住所、電話番号の順で配置されます。
実行結果は下記のようになります。

指定したレイアウトで配置されます。
ウインドウの幅を広げると2列目のテキストボックスの幅も広がります。

入れ子
Gridコントロールの子にGridコントロールを配置することもできます。
例えば、画面の上半分は2×2の分割下半分は1×1にしたいなど、柔軟に対応することが可能です。
今回変更したメイン画面を下記のように変更します。

「表示2」ボタンから入れ子を使用したGridサンプルページを開きます。
ここでは、「GridLayout2Window.xaml」として新しいウィンドウを追加し、表示2ボタンクリックイベントハンドラから新しい画面を呼び出します。
private void ButtonDisplayGridSample2_Click(object sender, RoutedEventArgs e)
{
GridLayout2Window window = new GridLayout2Window();
window.Show();
}
「GridLayout2Window.xaml」を上半分は2×2の分割下半分は1×1にします。
<Window x:Class="HelloWpfApp.GridLayout2Window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:HelloWpfApp"
mc:Ignorable="d"
Title="GridLayout2Window" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border Grid.Row="0" Grid.Column="0" Background="LightBlue">
<TextBlock Text="1-1" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<Border Grid.Row="0" Grid.Column="1" Background="LightYellow">
<TextBlock Text="1-2" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<Border Grid.Row="1" Grid.Column="0" Background="LightGreen">
<TextBlock Text="2-1" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<Border Grid.Row="1" Grid.Column="1" Background="LightCoral">
<TextBlock Text="2-2" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</Grid>
<Grid Grid.Row="1">
<Border Background="LightSalmon">
<TextBlock Text="1-1" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</Grid>
</Grid>
</Window>
基本的な考え方は同じです。最初に2行のグリッドを作成し、1行目に2×2、2行目に1×1のグリッドを入れます。
実行した際にわかりやすくなるように背景色と、行-列番号を表示します。(XAML上はゼロ始まりですが、わかりやすいように1始まりで表示しています。
早速実行して表示2ボタンを押下します。

このように2×2と1×1のレイアウトを作成することができます。
Gridコントロールの列結合を使えばGrid一つでも同じレイアウトを作成することも可能です。
エリアで表示する情報が違い明らかにレイアウトが異なってくる場合は、今回のように先に大きく行や列を分けて、入れ子にしておいたほうが後々修正が入った場合に対応がしやすくなるかと思います。結合ですべて対応すると、後から行や列を追加した際に、結合数を修正したりと複雑になることがありますので、ご注意ください。
スプリッター
Gridの隣り合う列や、行はスプリッターというコントロールを使うことで動的に幅や、高さを変更することができます。
これにより、ユーザーが自由にレイアウトを決めることができます。
入れ子で作成したサンプルにスプリッターを入れます。
XAMLファイルを下記のように変更します。
<Window x:Class="HelloWpfApp.GridLayout2Window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:HelloWpfApp"
mc:Ignorable="d"
Title="GridLayout2Window" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="2" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border Grid.Row="0" Grid.Column="0" Background="LightBlue">
<TextBlock Text="1-1" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<Border Grid.Row="0" Grid.Column="1" Background="LightYellow">
<TextBlock Text="1-2" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<Border Grid.Row="1" Grid.Column="0" Background="LightGreen">
<TextBlock Text="2-1" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<Border Grid.Row="1" Grid.Column="1" Background="LightCoral">
<TextBlock Text="2-2" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</Grid>
<GridSplitter Grid.Row="1" HorizontalAlignment="Stretch" Background="Gold" />
<Grid Grid.Row="2">
<Border Background="LightSalmon">
<TextBlock Text="1-1" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</Grid>
</Grid>
</Window>
今回は2×2と1×1の間にスプリッターを入れました。
一番上のGridの行を3つに変更し、真ん中の行にGridSplitterを配置します。水平方向のスプリッターなので、HorizontalAlignmentをStretchにします。これをしないとスプリッターとならないのでご注意ください。背景色はわかりやすく、摘まみやすくするために変更しています。
実行するとスプリッターをつまんで大きさを動的に変更することができます。

↓ 金色の線にマウスを近づけると大きさを変更できるアイコンに変わりますのでドラッグします。

下にドラッグすることで上の領域を大きく、下の領域を小さくすることができます。
この大きさをアプリケーションで覚えることでユーザの好きな大きさで次回も表示することも可能になります。
以上で、Gridレイアウトの紹介は終了です。
引き続き別のレイアウトの紹介を行っていきたいと思います。



コメント