sbaeumlisberger / VirtualizingWrapPanel

Implementation of a comprehensive VirtualisingWrapPanel for WPF
MIT License
242 stars 33 forks source link

[2.0.0-preview3] NullReferenceException happens sometimes like when scrolling with the mouse #45

Closed c0debeef closed 1 year ago

c0debeef commented 1 year ago
xmlns:vwp="clr-namespace:WpfToolkit.Controls;assembly=VirtualizingWrapPanel"
...
    <material:DialogHost x:Name="xDialogHost" Identifier="NotificationsDialog"
                         DialogContent="{Binding DialogHostContent, Mode=OneWay}"
                         IsOpen="{Binding IsDialogHostOpen}"
                         OverlayBackground="{StaticResource PrimaryHueMidBrush}"
                         CloseOnClickAway="False">

        <ListView x:Name="xNotificationItems" 
                ItemsSource="{Binding Notifications, Mode=OneWay}" SelectedItem="{Binding SelectedNotification, Mode=TwoWay}"

                VirtualizingPanel.CacheLengthUnit="Item"
                VirtualizingPanel.CacheLength="64"
                VirtualizingPanel.ScrollUnit="Item"
                VirtualizingPanel.VirtualizationMode="Recycling"
                VirtualizingPanel.IsVirtualizing="True"

                ScrollViewer.CanContentScroll="True"
                ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                ScrollViewer.VerticalScrollBarVisibility="Auto">
            <ListView.Background>
                <ImageBrush ImageSource="/Images/background2.png" Stretch="UniformToFill"/>
            </ListView.Background>
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <vwp:VirtualizingWrapPanel Orientation="Horizontal" SpacingMode="Uniform"/>
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>

            <ListView.ItemTemplate>
                <DataTemplate>
                    <material:Card
                        Background="{StaticResource PrimaryHueMidBrush}"
                        Foreground="{StaticResource PrimaryHueMidForegroundBrush}"
                        Width="240" Height="200"
                        Padding="1"
                        material:ElevationAssist.Elevation="Dp7"
>
                        <Grid>.........

ItemContainerManager.cs:

 public IItemContainerInfo Realize(int itemIndex, out bool isNewlyRealized, out bool isNewContainer)
 {
     var item = Items[itemIndex];

     if (RealizedContainers.FirstOrDefault(container => container.Item == item) is { } containerInfo)
     {
         isNewlyRealized = false;
         isNewContainer = false;
         return containerInfo;
     }

     isNewlyRealized = true;
     var generatorPosition = recyclingItemContainerGenerator.GeneratorPositionFromIndex(itemIndex);
     using (recyclingItemContainerGenerator.StartAt(generatorPosition, GeneratorDirection.Forward))
     {
         var container = recyclingItemContainerGenerator.GenerateNext(out isNewContainer);
         recyclingItemContainerGenerator.PrepareItemContainer(container);
         containerInfo = ItemContainerInfo.For((UIElement)container, item); // <-- NullReferenceException
         cachedContainers.Remove(containerInfo);
         realizedContainers.Add(containerInfo);
         return containerInfo;
     }
 }

Stack:

PresentationFramework.dll!System.Windows.Controls.ItemContainerGenerator.System.Windows.Controls.Primitives.IItemContainerGenerator.PrepareItemContainer(System.Windows.DependencyObject container)
VirtualizingWrapPanel.dll!WpfToolkit.Controls.ItemContainerManager.Realize(int itemIndex, out bool isNewlyRealized, out bool isNewContainer) Line 140
    at C:\ItemContainerManager.cs(140)
VirtualizingWrapPanel.dll!WpfToolkit.Controls.VirtualizingWrapPanelModel.RealizeItemsAndFindEndIndex() Line 317
    at C:\VirtualizingWrapPanelModel.cs(317)
VirtualizingWrapPanel.dll!WpfToolkit.Controls.VirtualizingWrapPanelModel.OnMeasure(System.Windows.Size availableSize, System.Windows.Size viewportSize, System.Windows.Point scrollOffset) Line 97
    at C:\VirtualizingWrapPanelModel.cs(97)
VirtualizingWrapPanel.dll!WpfToolkit.Controls.VirtualizingWrapPanel.MeasureOverride(System.Windows.Size availableSize) Line 165
    at C:\VirtualizingWrapPanel.cs(165)
PresentationFramework.dll!System.Windows.FrameworkElement.MeasureCore(System.Windows.Size availableSize)
PresentationCore.dll!System.Windows.UIElement.Measure(System.Windows.Size availableSize)
PresentationCore.dll!System.Windows.ContextLayoutManager.UpdateLayout()
PresentationCore.dll!System.Windows.ContextLayoutManager.UpdateLayoutCallback(object arg)
PresentationCore.dll!System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()
PresentationCore.dll!System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
PresentationCore.dll!System.Windows.Media.MediaContext.RenderMessageHandlerCore(object resizedCompositionTarget)
PresentationCore.dll!System.Windows.Media.MediaContext.RenderMessageHandler(object resizedCompositionTarget)
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs)
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler)
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl()
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(object state)
WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(object obj)
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 980
    at f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs(980)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 928
    at f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs(928)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 917
    at f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs(917)
WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext executionContext, System.Threading.ContextCallback callback, object state)
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke()
WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue()
WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o)
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs)
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler)
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs)
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam)
[Native to Managed Transition]
[Managed to Native Transition]
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame)
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame)
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore)
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window)
PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window window)
PresentationFramework.dll!System.Windows.Application.Run()
Notificator.exe!Notificator.App.Main()

2.0.0-preview3 NET Framework 4.7.2 Windows 10 Version 22H2 Build 19045.3324

sbaeumlisberger commented 1 year ago

Thank's for reporting this issue. Unfortunately I do not unterstand how the NullReferenceExceptioncan can occur at this location.

Do you have any idea how I can reproduce this problem? Could you check if the issue also occurs with the stable version?

c0debeef commented 1 year ago

I have rewritten a lot of code since then. Maybe it's some kind of side effect. UTR too. Now I can't make it possible in this code to select elements of a list and have a background for this list at the same time.

sbaeumlisberger commented 1 year ago

I will close this issue now. If you can reproduce the problem, you can leave a comment or open a new issue.

Selection and background should work fine together. You can try it with the sample application. If you think there is an problem specific to the VirtualizingWrapPanel, feel free to open an issue regarding this problem.

c0debeef commented 1 year ago

It sometimes occurs. Tester's computer. I can't reproduce.

image_2023_09_06T15_43_30_977Z