かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

WPF4.5入門 その19 「Gridコントロール part 2」

Gridコントロールでのレイアウト例

Gridコントロールは、これまで説明したStackPanelやDockPanelなどと比べて非常に強力なレイアウトコントロールになります。Gridコントロールでレイアウトするときは、これまでに紹介した方法を使って最終的なレイアウトを実現するのに必要な行と列の数と、それぞれに設定するサイズを決めて、そこに目的のコントロールを配置するという手順で行います。具体的な例としてDockPanelコントロールで作成した下図のようなレイアウトをGridで作成する方法について説明します。

順を追って作成していきます。このレイアウトには、Menu用の行、Toolbar用の行、TreeとContent用の行、StatusBar用の行の4行が必要になります。各行のサイズはMenuとToolbarとStatusBarが子要素の高さで、TreeとContentの行が残りの部分を占有します。列に注目するとTree用の列とContent用の列の2列が必要になります。左側のTreeの列は150px固定でContentの列が残りの部分を占有します。これをRowDefinitionとColumnDefinitionで記述すると以下のようなXAMLになります。

<Window x:Class="GridSample01.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
    </Grid>
</Window>

行と列の定義が出来たので子要素のButtonをGrid.Row、Grid.Column、Grid.ColumnSpan、Grid.RowSpanの添付プロパティを使って置いていきます。注意する点は、MenuとToolbarとStatusbarは2列に渡って配置するのでGrid.ColumnSpanを2にする点です。ボタンを配置したGridのXAMLを以下に示します。

<Window x:Class="GridSample01.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <!-- メニューやツールバー -->
        <Button Grid.Row="0" Grid.ColumnSpan="2" Content="Menu" />
        <Button Grid.Row="1" Grid.ColumnSpan="2" Content="Toolbar" />
        <!-- ステータスバー -->
        <Button Grid.Row="3" Grid.ColumnSpan="2" Content="StatusBar" />
        <!-- ツリーが表示される場所 -->
        <Button Grid.Row="2" Content="Tree" />
        <!-- エクスプローラーの右側の領域 -->
        <Button Grid.Row="2" Grid.Column="1" Content="Content" />
    </Grid>
</Window>

このWindowを表示すると、以下のようになります。DockPanelコントロールで作成した画面と同じ表示になっています。破線とボタンの位置を確認して表示内容とXAMLの対応を確認してください。

GridSplitterコントロール

Gridコントロールの特徴の1つとしてGridSplitterコントロールを使ったマウスでのサイズ変更への対応があります。GridSplitterコントロールをGridコントロールの区切りに沿って配置することで、エクスプローラーのように左右(上下も可)で領域のサイズを変えることができます。
例として先ほど作成したXAMLにGridSplitterコントロールを追加してTreeとContentのサイズをマウスで変更できるようにします。GridSplitterコントロールを追加したGridコントロール部分のXAMLを以下に示します。

<Grid ShowGridLines="True">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="150" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <!-- メニューやツールバー -->
    <Button Grid.Row="0" Grid.ColumnSpan="2" Content="Menu" />
    <Button Grid.Row="1" Grid.ColumnSpan="2" Content="Toolbar" />
    <!-- ステータスバー -->
    <Button Grid.Row="3" Grid.ColumnSpan="2" Content="StatusBar" />
    <!-- ツリーが表示される場所 最低限の幅確保のためMinWidthプロパティを指定 -->
    <Button Grid.Row="2" Content="Tree" />
    <!-- エクスプローラーの右側の領域 -->
    <!-- TreeとContentのサイズを変えるためのGridSplitterを配置 -->
    <GridSplitter 
        Grid.Row="2" Grid.Column="1" 
        HorizontalAlignment="Left" VerticalAlignment="Stretch" Width="5" />
    <!-- GridSplitterコントロールを置く余白を確保するためにMarginを設定 -->
    <Button Grid.Row="2" Grid.Column="1" Content="Content" Margin="5,0,0,0" />
</Grid>

上記の例では、Contentの左に幅5pxのGridSplitterコントロールを置いています。Gridコントロールで同じセルにコントロールを置くと重ねて表示するため、重なりを防ぐためにContentの左側に5pxのマージンを指定しています。このWindowを表示すると以下にようになります。

TreeとContentの間にあるGridSplitterコントロールをドラッグすることで以下のようにサイズ変更ができます。