On UWP: When my collection sends a CollectionChanged(NotifyCollectionChangedAction.Remove), the ListView scrolls back up to the top of the list.
Is there a way to make the scroll position stay the same on Remove?
FYI it works fine on Android.
@jezh I noticed that a sample code using ListView did not exhibit the same problematic behavior, so I tracked down the difference.
It's related to how NotifyCollectionChanged messages are interpreted, where on UWP the ListView is more picky than on Android.
My Remove messages were sent using OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
This seemingly triggered a reset of the Listview - for every remove the list scrolled to the top.
When I changed to use the constructor with item position OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, oldIndex));
then the expected behavior did indeed happen - the item was removed and items below moved up to fill the void.
In summary, this is a lesson for when not using an ObservableCollection base for your collection class - if you do your own CollectionChanged notification then make sure it behaves exactly like ObservableCollection. Following documentation and guidelines is not enough.
I'm not sure whether to call this a bug or poor documentation. My expectation on behavior was based on documentation, behavior on Android, and runtime output (no errors, warnings or log messages). On UWP expectations were not met, whereas on Android they were.
Answers
The listviews default ItemsPanel has a property called
ItemsUpdatingScrollMode
. You can set it toKeepItemsInView
.For more details: https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.itemsupdatingscrollmode#fields
@jezh I noticed that a sample code using ListView did not exhibit the same problematic behavior, so I tracked down the difference.
It's related to how NotifyCollectionChanged messages are interpreted, where on UWP the ListView is more picky than on Android.
My Remove messages were sent using
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
This seemingly triggered a reset of the Listview - for every remove the list scrolled to the top.
When I changed to use the constructor with item position
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, oldIndex));
then the expected behavior did indeed happen - the item was removed and items below moved up to fill the void.
In summary, this is a lesson for when not using an ObservableCollection base for your collection class - if you do your own CollectionChanged notification then make sure it behaves exactly like ObservableCollection. Following documentation and guidelines is not enough.
I'm not sure whether to call this a bug or poor documentation. My expectation on behavior was based on documentation, behavior on Android, and runtime output (no errors, warnings or log messages). On UWP expectations were not met, whereas on Android they were.
Could you please share a basic demo so that we can test the
OnCollectionChanged
?Besides, you can post your requirement for the poor documentation to official Website. I'm sure they will deal with your request as soon as possible.