[WPF] WPF入門 ~レイアウト [Grid]~

投稿日 : 2009年3月17日 10:12
今回はレイアウトコントロールの1つ、System.Windows.Controls.Gridコントロールについてです。
では早速MSDNでの説明を見てみましょう。

列と行で構成されている柔軟なグリッド領域を定義します。Grid 内で定義された列と行は、Star サイズ変更機能を利用して、残りのスペースを比率に応じて分配できます。Star が行または列の高さまたは幅として選択された場合、その列または行は、使用可能な残りのスペースの領域の加重比率分を受け取ります。これは、列または行内のコンテンツのサイズに基づいてスペースを均等に分配する Auto とは対照的です。Extensible Application Markup Language (XAML) を使用する場合、この値は * または 2* と表現されます。最初のケースでは、行または列は使用可能なスペース領域を 1 回受け取り、2 番目のケースでは 2 回受け取ることになります。スター サイズ変更の詳細については、「スター サイズ変更の使用」のサンプルを参照してください。HorizontalAlignment を使用してスペースを比率に応じて分配する方法と、Stretch の VerticalAlignment 値を組み合わせることにより、画面スペースのパーセンテージ単位でレイアウト スペースを分割できます。Grid は、この方法でスペースを分配できる唯一のレイアウト パネルです。

少し長い説明ですが徐々に見ていきましょう。
まずは簡単なGridコントロールを使用した例です。

<Window x:Class="Window1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="Window1" Height="300" Width="300">
    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
    </Grid>
</Window>

上記例では、「3行3列」で構成されているGridコントロールを作成しています。
Gridコントロールの行の作成にはRowDefinitionsプロパティに任意数のRowDefinitionオブジェクトを追加し定義します。
また、列の作成にはColumnDefinitionsプロパティに任意数のColumnDefinitionオブジェクトを追加し定義します。

RowDefinitionオブジェクトは行を定義するオブジェクトなので、Heightプロパティがあります。
またColumnDefinitionオブジェクトは列を定義するオブジェクトなので、Widthプロパティがあります。

このHeightプロパティとWidthプロパティはGridLength構造体型となっています。
GridLength構造体は「Starサイズ変更機能」をサポートしている構造体です。
このGridLength構造体はとてもGridコントロールで深く関わる物なのでまずGridLength構造体について見てみましょう。

GridLength構造体は以下のような特性を持った構造体です。
  • 数値が指定された場合は、その値をピクセル数として扱う。
  • スターサイズ(アスタリスク "*" )を指定された場合は、スペースを比率に応じて分配する。
  • リテラルの "Auto" が指定された場合は、列または行内のコンテンツのサイズに基づいてスペースを分配する。
このような特性があります。

まずは数値指定の場合の例を見てみましょう。

<Window x:Class="Window1"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="Window1" Height="300" Width="300">
    <Grid ShowGridLines="True">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="125"/>
            <ColumnDefinition Width="50"/>
            <ColumnDefinition Width="125"/>
        </Grid.ColumnDefinitions>
    </Grid>
</Window>



上記例では、左列が125pxとして、中央列が50pxとして、右列が125pxとして指定されています。



次にスターサイズ指定の場合の例を見てみましょう。

<Window x:Class="Window1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="Window1" Height="300" Width="300">
    <Grid ShowGridLines="True">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="0.25*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
    </Grid>
</Window>



上記例を少し細かく解説します。
スターサイズ指定の場合、既定の "*" を1として比率が計算されます。
よって「2*」の場合は「*」の2倍の領域になり、「0.5*」の場合は「*」の1/2になります。
上記例での2列目では「0.25*」と指定されているので「*」の1/4という比率で領域が割り当てられます。
このようにスターサイズは全体における比率指定を行ってレイアウトを構築します。



次にリテラルの "Auto" を使用した例を見てみましょう。

<Window x:Class="Window1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="Window1" Height="300" Width="300">
    <Grid ShowGridLines="True">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
 
        <Button Width="200" Grid.Column="1">Button</Button>
    </Grid>
</Window>



