wpfxamlresizegridsplitterwpf-grid

Grow-Only GridSplitter


I have a pretty simple requirement that I can't seem to find a solution for. Take a look at my sample XAML code:

<Grid ShowGridLines="True" VerticalAlignment="Top" Margin="5">
    <Grid.RowDefinitions>
        <RowDefinition MinHeight="100"/>
        <RowDefinition MinHeight="100"/>
        <RowDefinition MinHeight="100"/>
    </Grid.RowDefinitions>

    <Grid.Resources>
        <Style TargetType="GridSplitter">
            <Setter Property="HorizontalAlignment" Value="Stretch"/>
            <Setter Property="VerticalAlignment" Value="Bottom"/>
            <Setter Property="Height" Value="1"/>
            <Setter Property="Background" Value="Black"/>
        </Style>
    </Grid.Resources>

    <GridSplitter/>
    <GridSplitter Grid.Row="1"/>
    <GridSplitter Grid.Row="2"/>
</Grid>

I have three rows that start out with a height of 100. I want the user to be able to drag the edge of any row to make it taller, so I put a GridSplitter in every row.

The problem is:

The GridSplitter control redistributes space between rows or columns in a Grid, without changing the dimensions of the Grid. For example, when a GridSplitter resizes two columns, the ActualWidth property of one column is increased while at the same time the ActualWidth property of the other column is decreased by the same amount.

The above XAML doesn't work, none of the rows change size when dragged, because the GridSplitter is trying to take height from another row and add it to the one being resized. Since none of the rows can get any smaller (MinHeight="100"), nothing happens.

But I don't want to take height from the other rows. I want to increase the size of one row independently, which will in turn change the overall height of the Grid. If I drag the middle row to be 50px taller, I want to have that row be 150px while the other two remain 100px, making the overall grid 350px.

Is there any setting on the GridSplitter I'm missing that will allow this? Or is there some other control I can use?


Solution

  • Is this what you're expecting?

    <StackPanel>
        <TextBlock Text="{Binding ActualHeight, 
                          ElementName=grid, 
                          StringFormat='Grid Actual Height: {0}'}" FontSize="30"/>
        <Grid x:Name="grid" Background="Aqua">
            <Grid.Resources>
                <Style TargetType="GridSplitter">
                    <Setter Property="HorizontalAlignment" Value="Stretch"/>
                    <Setter Property="VerticalAlignment" Value="Center"/>
                    <Setter Property="Height" Value="5"/>
                    <Setter Property="ShowsPreview" Value="False"/>
                    <Setter Property="Background" Value="Black"/>
                </Style>
                <Style TargetType="TextBlock">
                    <Setter Property="Text" 
                            Value="{Binding ActualHeight, 
                                    RelativeSource={RelativeSource AncestorType=StackPanel}, 
                                    StringFormat='Row Actual Height: {0}'}"/>
                    <Setter Property="FontSize" Value="30"/>
                    <Setter Property="HorizontalAlignment" Value="Center"/>
                </Style>
            </Grid.Resources>
            <Grid.RowDefinitions>
                <RowDefinition MinHeight="100" Height="100" />
                <RowDefinition Height="Auto" />
                <RowDefinition MinHeight="100" Height="100" />
                <RowDefinition Height="Auto" />
                <RowDefinition MinHeight="100" Height="100" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
    
            <StackPanel Grid.Row="0" Background="Tan">
                <TextBlock />
            </StackPanel>
            <GridSplitter Grid.Row="1"/>
            <StackPanel Grid.Row="2" Background="Brown">
                <TextBlock />
            </StackPanel>
            <GridSplitter Grid.Row="3"/>
            <StackPanel Grid.Row="4" Background="Bisque">
                <TextBlock />
            </StackPanel>
            <GridSplitter Grid.Row="5" ResizeBehavior="PreviousAndCurrent"/>
        </Grid>
    </StackPanel>
    

    The problem is with the way you're adding GridSplitter to your Grid control. You can get more detail on how this works at GridSplitter documentation. This also includes how to use ResizeBehavior; which i'd used to get it working for last row