Closed c0nstexpr closed 3 months ago
I might understand why the exception was thrown, a possible solution would be add a backed collection (for example a sorted list) for binding in my code.
I did some research, and found that this is a decades-old pain point in regards to ListView, ListBox, etc: you pass an IEnumerable to bind to, but what they really want is IList, because they expect an integer index to synchronize things.
Dictionaries do not store data in a deterministic order, so ObservableDictionary can't guarantee a specific integer index for each key-value-pair, which is why it returns -1 for oldStartingIndex in its NotifyCollectionChangedEventArgs for remove. This causes the error you're experiencing. Incidentally, ObservableHashSet will have the same behavior.
Perhaps ObservableCollections may benefit from an ObservableKeyedCollection (which can be indexed both as a dictionary and a list).
I did some research, and found that this is a decades-old pain point in regards to ListView, ListBox, etc: you pass an IEnumerable to bind to, but what they really want is IList, because they expect an integer index to synchronize things.
Dictionaries do not store data in a deterministic order, so ObservableDictionary can't guarantee a specific integer index for each key-value-pair, which is why it returns -1 for oldStartingIndex in its NotifyCollectionChangedEventArgs for remove. This causes the error you're experiencing. Incidentally, ObservableHashSet will have the same behavior.
Perhaps ObservableCollections may benefit from an ObservableKeyedCollection (which can be indexed both as a dictionary and a list).
I also see the post when I encounter the problem and search for solution. For now I write my own list collection for dictionary to support list view binding.
I clone the repo and edit the wpf test like below:
Run the application, and click the remove button. It thows
InvalidOperation
with messageCollection Remove event must specify item position
. Stack trace below: