#462 – Drawing a Better Looking GridSplitter

By default, a GridSplitter control is composed only of a Border element.  You can set the border’s thickness, color and background.

We can make the GridSplitter look a little nicer by drawing a couple horizontal lines on its surface.

We do this by overriding the default Style for the GridSplitter.

	<Window.Resources>
		<Style x:Key="GridSplitterPreviewStyle" >
			<Setter Property="Control.Template">
				<Setter.Value>
					<ControlTemplate>
						<Rectangle Fill="#80000000"/>
					</ControlTemplate>
				</Setter.Value>
			</Setter>
		</Style>
		<Style x:Key="GridSplitterStyle1" TargetType="{x:Type GridSplitter}">
			<Setter Property="Background"
                    Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
			<Setter Property="PreviewStyle" Value="{StaticResource GridSplitterPreviewStyle}"/>
			<Setter Property="Template">
				<Setter.Value>
					<ControlTemplate TargetType="{x:Type GridSplitter}">
						<Border BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                Background="{TemplateBinding Background}"
                                CornerRadius="5">
                            <Canvas RenderOptions.EdgeMode="Aliased" UseLayoutRounding="True"
                                    Height="6" VerticalAlignment="Center"
                                    Width="50" HorizontalAlignment="Center">
                                <Line X1="0" X2="50" Y1="0" Y2="0"
                                      Stroke="White" StrokeThickness="1"/>
                                <Line X1="0" X2="50" Y1="1" Y2="1"
                                      Stroke="#A0A0A0" StrokeThickness="1"/>
                                <Line X1="0" X2="50" Y1="4" Y2="4"
                                      Stroke="White" StrokeThickness="1"/>
                                <Line X1="0" X2="50" Y1="5" Y2="5"
                                      Stroke="#A0A0A0" StrokeThickness="1"/>
                            </Canvas>
						</Border>
					</ControlTemplate>
				</Setter.Value>
			</Setter>
		</Style>
	</Window.Resources>

We also specify a gradient fill for the Background of the GridSplitter.

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Label Content="Row 0 Col 0" Background="Azure" Grid.Row="0" Grid.Column="0" />
        <Label Content="Row 0 Col 1" Background="Lavender" Grid.Row="0" Grid.Column="1" />
        <Label Content="Row 2 Col 0" Background="Moccasin" Grid.Row="2" Grid.Column="0" />
        <Label Content="Row 2 Col 1" Background="Honeydew" Grid.Row="2" Grid.Column="1" />

        <GridSplitter Grid.Row ="1" Grid.ColumnSpan="2" Height="16"
                      VerticalAlignment="Center" HorizontalAlignment="Stretch"
                      BorderBrush="White" BorderThickness="1"
					  Style="{DynamicResource GridSplitterStyle1}">
            <GridSplitter.Background>
                <LinearGradientBrush EndPoint="0.5,0" StartPoint="0.5,1">
                    <GradientStop Color="#A0A0A0" Offset="0"/>
                    <GradientStop Color="#E5E5E5" Offset="0.15"/>
                    <GradientStop Color="#ECECEC" Offset="0.8"/>
                    <GradientStop Color="#E5E5E5" Offset="1"/>
                </LinearGradientBrush>
            </GridSplitter.Background>
        </GridSplitter>
    </Grid>
Advertisements

#461 – Making a GridSplitter Look Three-Dimensional

You can make a GridSplitter element look like a more traditional three-dimensional element by using a Border and a gradient fill.  This will make it more obvious to the user that it is something that they can grab with the mouse.

In the XAML snippet below, the GridSplitter has a dark grey border and a gradient fill that goes from white to gray.

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Label Content="Row 0 Col 0" Background="Azure" Grid.Row="0" Grid.Column="0" />
        <Label Content="Row 0 Col 1" Background="Lavender" Grid.Row="0" Grid.Column="1" />
        <Label Content="Row 2 Col 0" Background="Moccasin" Grid.Row="2" Grid.Column="0" />
        <Label Content="Row 2 Col 1" Background="Honeydew" Grid.Row="2" Grid.Column="1" />

        <GridSplitter Grid.Row="1" Grid.ColumnSpan="2" Height="6" BorderThickness="1" BorderBrush="DarkSlateGray"
                      VerticalAlignment="Center" HorizontalAlignment="Stretch">
            <GridSplitter.Background>
                <LinearGradientBrush EndPoint="0.5,0" StartPoint="0.5,1">
                    <GradientStop Color="#FF808385" Offset="0"/>
                    <GradientStop Color="#FFECF1F7" Offset="1"/>
                </LinearGradientBrush>
            </GridSplitter.Background>
        </GridSplitter>

    </Grid>

#460 – A GridSplitter Can Share a Cell with Another Control

When using a GridSplitter in a Grid, you often define the Grid so that the GridSplitter is located within its own row (for a horizontal GridSplitter) or column (for a vertical GridSplitter).  However, you can also place a GridSplitter in a cell with another control.

