Является ли привязка ItemsControl к ObservableCollection более эффективной, чем список?


В ItemsControl у меня есть шаблон для рендеринга тяжелых элементов, и я хочу свести к минимуму воссоздание дочерних шаблонов элементов, когда ItemsSource сигнализирует об изменении. Мне интересно, потому что ObservableCollection может точно сказать WPF, что изменилось (в отличие от всего списка), если он более эффективен при визуализации изменений в коллекции, или если WPF достаточно умен, чтобы повторно использовать предыдущие представления элементов, если он обнаруживает, что тот же элемент все еще находится в измененном списке.

2 3

2 ответа:

Ваши подозрения верны. WPF не будет повторно использовать предыдущие представления. Если вы замените ItemsSource элемента ItemsControl новым списком, он создаст совершенно новые представления для каждого элемента в списке, даже если те же самые элементы были в старом списке.

Вы можете проверить это самостоятельно, поместив пользовательский элемент управления в ItemTemplate и добавив точку останова или журнал отладки в его конструктор. Если вы замените ItemsSource идентичным списком, вы увидите, что ваш элемент управления создан один раз для каждый пункт в списке. С другой стороны, когда элемент добавляется в коллекцию ObservableCollection, он вызывается только один раз.

Обратите внимание, что ItemsControl может повторно использовать контейнер (например, ListBoxItem), если вы используете панель виртуализации и включили утилизацию контейнеров. См. http://blogs.msdn.com/b/vinsibal/archive/2008/05/14/recycling-that-item-container.aspx однако он по-прежнему не может повторно использовать содержимое контейнера.

ObservableCollection сообщает только о добавлении и удалении объектов - так что, возможно, не так точно, как вы ожидали (если объект в списке изменяется, ObservableCollection не будет запускать никаких уведомлений).