Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF listview/gridsplitter/scrollviewer resize problem

I have a problem with the gridsplitter pushing my listview out of view in this combination. Steps to reproduce:

  • Start program, drag the window size larger
  • Drag the red splitter all the way left to minimize the blue column
  • Widen both ListView columns until they are outside the viewport and a horizontal scroll appears
  • Drag the window size smaller again

For me, this slowly pushes the ListView outside the Window. Note the ScrollViewer is actually decreasing in size with the Window, but not at the same rate and slowly goes out of view. Once the scrollviewer starts slipping out of view the splitter cannot be used any more!

Oddly enough, if I don't minimize the left panel first I don't get this behavior!

What would be a fix for this?

<Window x:Class="LayoutTest3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="600" Width="800" MinHeight="600" MinWidth="800" >
    <Window.Resources>
        <XmlDataProvider XPath="/Celebrities/Celebrity" x:Key="celebs">
            <x:XData>
                <Celebrities xmlns="">
                    <Celebrity Name="Jimmy">
                        <LastName>Page</LastName>
                    </Celebrity>
                    <Celebrity Name="Johnny">
                        <LastName>Depp</LastName>
                    </Celebrity>
                    <Celebrity Name="Britney">
                        <LastName>Spears</LastName>
                    </Celebrity>
                </Celebrities>
            </x:XData>
        </XmlDataProvider>

        <DataTemplate x:Key="NameTemplate">
            <TextBlock Text="{Binding XPath=@Name}" />
        </DataTemplate>
    </Window.Resources>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" MinWidth="100" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" MinWidth="400" />
        </Grid.ColumnDefinitions>
        <Border Grid.Column="0" Background="Blue" />
        <GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Center" ResizeBehavior="PreviousAndNext" VerticalAlignment="Stretch" Background="Red" />
        <Border Grid.Column="2" Background="Green">
            <ListView ItemsSource="{Binding Source={StaticResource celebs}}">
                <ListView.View>
                    <GridView>
                        <GridView.Columns>
                            <GridViewColumn Header="Name" CellTemplate="{StaticResource NameTemplate}" Width="150" />
                            <GridViewColumn Header="LastName" DisplayMemberBinding="{Binding XPath=LastName}" />
                        </GridView.Columns>
                    </GridView>
                </ListView.View>
            </ListView>
        </Border>
    </Grid>
</Window>
like image 892
DaveO Avatar asked Jun 19 '11 00:06

DaveO


2 Answers

There is a known problem with GridSplitter and Column with MinWidth, GridSplitter still resized Grid ignoring Column's MinWidth. Result of that is the growing column's child gets more size the actually available. But Grid layouts children considering MinWidth and thus your Shrinking column remains at MinWidth but Growing Column's child goes out of view of the size that GridSplitter has gone beyond MinWidth of shrinking column.

I am going to find out how did I solve this in my one of the project and I will post code. Meanwhile you can try following options.

  1. Remove MinWidth from ColumnDefinition
  2. Add MinWidth to Child

Knowing in advance that your Grid's Minimum Size should be 500 + Size of Splitter, you can set MinWidth of entire Grid.

like image 56
Akash Kava Avatar answered Sep 28 '22 17:09

Akash Kava


Here's how I did it:

<Grid Name="container" SizeChanged="container_SizeChanged">
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition Name="rightPanel" Width="*" MinWidth="100"/>
    </Grid.ColumnDefinitions>
    <TextBlock Grid.Column="0" Background="Red" Foreground="White">Test</TextBlock>
    <GridSplitter Grid.Column="0" VerticalAlignment="Stretch" HorizontalAlignment="Right" Width="2" Height="Auto" ResizeDirection="Columns"/>
    <Border Grid.Column="1" Background="Green" Margin="0 0 0 0">
        <ListView ItemsSource="{Binding Source={StaticResource celebs}}">
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Header="Name" CellTemplate="{StaticResource NameTemplate}" Width="150" />
                        <GridViewColumn Header="LastName" DisplayMemberBinding="{Binding XPath=LastName}" />
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>
    </Border>
</Grid>

and code behind (yuck!):

private void container_SizeChanged(object sender, SizeChangedEventArgs e)
{
    rightPanel.MaxWidth = container.ActualWidth - 150;
}

Basically you take out the min width and perform a similar calculation to set MaxWidth on the other panel.

like image 30
DaveO Avatar answered Sep 28 '22 17:09

DaveO