In the example below, the horizonal GridSplitter is placed in the first row (of two rows), with two Label controls.

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Label Content="Row 0 Col 0" Background="Azure" Grid.Row="0" Grid.Column="0" />
        <Label Content="Row 0 Col 1" Background="Lavender" Grid.Row="0" Grid.Column="1" />
        <Label Content="Row 1 Col 0" Background="Moccasin" Grid.Row="1" Grid.Column="0" />
        <Label Content="Row 1 Col 1" Background="Honeydew" Grid.Row="1" Grid.Column="1" />

        <GridSplitter Grid.Row="0" Grid.ColumnSpan="2" Height="3" Background="Blue"
                      VerticalAlignment="Bottom" HorizontalAlignment="Stretch" />

    </Grid>



Note that we add the GridSplitter as the last element in the Grid, to make sure that it shows up on top of the Label that it shares a cell with.

#459 – Using Two (or More) GridSplitter Elements in the Same Grid

You can include more than one GridSplitter in a Grid by setting up the properties for each GridSplitter properly.

In the example below, we have both a vertical and a horizontal GridSplitter.

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Label Content="Row 0 Col 0" Background="Azure" Grid.Row="0" Grid.Column="0" />
        <Label Content="Row 0 Col 2" Background="Lavender" Grid.Row="0" Grid.Column="2" />
        <Label Content="Row 2 Col 0" Background="Moccasin" Grid.Row="2" Grid.Column="0" />
        <Label Content="Row 2 Col 2" Background="Honeydew" Grid.Row="2" Grid.Column="2" />

        <GridSplitter Grid.Row="1" Grid.ColumnSpan="3" Height="3" Background="Blue"
                      VerticalAlignment="Center" HorizontalAlignment="Stretch" />

        <GridSplitter Grid.Column="1" Grid.RowSpan="3" Width="3" Background="Green"
                      VerticalAlignment="Stretch" HorizontalAlignment="Center" />
    </Grid>



#458 – Properties to Set When Using a Horizontal or Vertical GridSplitter

To get the desired behavior when using a GridSplitter element, you need to set HorizontalAlignment and VerticalAlignment properties as shown below.

For a vertical splitter:

  • Put GridSplitter in its own column, setting column’s width to Auto
  • Set Grid.RowSpan to span all rows of the Grid
  • No need to set Grid.Row property  (defaults to 0)
  • Set Width of GridSplitter to be desired thickness
  • Set HorizontalAlignment to Center
  • Set VerticalAlignment to Stretch

For a horizontal splitter:

  • Put GridSplitter in its own row, setting row’s height to Auto
  • Set Grid.ColumnSpan to span all columns of the Grid
  • No need to set Grid.Column property  (defaults to 0)
  • Set Height of GridSplitter to be desired thickness
  • Set HorizontalAlignment to Stretch
  • Set VerticalAlignment to Center

#457 – Use a GridSplitter to Let a User Change Row or Column Size in a Grid

Rows and columns in a Grid don’t normally change their size at runtime, unless the content of the Grid changes.  But you can allow a user to change the size of rows or columns by using a GridSplitter element.

You typically place a GridSplitter in its own row or column.  In the example below, the middle column contains a blue GridSplitter.  At runtime, a user can click and drag on this element to change the relative sizes of columns 0 and 2.

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Label Content="Row 0 Col 0" Background="Azure" Grid.Row="0" Grid.Column="0" />
        <Label Content="Row 0 Col 2" Background="Lavender" Grid.Row="0" Grid.Column="2" />
        <Label Content="Row 1 Col 0" Background="Moccasin" Grid.Row="1" Grid.Column="0" />
        <Label Content="Row 1 Col 2" Background="Honeydew" Grid.Row="1" Grid.Column="2" />

        <GridSplitter Grid.Column="1" Grid.RowSpan="2" Width="3" Background="Blue"
                      VerticalAlignment="Stretch" HorizontalAlignment="Center" />
    </Grid>

Layout at startup:

User clicks and drags to the left:

Or drags to the right:

#456 – An Element in a Grid Can Span Multiple Rows or Columns

You can have child elements in a grid span multiple rows and/or multiple columns using the the Grid.RowSpan and Grid.ColumnSpan properties.

In the example below, the Image spans two rows and two columns and the TextBlock is located in a single row, but spans two columns.

    <Grid DataContext="{Binding GoodMovie}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Image Source="{Binding Image}" Grid.RowSpan="2" Grid.ColumnSpan="2"
               Width="142" Height="216" Margin="5"
               HorizontalAlignment="Center" VerticalAlignment="Center"/>

        <Label Content="{Binding Title}" FontWeight="Bold" Grid.Row="0" Grid.Column="2"/>
        <Label Content="{Binding Year}" Grid.Row="0" Grid.Column="3"/>

        <TextBlock Text="{Binding Summary}" Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="2"
                   TextWrapping="Wrap" Margin="8"/>

        <Label Content="Director:" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Right"/>
        <Label Content="{Binding Director}" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Left"/>

        <Label Content="Actor:" Grid.Row="3" Grid.Column="0" HorizontalAlignment="Right"/>
        <Label Content="{Binding ActorLead}" Grid.Row="3" Grid.Column="1" HorizontalAlignment="Left"/>

        <Label Content="Actress:" Grid.Row="4" Grid.Column="0" HorizontalAlignment="Right"/>
        <Label Content="{Binding ActressLead}" Grid.Row="4" Grid.Column="1" HorizontalAlignment="Left"/>
    </Grid>


You can see things a little better by turning on the grid lines.