wpfgridsplitterwpf-grid

Multiple Auto column definitions causing weird GridSplitter behavior


I have the following XAML:

<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <TextBlock Text="0,0" Grid.Column="0" Background="Yellow" />
        <TextBlock Text="1,0" Grid.Column="1" Background="SkyBlue" />
        <GridSplitter Width="20" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Stretch" ShowsPreview="True" />
        <TextBlock Text="3,0" Grid.Column="3" Grid.Row="0" />
    </Grid>
</Window>

When there is only one ColumnDefinition with a Width of Auto, the GridSplitter works properly. However, once there are multiple columns with a Width of Auto, the first Auto column also gets resized when the GridSplitter is moved (can be seen in cell 1,0).

Before resize:

enter image description here

After resize:

enter image description here

How can I prevent the GridSplitter from resizing the second column?


Solution

  • If you cannot modify the existing columns, perhaps you could try to achieve this behavior programmatically...

    Name the columns:

    <Grid.ColumnDefinitions>
        <ColumnDefinition Name="firstColumn" Width="*" />
        <ColumnDefinition Name="secondColumn" Width="Auto" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    

    Add events to grid spliiter:

    <GridSplitter Name="gridSplitter" DragStarted="gridSplitter_DragStarted" DragCompleted="gridSplitter_DragCompleted" />
    

    Then just save the column widths before splitter drag and apply the change to the first column width, instead of second:

    public partial class MainWindow : Window
    {
        private double savedFirstColumnWidth;
        private double savedSecondColumnWidth;
    
        private void gridSplitter_DragStarted(object sender, DragStartedEventArgs e)
        {
            // Save the initial column width values
            savedFirstColumnWidth = firstColumn.ActualWidth;
            savedSecondColumnWidth = secondColumn.ActualWidth;
        }
    
        private void gridSplitter_DragCompleted(object sender, DragCompletedEventArgs e)
        {           
            double dragChange = e.HorizontalChange;
    
            // Change the width of the first column instead of second
            firstColumn.Width = new GridLength(savedFirstColumnWidth + dragChange);
            // Set the with of the second column to the value saved before the drag
            secondColumn.Width = new GridLength(savedSecondColumnWidth);
        }
    }