INotifyCollectionChanged - Как часто он срабатывает (и как они делают его таким эффективным / быстрым)? - PullRequest
2 голосов
/ 03 октября 2011

В общем, мне интересно, как это на самом деле эффективно здесь.

Пример кода:

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

Не будет ли это запускать событие CollectionChanged каждый раз, когда пользовательский интерфейс будет иметьобновлять каждый раз?Или он делает это так, что ждет до тех пор, пока не будет завершена функция GetItems?

По сути, кажется, что WPF справляется с этим очень хорошо, и мне интересно, как они это сделали.

Ответы [ 3 ]

4 голосов
/ 03 октября 2011

Оптимизация производительности: привязка данных предоставляет некоторую справочную информацию о том, как разрешаются привязки данных, включая влияние на производительность различных источников элементов.Взгляните на привязку к разделу ItemsSource .

Рассмотрим сценарий, в котором у вас есть объект CLR List, содержащий список сотрудников, которые вы хотите отобразить вListBox.Чтобы создать соответствие между этими двумя объектами, вы должны связать свой список сотрудников со свойством ItemsSource объекта ListBox.Однако предположим, что к вашей группе присоединился новый сотрудник.Вы можете подумать, что для того, чтобы вставить этого нового человека в ваши связанные значения ListBox, вы просто добавили бы этого человека в свой список сотрудников и ожидаете, что это изменение будет автоматически распознано механизмом привязки данных.

Это предположениедоказать ложь;на самом деле, изменение не будет автоматически отражено в ListBox.Это связано с тем, что объект CLR List автоматически не вызывает событие изменения коллекции.Для того чтобы ListBox мог забрать изменения, вам нужно будет заново создать список сотрудников и повторно присоединить его к свойству ItemsSource объекта ListBox.Хотя это решение работает, оно оказывает огромное влияние на производительность.Каждый раз, когда вы переназначаете ItemsSource объекта ListBox на новый объект, ListBox сначала отбрасывает свои предыдущие элементы и восстанавливает весь список.Влияние на производительность увеличивается, если ваш ListBox отображается на сложный шаблон DataTemplate.

Очень эффективное решение этой проблемы - сделать список сотрудников ObservableCollection.Объект ObservableCollection вызывает уведомление об изменении, которое может получить механизм привязки данных.Событие добавляет или удаляет элемент из ItemsControl без необходимости регенерации всего списка.

Время обновления для 1 элемента (мс)

  • Для объекта списка CLR = 1656 мс
  • Для коллекции ObservableCollection = 20 мс

WPF никогда не привязывается напрямую к коллекции.Если вы указываете коллекцию в качестве источника привязки, WPF фактически привязывается к представлению коллекции по умолчанию .

Представление коллекции - это слой поверх коллекции источника привязки, который позволяет вамдля навигации и отображения исходной коллекции на основе запросов сортировки, фильтрации и группировки без необходимости изменения самой исходной коллекции.Представление коллекции также поддерживает указатель на текущий элемент в коллекции.Если исходная коллекция реализует интерфейс INotifyCollectionChanged, изменения, вызванные событием CollectionChanged, распространяются на представления.

3 голосов
/ 03 октября 2011

Событие будет срабатывать при каждом изменении.

Графический интерфейс не должен реагировать и обновляться каждый раз, он может откладывать это.
Я знаю, что WinForms оптимизирует это, я думаю, что в WPF аналогичный подход.

0 голосов
/ 03 октября 2011

Если вы хотите увидеть, как часто пользовательский интерфейс запрашивает свежие результаты, предоставьте его в качестве открытого свойства и поместите строку отладки в get (оценщик) открытого свойства для myObservableCollection.

...