BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Windows Presentation Foundation
.NET 4.0+

WPF Layout Controls - GridSplitter

The seventh part of the Windows Presentation Foundation Fundamentals tutorial takes a look at another WPF layout control. This article explains the use of the GridSplitter, which allows Grid columns and rows to be resized using the mouse or keyboard.

The GridSplitter

Unlike the three layout controls that we've looked at earlier in this tutorial, the GridSplitter cannot be used in isolation. It is a layout control that must be placed within the cells of a Grid. Once configured, a standard GridSplitter appears as a bar between two columns or two rows. Users can drag the bar with the mouse, or adjust its position using the keyboard, resizing the two columns or rows between which the GridSplitter appears.

Using a single GridSplitter is good for separating two areas that may each hold more information that can be seen at once. Adding multiple GridSplitters to a single Grid allows for flexible, resizable layouts such as those seen in Visual Studio, Microsoft Outlook or Windows Explorer.

GridSplitter Example

Let's look at a simple two-cell grid with a GridSplitter to see how it works. In Visual Studio create a new WPF Application project and set the XAML of the main form to that shown below. Here we are creating a grid with one row and two columns. Each of the two grid cells has a different background colour and includes a TextBlock so that you can see how the splitter behaves.

The GridSplitter in this case is used to resize the two columns. This means that it should be a vertical splitter that is displayed between the two cells. For this reason, the GridSplitter appears in the first column and is horizontally aligned to the right. To make it clearly visible, it is five pixels wide and coloured red. The VerticalAlignment property of Stretch ensures that the GridSplitter extends to the full height of the cell.

<Window x:Class="GridSplitterDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="GridSplitter Demo"
        Height="200"
        Width="250">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0"
                   Text="This text is on the left."
                   TextWrapping="Wrap"
                   Background="LightYellow"/>
        <TextBlock Grid.Column="1"
                   Text="This text is on the right."
                   TextWrapping="Wrap"
                   Background="AliceBlue"/>
        
        <GridSplitter Width="5"
                      HorizontalAlignment="Right"
                      VerticalAlignment="Stretch"
                      Background="Red" />
    </Grid>
</Window>

Execute the project to see the results. The window should appear as shown below. You can see that the relative "star" sizes have been used to set the initial width of the two columns. However, you can change the sizes by dragging the red bar or by giving the GridSplitter the focus, then pressing the left and right arrow keys on the keyboard.

WPF GridSplitter

GridSplitters include a little intelligence to make them easier to configure in most cases. By examining the horizontal and vertical alignment properties the splitter knows that it must resize columns, rather than rows. In more complex scenarios it is possible that a GridSplitter will automatically choose to resize rows instead of columns or vice versa. You can override the automatically selected option by specifying a value for the ResizeDirection property. Valid values are "Rows" or "Columns".

If we wanted to be more specific in the above example we could achieve exactly the same results using the XAML shown below. This adds the appropriate ResizeDirection property.

<Window x:Class="GridSplitterDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="GridSplitter Demo"
        Height="200"
        Width="250">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0"
                   Text="This text is on the left."
                   TextWrapping="Wrap"
                   Background="LightYellow"/>
        <TextBlock Grid.Column="1"
                   Text="This text is on the right."
                   TextWrapping="Wrap"
                   Background="AliceBlue"/>
        
        <GridSplitter Width="5"
                      HorizontalAlignment="Right"
                      VerticalAlignment="Stretch"
                      Background="Red"
                      ResizeDirection="Columns" />
    </Grid>
</Window>

A vertical GridSplitter can appear at either side of a column. In the first example it was placed at the right of the first column. For similar results we could move it to the left side of the second column. To do so we need to modify the Grid.Column attached property and the HorizontalAlignment value.

Adjust the GridSplitter XAML element as follows:

<GridSplitter Width="5"
              Grid.Column="1"
              HorizontalAlignment="Left"
              VerticalAlignment="Stretch"
              Background="Red"/>

When you run the program you will see that the results are very similar to the first example. However, this example more clearly shows a problem that you may not have spotted before. As the GridSplitter appears within the same cell as the second TextBlock, it actually obscures the text slightly.

WPF GridSplitter

The overlapping of the two controls occurs because both are in the same grid cell. In this case the GridSplitter appears in front of the text because it is defined later in the XAML. If you were to switch the positions of the two XML elements you would see that the text appeared in front of, and overlapping, the GridSplitter. To fix this problem you could add a left margin to the TextBlock, pushing the text several pixels to the right. An alternative approach is to place the GridSplitter in its own column. However, I'll leave that for another article.

20 March 2013