Stop Gridsplitter stretching content beyond window

DaveO picture DaveO · May 4, 2011 · Viewed 10.4k times · Source

Given the below XAML, how do I have the gridsplitter respect the MinHeight given to the 3rd row and have the content remain inside my window?

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition MinHeight="40" />
    </Grid.RowDefinitions>
    <Expander Grid.Row="0" ExpandDirection="Down" VerticalAlignment="Top">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" MinHeight="40" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Border Grid.Row="0" MinHeight="100" Background="Black" />
            <GridSplitter Grid.Row="1" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Background="LightBlue" ResizeBehavior="PreviousAndCurrent" />
        </Grid>
    </Expander>
    <Expander Grid.Row="1" ExpandDirection="Down" VerticalAlignment="Top">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" MinHeight="40" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Border Grid.Row="0" MinHeight="100" Background="Black" />
            <GridSplitter Grid.Row="1" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Background="LightBlue" ResizeBehavior="PreviousAndCurrent" />
        </Grid>
    </Expander>
    <Border DockPanel.Dock="Bottom"  Grid.Row="2" Background="Lime" MinHeight="30" >
        <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=DockPanel},Path=ActualHeight,StringFormat={}{0:f0}}" />
    </Border>
</Grid>

Answer

Stefan Z Camilleri picture Stefan Z Camilleri · Jun 24, 2011

The way your code is, this cannot be done mate. This is due to how the GridSplitter works.

A few points

  • A GridSplitter will always work on directly adjacent rows/columns
  • In reality, your MinHeight IS being respected, but so is the GridSplitter's request to grow being respected, which results in the Grid growing larger than your Window
  • When sized to Auto, a row/column will always resize according to its content, not bigger, and not smaller
  • Therefore if a GridSplitter is sandwiched between two * sized rows/columns, then it would implicitly respect your MinHeight, since in reality, it would not be touching it

You have a few solutions

  1. Add another row in the 3rd position which is * sized, and have your border on row 3 with a RowSpan of 2 (so the 3rd row is the one being really resized, and your 4th row isn't touched. Though this will also have side-effects.
  2. Handle a mixture of DragEnter and PreviewMouseMove events on the GridSplitter, keeping track of focus, and cancelling (e.Handled = true) the event when a certain size is reached.

This is what I can think of mate, hope I've been of some help.