Skip to content

Stackoverflow exception in VirtualizingWrapPanel.MeasureOverride #65

@GwenhaelCoray

Description

@GwenhaelCoray

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

Metadata

Metadata

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions