Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set a GridSplitter to a specific initial position?

I'm using a GridSplitter in my WPF application and would like to set it to a specific initial position from code. I'm stuck with the behaviour of the GridSplitter when setting a specific value to the Height property of the associated RowDefinition.

Here's my example to illustrate the problem. I have added TextBlocks to display the acual values of the RowDefinition.Height properties.

XAML code:

  <Grid>
        <Grid.RowDefinitions>
            <RowDefinition x:Name="RowDef1" Height="*" MinHeight="20"/>
            <RowDefinition Height="Auto" />
            <RowDefinition x:Name="RowDef2" Height="*" MinHeight="20"/>
        </Grid.RowDefinitions>
        <DockPanel Grid.Row="0" LastChildFill="True" >
            <TextBlock FontSize="16" VerticalAlignment="Top"  Text="Upside Height: "/>
            <TextBlock x:Name="Tbl1" FontSize="16" Text="{Binding Height}"/>
        </DockPanel>
        <GridSplitter Grid.Row="1" Height="10" HorizontalAlignment="Stretch" ResizeBehavior="PreviousAndNext" Background="Black" />
        <DockPanel Grid.Row="2" LastChildFill="True" >
            <TextBlock FontSize="16" VerticalAlignment="Top" Text="Downside Height: "/>
            <TextBlock x:Name="Tbl2" FontSize="16" Text="{Binding Height}"/>
        </DockPanel>
    </Grid>

Codebehind:

namespace WpfGridSplitterTest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Tbl1.DataContext = this.RowDef1;
            Tbl2.DataContext = this.RowDef2;

        }
    }
}

The result works as expected. The GridSplitter resizes both parts of the window, obeys the MinHeight values and stops at the window borders. Resizing the window also works as designed :-)

Now I'm trying to set the initial position for the GridSplitter from codebehind like this:

    InitializeComponent();

    RowDef1.Height = new GridLength(50, GridUnitType.Pixel);
    Tbl1.DataContext = this.RowDef1;
    Tbl2.DataContext = this.RowDef2;

The result is weired:

  • The GridSplitter is initially set to 50 px from the top (that's fine)
  • It stops at the upper rows MinHeight of 20px (that's also fine)

but

  • it does no longer respect the lower boundary of the window nor the MinHeight value for the lower row
  • ActualHeight values for the lower row are not longer updated when the GridSplitter is moved

What am I missing here? Any hints are greatly appreciated!

I have read this post, yet the answer doesn't work in my case: How to set initial height of a GridSplitter 'pane'?

Changing Height="*" to Height="Auto" isn't fixing the problem either.

like image 818
kaha Avatar asked Jan 25 '16 19:01

kaha


1 Answers

The problem is that you're setting RowDef1's height to 50 PIXEL. What you want to do is set it to something STAR. But what value of star?

Since you want RowDef1 to end up at 50 pixels then you need to calculate the space available to RowDef1/2 in pixels. Assign 50 to RowDef1 in STAR units and the assign the remaining to RowDef2 in STAR units.

InitializeComponent();

Tbl1.DataContext = this.RowDef1;
Tbl2.DataContext = this.RowDef2;

this.Loaded += (s, e) =>
{
  var height = RowDef1.ActualHeight + RowDef2.ActualHeight; // 301 pixels
  RowDef1.Height = new GridLength(50, GridUnitType.Star); // 50*
  RowDef2.Height = new GridLength(height - 50, GridUnitType.Star); // 251*
};
like image 149
J.H. Avatar answered Oct 12 '22 12:10

J.H.