How do I keep the WPF GridSplitter from changing the size of my Grid?

26,248

Solution 1

If your Window is resized so its Width is less than the sum of your columns' MinWidths, you'll see the columns cut off, but otherwise I can't reproduce your problem:

<Window 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>
        <Grid.ColumnDefinitions>
            <ColumnDefinition MinWidth="150" Width="*"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition MinWidth="400" Width="*"/>
        </Grid.ColumnDefinitions>
        <GridSplitter
            Width="2"
            Grid.Column="1"
            HorizontalAlignment="Center"
            Margin="0,5,0,5"
            Panel.ZIndex="1"
            VerticalAlignment="Stretch"
            ResizeBehavior="BasedOnAlignment"
            ResizeDirection="Columns"/>
        <Grid Grid.Column="0">
            <Border Background="Red" Margin="5"/>
        </Grid>
        <Grid Grid.Column="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition MinWidth="150" Width="*"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition MinWidth="200" Width="*"/>
            </Grid.ColumnDefinitions>
            <GridSplitter
                Width="2"
                Grid.Column="1"
                HorizontalAlignment="Center"
                Margin="0,5,0,5"
                Panel.ZIndex="1"
                VerticalAlignment="Stretch"
                ResizeBehavior="PreviousAndNext"
                ResizeDirection="Columns"/>
            <Grid Grid.Column="0">
                <Border Background="Green" Margin="5"/>
            </Grid>
            <Grid Grid.Column="2">
                <Border Background="Blue" Margin="5"/>
            </Grid>
        </Grid>
    </Grid>
</Window>

Expanding the red column, it will only expand until the right column reaches its MinWidth of 400, it won't boot it off the page.

It's possible you're setting other properties of the Window or the outermost Grid that would cause this behavior...

Solution 2

Try changing your Width's to star sizes. This will cause the splitter to only resize the columns between which it sits, so not sure if this is your desired behavior. However, with star sizes, the content will not grow beyond the bounds of the window.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*" MinWidth="100" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" MinWidth="50" />
        <ColumnDefinition Width="2*" MinWidth="100" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="3*" MinWidth="150" />
    </Grid.ColumnDefinitions>
    <GridSplitter 
        ResizeDirection="Columns"
        Grid.Column="1"
        Grid.RowSpan="8"
        HorizontalAlignment="Center"
        VerticalAlignment="Stretch"
        Width="2"
        Margin="0,5,0,5"
        Panel.ZIndex="1"/>
    ...
</Grid>

Solution 3

It works for me without any additional code when there are no Columns with Auto Width between the splitters, i.e.:

<Grid >
<Grid.ColumnDefinitions>
    <ColumnDefinition Width="20*" MinWidth="50" MaxWidth="500" />
    <ColumnDefinition Width="Auto"/> <!-- Remove such columns /-->
    <ColumnDefinition Width="100*" MinWidth="850"/>
    <ColumnDefinition Width="30*" MinWidth="50" MaxWidth="800" />
</Grid.ColumnDefinitions>
...
<GridSplitter HorizontalAlignment="Right" Width="3"/>
...
<GridSplitter Grid.Column="3" HorizontalAlignment="Left" Width="3" />
<!-- Assign Grid.Column to 2 if you remove the auto width column /-->
...
</Grid>

Otherwise the grid will be resizable.

Solution 4

Capturing the DragDelta event is another way of doing it:

    private void VerticalGridSplitter_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
    {
        if (GridName.ColumnDefinitions[2].Width.Value < 400)
        {
            GridName.ColumnDefinitions[2].Width = new GridLength(400);
        }
    }

But using MinWidth on a * ColumnDefinition should work just fine. Note that the ColumnDefinition with the MinWidth needs to be at the top level. It doesnt work if it's nested in some grid inside a column.

Solution 5

I had this problem too, with a normal Grid with no special controls, and * size on both columns/rows.

The problem turned out to be that I programmatically set the width an height of columns/rows in the grid after loading the Window, because I save the splitter position to restore it on the next program run.

I changed it to calculating a * size to solve the problem.

Share:
26,248
Zack Peterson
Author by

Zack Peterson

Specializes in the design and creation of web and desktop applications. Contributes in all aspects of the software development process such as: requirements analysis and product definition; prototyping; choosing architecture and framework; interface design; database design; installation and integration; documentation and training; gathering feedback; and maintenance.

Updated on August 06, 2020

Comments

  • Zack Peterson
    Zack Peterson almost 4 years

    WPF GridSplitter makes my Grid wider than my Window!

    I've got a WPF Grid with a GridSplitter. If I resize my columns, then I can make my grid wider than my window and non-viewable.

    It starts like this:

    WPF Grid http://img201.imageshack.us/img201/9505/onehg6.jpg

    But after widening the left column, I can no longer see the right column (green):

    WPF GridSplitter http://img201.imageshack.us/img201/1804/twomy6.jpg

    What am I doing wrong? How do I keep the GridSplitter from changing the size of my Grid?


    Update:

    I'm still struggling with this. I've now tried nesting grids within grids. That didn't help. Here's my XAML ColumnDefinitions, RowDefinitions, and GridSplitters...

    <Window ... >
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" MinWidth="150" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" MinWidth="400" />
            </Grid.ColumnDefinitions>
            <GridSplitter 
                ResizeDirection="Columns"
                ResizeBehavior="BasedOnAlignment"
                Grid.Column="1"
                HorizontalAlignment="Center"
                VerticalAlignment="Stretch"
                Width="2"
                Margin="0,5,0,5"
                Panel.ZIndex="1"/>
            <Grid Grid.Column="0">
                ...
            </Grid>
            <Grid Grid.Column="2">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" MinWidth="150" />
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*" MinWidth="200" />
                </Grid.ColumnDefinitions>
                <GridSplitter 
                    ResizeDirection="Columns"
                    ResizeBehavior="PreviousAndNext"
                    Grid.Column="1"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Stretch"
                    Width="2"
                    Margin="0,5,0,5"
                    Panel.ZIndex="1"/>
                <Grid Grid.Column="0">
                    ...
                </Grid>
                <Grid Grid.Column="2">
                    ...
                </Grid>
            </Grid>
        </Grid>
    </Window>
    

    Update:

    I think the problem is with the WebBrowser control. See new question:

    WPF GridSplitter Doesn't Work With WebBrowser Control?

  • Zack Peterson
    Zack Peterson over 15 years
    I got this to work by setting arbitrarily high MaxWidth values for the non-web browser columns as you demonstrated in this other question: stackoverflow.com/questions/375841/… <ColumnDefinition ... MaxWidth="10000"/>
  • Joshua Tacoma
    Joshua Tacoma about 14 years
    This solved the problem for me. The columns on either side of the splitter had to be star-sized.