6
votes

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?

2
What are you using? WPF/Silverlight? WinForms? Something else?slugster
It should be obvious that it's not windows forms because none of the mentioned classes exist in windows forms.bitbonk
is there any specific reason your itemscontrol cannot use UI Virtualization?Joachim Kerschbaumer

2 Answers

10
votes

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);
       }
    }
}
0
votes
<ItemsControl IsAsync="True" ... />