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="Gr开发者_运维问答een">
<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>
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.
- Remove MinWidth from ColumnDefinition
- 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.
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.
Maybe this can help, you always have to use the same type of unit for width / height, or the splitter wont work correctly.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" MinWidth="150"/>
<ColumnDefinition Width="4*" MinWidth="150"/>
</Grid.ColumnDefinitions>
<ListView Grid.Column="0" BorderBrush="#FF005BFF" Margin="0,0,5,0">
<ListView.View>
<GridView>
<GridViewColumn />
</GridView>
</ListView.View>
</ListView>
<GridSplitter Grid.Column="1"
HorizontalAlignment="Left" VerticalAlignment="Stretch"
Background="Black"
ShowsPreview="true"
Width="2" />
<ListView Grid.Column="1" BorderBrush="#FFFF5100" Margin="5,0,0,0">
<ListView.View>
<GridView>
<GridViewColumn />
</GridView>
</ListView.View>
</ListView>
</Grid>
精彩评论