views:

34

answers:

2

I am using a GridSplitter to resize a cell in a grid however its behaviour is not what I am expecting and I cannot find a solution. It is a grid of three rows, the first has a row definition set to Auto and contains some elements. The second row has some data in it and has a row definition of * to fill the remaining space. The last row is a status bar that needs to be resizable, and so has a grid splitter in it and a row definition height of Auto and MinHeight of 30.

The problem is when you drag the GridSplitter all the way to the top, it will make the cell overflow. I wish for it to STOP once it gets to the top. The desired behaviour can be achieved by removing the Height=Auto from the last row, but that makes the bottom cell expand to equal height with the middle row.

Here is a XAML Pad example.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" MinHeight="20" />
            <RowDefinition Height="Auto" MinHeight="30" />
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Text="Foo" />
        <TextBlock Grid.Row="1" Text="Bar" />
        <GridSplitter  Canvas.ZIndex="1"  VerticalAlignment="Top"  Grid.Row="2" Background="Cyan" Height="5" HorizontalAlignment="Stretch"  />
        <TextBlock VerticalAlignment="Bottom" Grid.Row="2" TextWrapping="Wrap">LOL<LineBreak/>LOL<LineBreak/>LOL</TextBlock>
    </Grid>
</Page>

When you drag to the top, you will notice the bottom text disappears.

I have tried various things, such as putting the grid splitter in its own cell, and Binding Height to another objects ActualHeight etc but none really work that well.

I know it isn't the most well explained question, but any ideas would be greatly appreciated.

Edit: I have made the GridSplitter with its own row as posted below, but as I mentioned earlier the problem still remains. I have the ResizeBehavior and ResizeDirection also set here.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" MinHeight="20" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" MinHeight="30"  />
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Text="Foo" />
        <TextBlock Grid.Row="1" Text="Bar" />
        <GridSplitter ResizeDirection="Rows" ResizeBehavior="PreviousAndNext" Grid.Row="2" Background="Cyan" Height="5" HorizontalAlignment="Stretch"  />
        <TextBlock VerticalAlignment="Bottom" Grid.Row="3" TextWrapping="Wrap">LOL<LineBreak/>LOL<LineBreak/>LOL</TextBlock>
    </Grid>
</Page>

An example of what does work is removing the last rows Height="Auto" and changing it to * like so

This however makes the last row equal in size to the row before it and not to the requested size of the cell.

+1  A: 

GridSplitter should lie at its own row or column. Experiment with GridSplitter.ResizeDirection and GridSplitter.ResizeBehavior properties.

Take a look at the following articles:

UPDATE

You may provide "star coefficients" to GridLength object. For example:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:sys="clr-namespace:System;assembly=mscorlib" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;   
    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="95*" MinHeight="20" /> <!--here we are using 95*-->
            <RowDefinition Height="Auto" />
            <RowDefinition Height="5*" MinHeight="30"/> <!--and here we are using 5*-->     
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Text="Foo" />
        <TextBlock Grid.Row="1" Text="Bar" />
        <GridSplitter ResizeDirection="Rows"  Grid.Row="2" Background="Cyan" Height="5" HorizontalAlignment="Stretch"  />
        <TextBlock VerticalAlignment="Bottom" Grid.Row="3" TextWrapping="Wrap">LOL<LineBreak/>LOL<LineBreak/>LOL</TextBlock>
    </Grid> 
</Page>

So we have the layout as you need without GridSplitter unclear behaviour.

Eugene Cheverda
Thank you for your prompt reply. I have read both articles you have posted and notice they say that it is fine for a grid splitter to occupy the same row as other elements, as long as it is visible (which it is). Unfortunatly even in it's own row it still has the same issue. I have updated the question with the XAML for the GridSplitter row. I attempted to use all of the options of ResizeDirection and ResizeBehavior, which i understand controls which grid elements it resizes, however the row height overflowing still occurs.
Seravy
See update please.
Eugene Cheverda
Yeah, As mentioned before that the * will not cause the height to be over extended. My work colleague and I spent some time nutting this one out. When the splitter is used against an Auto row definition it will change it to an absolute GridLength, which is where the problem lies. Because they are absolute there is no reason why the grid splitter cannot keep expanding the cell.
Seravy
Unfortunately your solution does not do what Auto does, as it is pushing the row to the minimum height (it allows 5% of the left over used there) and so it will only show the first two 'LOL's and not the last LOL. It is probably all that can be done simpily however so I am happy to mark you as the correct answer. I will be either implementing a sub GridSplitter to figure out the correct star percentages when used or adding a LayoutUpdated event handler and updating the MaxHeight. Thanks.
Seravy
A: 

Drat, beat me to it. I might as well post what I have. Your issue is with the third row definition. When you start scrolling up and the text disappears, the row's height keeps increasing. You could try setting the max height to some restriction, if Eugene's solution doesn't work.

WanderingThoughts