سؤال

Basically, I'm wondering how it is actually efficient here.

Sample code:

void GetItems()
{
    foreach (var item in items)
        myObservableCollection.Add(item);
}

Won't this fire off the CollectionChanged event every time causing the UI to have to refresh everytime? Or does it do it so that it waits til the GetItems function is done?

Basically, it seems that WPF handles it very well, and I'm wondering how they did that.

هل كانت مفيدة؟

المحلول

The event will fire for every change.

The GUI does not have to react and refresh every time, it can postpone that.
I know WinForms will optimize this, I think WPF has a similar approach.

نصائح أخرى

Optimizing Performance: Data Binding provides some background on how data bindings are resolved, including the performance implications of different items sources. Take a look at the Binding to an ItemsSource section.

Consider a scenario in which you have a CLR List object that holds a list of employees that you want to display in a ListBox. To create a correspondence between these two objects, you would bind your employee list to the ItemsSource property of the ListBox. However, suppose you have a new employee joining your group. You might think that in order to insert this new person into your bound ListBox values, you would simply add this person to your employee list and expect this change to be recognized by the data binding engine automatically.

That assumption would prove false; in actuality, the change will not be reflected in the ListBox automatically. This is because the CLR List object does not automatically raise a collection changed event. In order to get the ListBox to pick up the changes, you would have to recreate your list of employees and re-attach it to the ItemsSource property of the ListBox. While this solution works, it introduces a huge performance impact. Each time you reassign the ItemsSource of ListBox to a new object, the ListBox first throws away its previous items and regenerates its entire list. The performance impact is magnified if your ListBox maps to a complex DataTemplate.

A very efficient solution to this problem is to make your employee list an ObservableCollection. An ObservableCollection object raises a change notification which the data binding engine can receive. The event adds or removes an item from an ItemsControl without the need to regenerate the entire list.

Update time for 1 item (ms)

  • To a CLR List object = 1656 ms
  • To an ObservableCollection = 20 ms

WPF never binds directly to a collection. If you specify a collection as a binding source, WPF actually binds to the collection's default view.

A collection view is a layer on top of a binding source collection that allows you to navigate and display the source collection based on sort, filter, and group queries, without having to change the underlying source collection itself. A collection view also maintains a pointer to the current item in the collection. If the source collection implements the INotifyCollectionChanged interface, the changes raised by the CollectionChanged event are propagated to the views.

If you want to see how often the UI requests the fresh results expose it as a public property and put a debug line in the get (assessor) of the public property for myObservableCollection.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top