The GridSplitters in my WPF app are behaving strangely. My application has a 3-panel layout, implemented as a grid with 5 columns, where 0/2/4 have content and 1/3 have GridSplitters. The middle panel is a Grid with a ListView.
Everything works fine until the ListView gets focus, at which point the splitters mostly stop moving. You can drag them a pixel or two, then they freeze. The app sees an initial motion event, but nothing further. You can repeat this a few times to move the splitter multiple pixels, but if you try to move another splitter the previous one jumps back where it was. There are two more splitters in the side panels that continue to work normally.
Reloading the project causes the ListView to lose focus, and the splitters start working again.
That's probably hard to visualize, so a made a short video.
The XAML is pretty straightforward. The only quirk is that the center panel is defined twice, with mutually-exclusive visibility.
<Grid Name="triptychGrid" DockPanel.Dock="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="100"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" MinWidth="150"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" MinWidth="100"/>
</Grid.ColumnDefinitions>
<GridSplitter Grid.Column="1" Width="4" HorizontalAlignment="Left"/>
<GridSplitter Grid.Column="3" Width="4" HorizontalAlignment="Center"/>
<Grid Grid.Column="0" Name="leftPanel"> ... </Grid>
<Grid Grid.Column="2" Name="launchPanel" Visibility="{Binding Path=LaunchPanelVisibility}"> ... </Grid>
<Grid Grid.Column="2" Name="codeListGrid" Visibility="{Binding Path=CodeListVisibility}"> ... </Grid>
<Grid Grid.Column="4" Name="rightPanel"> ... </Grid>
</Grid>
There are event listeners on the panel widths so they get remembered between runs. I restore the widths of the panels when the application first starts, but don't touch them after that.
Everything works just fine until the ListView gets focus. It would be less weird if it froze up entirely. Moving a couple of pixels at a time and then jumping back when other controls are touched seems weird.
I have reproduced this on a desktop running the latest Win10 (.NET reports 10.0.18362) and a virtual machine running the latest Win7. The project is open source.
The problem occurs because you are handling the
ItemContainerGenerator.StatusChangedevent. When thelistViewgets resized because of the grid splitter, the even get generated for each pixel or so which mess up the smoothness of the operation.A quick and lazy fix to that is to cancel that handler when the sliding is in progress, you can achieve that simply by using a
boolean, set it totrueorfalseby handling theDragStartedandDragOverof theGridSplitters:The handlers look something like that:
Then update your
ItemContainerGenerator_StatusChangedto consider that boolean:There might be something more sophisticated to do with the
ItemContainerGenerator, but that requires more diggings.