ItemsControl.ItemsSource MVVM performance
-
20-09-2019 - |
Question
I have an (non-virtualized) ItemsControl that binds its ItemsSource to a ObeservableCollection of ViewModel instances. Now once the large amount Model instances is loaded all the ViewModel complemnents needs to be added to that ObservableCollection. How can I add a large amount of ViewModels without making the UI Thread hang?
I suppose the UI Thread hangs because each time a new item is added the ItemsControl needs to update itself and does layout etc. over and over again.
- Should I suspend the binding add all items and then resume? If so, how?
- Should I override the ObservableCollection to implement an AddRange so only 1 CollectionChanged Event is fired for adding multiple items? Or alternatively just replace the whole collection?
- Or is it better to add each items separately and call Dispatcher.Invoke for each item separately? So I would unblock frequently.
How do you handle large dynamic lists that can not be virtualized?
Solution
You can create a a class derived from ObservableCollection which allows you to temporarily suspend CollectionChanged events like this:
public class SuspendableObservableCollection : ObservableCollection
{
private bool suspended;
public bool Suspended
{
get
{
return this.suspended;
}
set
{
this.suspended = value;
OnCollectionChanged(new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Reset));
}
}
protected override void OnCollectionChanged(
NotifyCollectionChangedEventArgs args)
{
if (!Suspended)
{
base.OnCollectionChanged(args);
}
}
}
OTHER TIPS
<ItemsControl IsAsync="True" ... />
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow