microsoft / microsoft-ui-xaml

Windows UI Library: the latest Windows 10 native controls and Fluent styles for your applications
MIT License
6.36k stars 678 forks source link

clearing observable collection bound to ListView crashes with ArgumentOutOfRangeException #8684

Closed busitech closed 11 months ago

busitech commented 1 year ago

WinUI Toolkit Bug Report


Name of components or parts of Toolkit: UIElement ListViewRenderer.ListViewTransparent ListViewRenderer TemplatedItemsList ListProxy ObservableCollection

Describe the bug: After calling ObservableCollection.Clear() the execution path travels down into the ABI and crashes there, in a virtual function table call to UpdateLayout, on an instance of ListViewRenderer.ListViewTransparent. The event being processed is OnCollectionChanged, and the NotifyCollectionChangedEventArgsEx.Action is Reset.

Version Info: SDK 7.0.306, RT 7.0.9, VS 17.6.33815.320, MAUI 7.0.92

Additional context:

System.ArgumentOutOfRangeException: This collection cannot work with indices larger than Int32.MaxValue - 1 (0x7FFFFFFF - 1). (Parameter 'index') at ABI.System.Collections.IList.ToAbiHelper.EnsureIndexInt32(UInt32 index, Int32 listCapacity) at ABI.System.Collections.IList.ToAbiHelper.GetAt(UInt32 index) at ABI.System.Collections.IList.Vftbl.Do_Abi_GetAt_0(IntPtr thisPtr, UInt32 index, IntPtr* result) --- End of stack trace from previous location --- at WinRT.ExceptionHelpers.gThrow|20_0(Int32 hr) at WinRT.ExceptionHelpers.ThrowExceptionForHR(Int32 hr) at ABI.Microsoft.UI.Xaml.IUIElementMethods.UpdateLayout(IObjectReference _obj) at Microsoft.UI.Xaml.UIElement.UpdateLayout() at Microsoft.Maui.Controls.Handlers.Compatibility.ListViewRenderer.b23_0() at Microsoft.Maui.Controls.DispatcherExtensions.DispatchIfRequired(IDispatcher dispatcher, Action action) at Microsoft.Maui.Controls.Handlers.Compatibility.ListViewRenderer.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) at Microsoft.Maui.Controls.Internals.TemplatedItemsList2.OnCollectionChanged(NotifyCollectionChangedEventArgs e) at Microsoft.Maui.Controls.Internals.TemplatedItemsList2.OnProxyCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) at Microsoft.Maui.Controls.ListProxy.OnCollectionChanged(NotifyCollectionChangedEventArgs e) at Microsoft.Maui.Controls.ListProxy.<>cDisplayClass34_0.b0() at Microsoft.Maui.Controls.DispatcherExtensions.DispatchIfRequired(IDispatcher dispatcher, Action action) at Microsoft.Maui.Controls.ListProxy.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) at Microsoft.Maui.Controls.ListProxy.WeakNotifyProxy.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e) at TestApp.TestAppUI.b21_0() <--- This calls ObservableCollection.Clear(); at Microsoft.Maui.Dispatching.Dispatcher.<>cDisplayClass9_0.b__0() at ABI.Microsoft.UI.Dispatching.DispatcherQueueHandler.Do_Abi_Invoke(IntPtr thisPtr)

alphac05 commented 1 year ago

The same occurs when trying to simple remove an item like this:

public ObservableCollection<string> Items { get; set; } = new ObservableCollection<string>() { "One" };

private void Button_Clicked(object sender, EventArgs e)
{
    Items.RemoveAt(Items.Count - 1);
    Items.Add("new");
}

At the third click on the button, exception occurs.

jsauve commented 1 year ago

A similar thing is happening for me on Android. ObservableCollection works fine with ListView when items are added. As soon as a collection change action of Reset happens (because Clear() is called on the bound ObservableCollection), I see an ArgumentOutOfRangeException that appears to be bubbling up from the layout mechanism.

ranjeshj commented 11 months ago

Just tried on a simple WinUI3 app. ObservableCollection hooked to a ListView's itemssource seems to work as expected. Can you please share a WinUI 3 standalone example where this crash is happening?

yaira2 commented 11 months ago

@ranjeshj how many items were in the list when you tested? This also seems to occur with larger collections as well as when you repeat this process multiple times.

ranjeshj commented 11 months ago

@yaira2 I tried with 100 items in itemssource. If you have a repro app, can you please share?

busitech commented 11 months ago

@ranjeshj Here is your repro app. Please reopen this issue.

ObservableCollectionResetCrash.zip

busitech commented 11 months ago

@ranjeshj You requested help with a repro app, and one was provided, yet the issue remains closed. Please respond in some way to indicate how we can proceed.

ranjeshj commented 10 months ago

@busitech are you seeing this in android or windows? the project you shared is a Maui project. Is it possible to share a WinUI repro? This repository is specific to WinUI (Windows only).

busitech commented 10 months ago

@ranjeshj The crash is seen only on Windows, and I am reporting a Windows bug.

Microsoft documentation states that "Windows apps built using .NET MAUI use Windows UI 3 (WinUI 3) library to create native apps that target the Windows desktop."

Therefore, please use the application project we shared to repro and resolve the issue.

busitech commented 10 months ago

@ranjeshj Are you going to reopen this case?

bengavin commented 8 months ago

We've also seeing this intermittently, but reliably, relevant portions of the stack trace are:

at ABI.System.Collections.IList.ToAbiHelper.EnsureIndexInt32(UInt32 index, Int32 listCapacity) at ABI.System.Collections.IList.ToAbiHelper.GetAt(UInt32 index) at ABI.System.Collections.IList.Vftbl.Do_Abi_GetAt_0(IntPtr thisPtr, UInt32 index, IntPtr* result) --- End of stack trace from previous location --- at WinRT.ExceptionHelpers.gThrow|39_0(Int32 hr) at ABI.Microsoft.UI.Xaml.IUIElementMethods.UpdateLayout(IObjectReference _obj) at Microsoft.UI.Xaml.UIElement.UpdateLayout() at Microsoft.Maui.Controls.Handlers.Compatibility.ListViewRenderer.b23_0() at Microsoft.Maui.Controls.DispatcherExtensions.DispatchIfRequired(IDispatcher dispatcher, Action action) at Microsoft.Maui.Controls.Handlers.Compatibility.ListViewRenderer.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) at Microsoft.Maui.Controls.Internals.TemplatedItemsList2.OnCollectionChanged(NotifyCollectionChangedEventArgs e) at Microsoft.Maui.Controls.Internals.TemplatedItemsList2.OnProxyCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) at Microsoft.Maui.Controls.ListProxy.OnCollectionChanged(NotifyCollectionChangedEventArgs e) at Microsoft.Maui.Controls.ListProxy.<>c__DisplayClass36_0.b__0() at Microsoft.Maui.Controls.DispatcherExtensions.DispatchIfRequired(IDispatcher dispatcher, Action action) at Microsoft.Maui.Controls.ListProxy.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) at Microsoft.Maui.Controls.WeakNotifyCollectionChangedProxy.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) at System.Collections.ObjectModel.ObservableCollection1.OnCollectionChanged(NotifyCollectionChangedEventArgs e) at System.Collections.ObjectModel.Collection1.Remove(T item)

busitech commented 8 months ago

@duncanmacmichael Would you please reopen this issue so we do not have to duplicate as a new issue?

SKeehnen commented 7 months ago

Any workaround for this? Just hit this issue as well.