Cysharp / ObservableCollections

High performance observable collections and synchronized views, for WPF, Blazor, Unity.
MIT License
602 stars 46 forks source link

`ArgumentOutOfRangeException` when using `ToNotifyCollectionChanged` with `ObservableDictionary` #70

Closed erri120 closed 2 months ago

erri120 commented 2 months ago

With the latest version, there is an issue with the synchronized view lists. NonFilteredSynchronizedViewList uses the index from the event, however, the dictionary uses index -1 for most events:

https://github.com/Cysharp/ObservableCollections/blob/efec73f052f5e71226adbcbf603d0dec6d39fdfd/src/ObservableCollections/ObservableDictionary.cs#L143

https://github.com/Cysharp/ObservableCollections/blob/efec73f052f5e71226adbcbf603d0dec6d39fdfd/src/ObservableCollections/SynchronizedViewList.cs#L269

var dict = new ObservableDictionary<int, string>();
var view = dict.ToNotifyCollectionChanged();
dict.Add(key: 1, value: "foo");
System.ArgumentOutOfRangeException: Index must be within the bounds of the List. (Parameter 'index')
   at System.Collections.Generic.List`1.Insert(Int32 index, T item)
   at ObservableCollections.NonFilteredSynchronizedViewList`2.Parent_ViewChanged(SynchronizedViewChangedEventArgs`2& e)
   at ObservableCollections.SynchronizedViewExtensions.InvokeOnAdd[T,TView](ISynchronizedView`2 collection, Int32& filteredCount, NotifyViewChangedEventHandler`2 ev, T value, TView view, Int32 index)
   at ObservableCollections.ObservableDictionary`2.View`1.SourceCollectionChanged(NotifyCollectionChangedEventArgs`1& e)
   at ObservableCollections.ObservableDictionary`2.Add(TKey key, TValue value)
   at NexusMods.App.UI.Controls.TreeDataGridItemModel`2..ctor() in /mnt/redline/projects/NexusMods/app/main/src/NexusMods.App.UI/Controls/TreeDataGrid/TreeDataGridItemModel.cs:line 65
   at NexusMods.App.UI.Pages.LibraryPage.LibraryItemModel..ctor(LibraryItemId libraryItemId) in /mnt/redline/projects/NexusMods/app/main/src/NexusMods.App.UI/Pages/LibraryPage/LibraryItemModel.cs:line 46
   at NexusMods.App.UI.Pages.LibraryPage.FakeParentLibraryItemModel..ctor(LibraryItemId libraryItemId) in /mnt/redline/projects/NexusMods/app/main/src/NexusMods.App.UI/Pages/LibraryPage/FakeParentLibraryItemModel.cs:line 20
   at NexusMods.App.UI.Pages.LocalFileDataProvider.<>c__DisplayClass4_0.<ObserveNestedLibraryItems>b__0(Datom _, EntityId entityId) in /mnt/redline/projects/NexusMods/app/main/src/NexusMods.App.UI/Pages/LocalFileDataProvider.cs:line 84
   at DynamicData.ObservableCacheEx.<>c__DisplayClass212_0`3.<Transform>b__0(TSource current, Optional`1 _, TKey key) in /_/src/DynamicData/Cache/ObservableCacheEx.cs:line 4634
   at DynamicData.Cache.Internal.Transform`3.<RunImpl>b__6_0(ChangeAwareCache`2 cache, IChangeSet`2 changes) in /_/src/DynamicData/Cache/Internal/Transform.cs:line 46
   at System.Reactive.Linq.ObservableImpl.Scan`2._.OnNext(TSource value)
neuecc commented 2 months ago

Oh, this is awful. I've fixed and released it.