GridLength構造体はリテラル "Auto" を受け取ると、その要素内の子要素のサイズに合わせサイズを算出します。
上記例では、2列目の子要素としてButtonコントロールが指定されており、またButtonコントロールの幅が200pxとして指定されている為、2列目の幅も200pxとして計算されます。
このように子要素によって動的にサイズ調整が必要な場合はリテラルの "Auto" を使用するととても便利です。



それではGridコントロールのレイアウトについて戻りたいと思います。
Gridコントロールの子要素は、自身が配置される領域を添付プロパティを使用して定義します。
その例を見てみましょう。

XAML使用例
<Window x:Class="Window1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="Window1" Height="300" Width="300">
    <Grid ShowGridLines="True">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
 
        <Button Grid.Column="0" Grid.Row="0">左上</Button>
        <Button Grid.Column="1" Grid.Row="1">右下</Button>
    </Grid>
</Window>

コード使用例(VB)
Class Application
    Private Sub Application_Startup(ByVal sender As Object, ByVal e As System.Windows.StartupEventArgs) Handles Me.Startup
        Dim mainWindow As New Window1()
 
        Dim myGrid As New Grid()
        myGrid.ShowGridLines = True
 
        Dim column1 As New ColumnDefinition()
        Dim column2 As New ColumnDefinition()
        myGrid.ColumnDefinitions.Add(column1)
        myGrid.ColumnDefinitions.Add(column2)
 
        Dim row1 As New RowDefinition()
        Dim row2 As New RowDefinition()
        myGrid.RowDefinitions.Add(row1)
        myGrid.RowDefinitions.Add(row2)
 
        Dim button1 As New Button()
        button1.Content = "左上"
        Grid.SetColumn(button1, 0)
        Grid.SetRow(button1, 0)
 
        Dim button2 As New Button()
        button2.Content = "右下"
        Grid.SetColumn(button2, 1)
        Grid.SetRow(button2, 1)
 
        myGrid.Children.Add(button1)
        myGrid.Children.Add(button2)
 
        mainWindow.Content = myGrid
        mainWindow.Show()
    End Sub
End Class

コード使用例(C#)
public partial class App : Application
{
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        Window1 mainWindow = new Window1();
 
        Grid myGrid = new Grid();
        myGrid.ShowGridLines = true;
 
        ColumnDefinition column1 = new ColumnDefinition();
        ColumnDefinition column2 = new ColumnDefinition();
        myGrid.ColumnDefinitions.Add(column1);
        myGrid.ColumnDefinitions.Add(column2);
 
        RowDefinition row1 = new RowDefinition();
        RowDefinition row2 = new RowDefinition();
        myGrid.RowDefinitions.Add(row1);
        myGrid.RowDefinitions.Add(row2);
 
        Button button1 = new Button();
        button1.Content = "左上";
        Grid.SetColumn(button1, 0);
        Grid.SetRow(button1, 0);
 
        Button button2 = new Button();
        button2.Content = "右下";
        Grid.SetColumn(button2, 1);
        Grid.SetRow(button2, 1);
 
        myGrid.Children.Add(button1);
        myGrid.Children.Add(button2);
 
        mainWindow.Content = myGrid;
        mainWindow.Show();
    }
}



上記例のように、Gridの子要素は添付プロパティを用いて自身の配置領域を指定する事によりレイアウトを行います。
Gridコントロールは動的なコントロールのサイズ変更等があるレイアウトにとても相性が良いです。

今回使用した例ではGridコントロールのShowGridLinesプロパティを使用してグリッド線を表示していました。
ShowGridLinesプロパティを使用することによって、Gridコントロールの領域が解り易くなるのでレイアウト構築中などにはお勧めです。

GridコントロールはCanvasコントロールに比べレイアウトに関わるオーバーヘッドが大きいですが、動的なサイズ変更等では強力なレイアウトを構築する事が出来ます。
パフォーマンス等も考慮しながら柔軟なレイアウトを構築するのが良いでしょう。

今回はレイアウト用コントロールのGridコントロールについてでした。

to be continue・・・
コメントの入力
タイトル
名前
Url
コメント