Search code examples
c#wpfgridsplitter

WPF GridSplitter: How to move programmatically?


I have two problems with the code below.

Problem 1) In the function MaximizePreview() I want to store the old width of the left column (lastListViewWidth = widthListView) and when calling MaximizeListView(), I want to restore the previous width of the left (and right) column. Therefore I write back the width I store with lastListViewWidth. The Problem is, that after restoring the width, the splitter does not exactly move to the old position. Calling both functions several times, the GridSplitter move more and more to the left and ListViewWith gets smaller with every call cycle. What do I have to do to exactly store and restore the GridSplitter's position and the width of the columns left and right from it?

Problem 2) You can see, that I added MinWidht="0.1", instead of MinWidth="0". The reason for that is, if a move the splitter absolutely to the right and than move the splitter to the left programmatically, the right column stays collapsed. If I move the splitter to the left by dragging it, the right column grows again when I move the splitter left. When setting MinWidth to 0.1 then moving the splitter left from the rightmost position programmatically works fine and the right column grows as when moving the splitter by hand. What is happening here?

I have defined the Grid as follows:

<Grid.ColumnDefinitions>
  <ColumnDefinition Width="*" Name="columnListView" />
  <ColumnDefinition Width="38" Name="columnSplitter"/>
  <ColumnDefinition Width="*" Name="columnPreView" MinWidth="0.1" />
</Grid.ColumnDefinitions>

I have to buttons/functions that move the GridSplitter programatically:

This function minimizes the left column.

private void MaximizePreview() {
  double widthPreview = columnPreView.ActualWidth;
  double widthSplitter = columnSplitter.ActualWidth;
  double widthListView = columnListView.ActualWidth;
  if(widthListView > 0) {
    lastListViewWidth = widthListView;
    columnListView.Width = new GridLength(0, GridUnitType.Star);
    columnPreView.Width = new GridLength(ActualWidth - widthSplitter, GridUnitType.Star);
  };
}

And with this function a want to restore the previous position.

private void MaximizeListView() {
  double widthPreview = columnPreView.ActualWidth;
  double widthSplitter = columnSplitter.ActualWidth;
  double widthListView = columnListView.ActualWidth;
  if(widthListView <= lastListViewWidth) {
    lastListViewWidth = Math.Min(lastListViewWidth, ActualWidth * .85);
    lastListViewWidth = Math.Max(lastListViewWidth, ActualWidth * .15);
    columnPreView.Width = new GridLength(ActualWidth - lastListViewWidth - widthSplitter, GridUnitType.Star);
    columnListView.Width = new GridLength(lastListViewWidth, GridUnitType.Star);
  };
}

Solution

  • You should set the parent container's grid/row definitions programatically:

    Here's an example:

            private void GridRowSplitter_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            GridContent.RowDefinitions[0].Height = new GridLength(200, GridUnitType.Star);
            GridContent.RowDefinitions[1].Height = new GridLength(3, GridUnitType.Pixel);
            GridContent.RowDefinitions[2].Height = new GridLength(0,GridUnitType.Star);
        }