[WPF] GridSplitter 画面を分割して境界線をドラッグしてリサイズする

更新: 2020-09-19 (土) 投稿: 2018-05-25 (金)

Gridの中にGridSplitterを配置して、隣り合うコントロールの幅をリサイズします。

環境

  • Windows 10 Pro 64bit 1909
  • Visual Studio 2019 16.7.3
  • .NET Core 3.1

結論

App.xaml

<Application x:Class="GridSplitterStudy.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <!--  GridSplitter  -->
        <Style x:Key="HorizontalGridSplitter" TargetType="{x:Type GridSplitter}">
            <Setter Property="Height" Value="5" />
            <Setter Property="HorizontalAlignment" Value="Stretch" />
        </Style>
        <Style x:Key="VerticalGridSplitter" TargetType="{x:Type GridSplitter}">
            <Setter Property="HorizontalAlignment" Value="Stretch" />
            <Setter Property="Width" Value="5" />
        </Style>
    </Application.Resources>
</Application>

MainWindow.xaml

<Window x:Class="GridSplitterStudy.MainWindow"
        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"
        mc:Ignorable="d"
        Title="MainWindow"
        Width="500"
        Height="300">
    <UniformGrid Columns="2">
        <!--  HorizontalGridSplitter (水平分割: 青と赤のエリアを上下に分割します)  -->
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" MinHeight="50" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" MinHeight="50" />
            </Grid.RowDefinitions>

            <TextBlock Grid.Row="0" Background="Blue" />
            <GridSplitter Grid.Row="1" Style="{StaticResource HorizontalGridSplitter}" />
            <TextBlock Grid.Row="2" Background="Red" />
        </Grid>

        <!--  VerticalGridSplitter (垂直分割: 緑と紫のエリアを左右に分割します)  -->
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" MinWidth="50" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" MinWidth="50" />
            </Grid.ColumnDefinitions>

            <TextBlock Grid.Column="0" Background="Green" />
            <GridSplitter Grid.Column="1" Style="{StaticResource VerticalGridSplitter}" />
            <TextBlock Grid.Column="2" Background="Purple" />
        </Grid>
    </UniformGrid>
</Window>

説明

Styleを定義する場合

上記のようにx:Key="HorizontalGridSplitter", x:Key="VerticalGridSplitter" というStykeを定義して、StaticResourceで使い回すと良いと思います。
ただし、既に規定の GridSplitter の Style が定義されている場合は、BaseOn を指定してください。

例えば、MaterialDesignInXamlToolkit を使用している場合は、以下のように BasedOn="{StaticResource MaterialDesignGridSplitter}" を指定します。

<!--  GridSplitter  -->
<Style x:Key="HorizontalGridSplitter"
        BasedOn="{StaticResource MaterialDesignGridSplitter}"
        TargetType="{x:Type GridSplitter}">
    <Setter Property="Height" Value="5" />
    <Setter Property="HorizontalAlignment" Value="Stretch" />
</Style>
<Style x:Key="VerticalGridSplitter"
        BasedOn="{StaticResource MaterialDesignGridSplitter}"
        TargetType="{x:Type GridSplitter}">
    <Setter Property="HorizontalAlignment" Value="Stretch" />
    <Setter Property="Width" Value="5" />
</Style>

Styleを定義しない場合

StaticResourceを使用せずに、以下のように直接プロパティ(Height, Width, HorizontalAlignment)を指定しても良いです。

<!--  HorizontalGridSplitter (水平分割: 上下に分割します)  -->
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" MinHeight="50" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" MinHeight="50" />
    </Grid.RowDefinitions>

    <TextBlock Grid.Row="0" />
    <GridSplitter Grid.Row="1" Height="5" HorizontalAlignment="Stretch" />
    <TextBlock Grid.Row="2" />
</Grid>

<!--  VerticalGridSplitter (垂直分割: 左右に分割します)  -->
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" MinWidth="50" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" MinWidth="50" />
    </Grid.ColumnDefinitions>

    <TextBlock Grid.Column="0" />
    <GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Stretch" />
    <TextBlock Grid.Column="2" />
</Grid>

感謝

更新: 2020-09-19 (土) 投稿: 2018-05-25 (金)