Thursday, March 20, 2014

A couple of simple improvements for gridsplitter

My application has a single grid splitter which I want to make some changes to, but I don't want to go to the trouble of re-templating it. I want to add a small image to the middle of the grid splitter to give the user a visual cue that clicking there might do something useful. I also want the grid splitter to respond to a single mouse-click but that isn't supported.

Let's start with the basic GridSplitter. It's defined like this...

<Grid name="BodyGrid">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Name="NavigationColumn" Width="*"/>
        <ColumnDefinition Name="SplitterColumn" Width="8"/>
        <ColumnDefinition Name="ClientColumn" Width="*"/>
    </Grid.ColumnDefinitions>
    <UserControl Name="WorkflowTreeUserControl" Grid.Column="0"/>
    <GridSplitter Name="GridSplitter" Grid.Column="1" HorizontalAlignment="Stretch">
    <UserControl Name="ChildUserControl" Grid.Column="2"/>
</Grid>

This gives us an 8px wide default grid splitter with a user control on either side. Let's add an image to the middle of the splitter to give the users their visual cue. I used MSPaint to create an 8x30 pixel image that looks like this...
ToggleWorkflow.png

And I used an ImageBrush (really handy) to set this as the background for the grid splitter. So now the grid splitter XAML looks like this.

<GridSplitter Name="GridSplitter" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Stretch">
    <GridSplitter.Style>
        <Style TargetType="{x:Type GridSplitter}">
            <Setter Property="Background">
                <Setter.Value>
                    <ImageBrush Stretch="None" ImageSource="/Images/ToggleWorkflow.png"/>
                </Setter.Value>
            </Setter>
        </Style>
    </GridSplitter.Style>
</GridSplitter>

But now the grid splitter has no background color. How can I have a background color AND a background image? Well one way (not necessarily the best way) is to add a rectangle to the grid column so the grid splitter sits on top of it. Add this rectangle XAML above the grid splitter XAML.

<Rectangle Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Fill="LightGray"/>

So now the grid splitter looks the way we want. We want to collapse the left user control when the user clicks on the grid splitter but wait, the grid splitter does not support a Click event. There's a MouseDoubleClick event but that's not what our users want (some of them have trouble counting to two!). We could retemplate the control to use a button, remove all the button chrome etc. But if we keep doing that our deadline will pass before we've written any functionality. I Googled the problem and found several pages that say "Use the MouseDown event". The MouseDown event does not work here because it bubbles and gets handled before it reaches us. Use the PreviewMouseDown event which tunnels and we do get to see it.

Here's how the new grid splitter looks. If I had a lot of these, I would have done this differently.

No comments:

Post a Comment