-
-
Notifications
You must be signed in to change notification settings - Fork 46
Description
I have a case where I got a stackoverflow exception when scrolling down.
The exception is raised in VirtualizingWrapPanel.MeasureOverride call stack.
After investigation, I found out that in some cases, this line may be always true:
line 167: GetY(ScrollOffset) + GetHeight(ViewportSize) > GetHeight(Extent)
This leads to endlessly and recursively call MeasureOverride:
if (ItemsOwner is not IHierarchicalVirtualizationAndScrollInfo
&& GetY(ScrollOffset) != 0
&& GetY(ScrollOffset) + GetHeight(ViewportSize) > GetHeight(Extent))
{
ScrollOffset = CreatePoint(GetX(ScrollOffset), Math.Max(0, GetHeight(Extent) - GetHeight(ViewportSize)));
ScrollOwner?.InvalidateScrollInfo();
return MeasureOverride(availableSize); // repeat measure with correct ScrollOffset
}In my case, when crashing, I had:
- GetY(ScrollOffset) = 1 231.52314426031
- GetHeight(ViewportSize) = 639.4
- GetHeight(ViewPortSize) = 1 870.92314426031
With these numbers, the comparison should return false, but it doesn't on my machine, because of double imprecision.
I would suggest to replace:
GetY(ScrollOffset) + GetHeight(ViewportSize) > GetHeight(Extent)
by something like:
GetY(ScrollOffset) + GetHeight(ViewportSize) - GetHeight(Extent) > SOME_EPSILON
Below is the xaml I am using. Note that the crash happens with a specific set of data (I mean, depending on the set of data the VirtualizingItemsControl is populated with, it may crash or not):
(Setting AllowDifferentSizedItems to True or False doesn't change the bug.)
<controls1:VirtualizingItemsControl Grid.Row="1"
BorderThickness="0"
ItemsSource="{Binding PuImagesInCategory, Mode=TwoWay}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<controls1:VirtualizingWrapPanel SpacingMode="Uniform"
AllowDifferentSizedItems="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Button Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.SelectTileCommand}"
CommandParameter="{Binding Path='.'}"
MaxWidth="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=ActualWidth, Converter={StaticResource ResourceKey=LibraryChartsItemsMaxWidthConverter}}"
Background="White"
BorderBrush="Transparent"
ToolTipService.ShowOnDisabled="True"
ToolTipService.Placement="Left"
ToolTipService.HorizontalOffset="-100"
Margin="5,0,5,10">
<Button.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Grid.Row="0"
Source="{Binding ImagePath, Mode=OneWay}" />
<Grid Grid.Row="0"
Visibility="{Binding IsEnabled, Converter={StaticResource ResourceKey=BoolToVisibilityConverter}, ConverterParameter={x:Static converters:BoolToVisibilityConverter.INVERTED}}">
<Rectangle Fill="White"
Opacity="0.5" />
<DockPanel Grid.Row="0"
Margin="5"
HorizontalAlignment="Right"
VerticalAlignment="Top">
<Image Width="24"
Height="24"
Source="{Binding LockImage}">
<Image.ToolTip>
<TextBlock Text="{Binding Tooltip}" />
</Image.ToolTip>
</Image>
</DockPanel>
</Grid>
<Viewbox Grid.Row="1"
StretchDirection="DownOnly">
<TextBlock Text="{Binding PuImage.Description}"
HorizontalAlignment="Center" />
</Viewbox>
</Grid>
</Button.Content>
<Button.ToolTip>
<ToolTip Style="{StaticResource TooltipNoMargin}">
<Border Background="White">
<Grid>
<Image Width="960"
Height="540"
Source="{Binding ImagePath, Mode=OneWay}" />
<DockPanel Margin="5"
Visibility="{Binding IsEnabled, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter={x:Static converters:BoolToVisibilityConverter.INVERTED}}"
HorizontalAlignment="Right"
VerticalAlignment="Top">
<Image Width="24"
Height="24"
Source="{Binding LockImage}" />
</DockPanel>
</Grid>
</Border>
</ToolTip>
</Button.ToolTip>
</Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</controls1:VirtualizingItemsControl>
Version Info
Package Version: 2.0.10
.NET Version: .NET Framework 4.6.2
OS Version: Windows 11 Business Build 22631.4249