Разница между ObservableCollection и BindingList
Я хочу знать разницу между ObservableCollection
а также BindingList
потому что я использовал оба для уведомления о любых добавлениях / удалениях в Source, но на самом деле я не знаю, когда предпочесть одно другому.
Почему я бы выбрал одно из следующего над другим?
ObservableCollection<Employee> lstEmp = new ObservableCollection<Employee>();
или же
BindingList<Employee> lstEmp = new BindingList<Employee>();
5 ответов
ObservableCollection
может обновляться из пользовательского интерфейса точно так же, как любая коллекция. Истинная разница довольно проста:
ObservableCollection<T>
инвентарь INotifyCollectionChanged
который предоставляет уведомление при изменении коллекции (как вы уже догадались ^^), он позволяет механизму привязки обновлять пользовательский интерфейс, когда ObservableCollection
обновляется.
Тем не мение, BindingList<T>
инвентарь IBindingList
,
IBindingList
обеспечивает уведомление об изменениях коллекции, но не только. Он предоставляет целый набор функциональных возможностей, которые пользовательский интерфейс может использовать для предоставления гораздо большего, чем просто обновления пользовательского интерфейса в соответствии с изменениями, например:
- Сортировка
- поиск
- Добавить через фабрику (функция-член AddNew).
- Список только для чтения (свойство CanEdit)
Все эти функции недоступны в ObservableCollection<T>
Другое отличие состоит в том, что BindingList
ретранслирует уведомления об изменении элемента, когда его элементы реализуют INotifyPropertyChanged
, Если предмет поднимает PropertyChanged
событие, BindingList
получит это поднимает ListChangedEvent
с ListChangedType.ItemChanged
а также OldIndex=NewIndex
(если предмет был заменен, OldIndex=-1
). ObservableCollection
не передает уведомления о предметах.
Обратите внимание, что в Silverlight, BindingList
не доступен в качестве опции: вы можете использовать ObservableCollection
с и ICollectionView
(а также IPagedCollectionView
если я хорошо помню).
Практическое отличие состоит в том, что BindingList предназначен для WinForms, а ObservableCollection - для WPF.
С точки зрения WPF, BindingList не поддерживается должным образом, и вы бы никогда не использовали его в проекте WPF без необходимости.
Наиболее важные различия, такие как функции и уведомления об изменениях в содержащихся элементах, уже упомянуты в принятом ответе, но есть и другие, о которых также стоит упомянуть:
Спектакль
когда AddNew
называется, BindingList<T>
ищет добавленный элемент IndexOf
уважать. И если T
инвентарь INotifyPropertyChanged
Индекс измененного элемента также ищется IndexOf
(хотя нет нового поиска, если один и тот же элемент изменяется неоднократно). Если вы храните тысячи элементов в коллекции, то ObservableCollection<T>
(или обычай IBindingList
реализация с O(1) стоимость поиска) может быть более предпочтительным.
завершенность
IBindingList
Интерфейс огромен (возможно, не самый чистый дизайн) и позволяет разработчикам реализовывать только часть его функций. Например,AllowNew
,SupportsSorting
а такжеSupportsSearching
свойства говорят лиAddNew
,ApplySort
а такжеFind
Методы могут быть использованы, соответственно. Люди часто удивляют, чтоBindingList<T>
Сам не поддерживает сортировку. На самом деле он предоставляет некоторые виртуальные методы, позволяющие производным классам добавлять недостающие функции.DataView
класс является примером для полногоIBindingList
реализация; однако, это не для типизированных коллекций во-первых. ИBindingSource
класс в WinForms является гибридным примером: он поддерживает сортировку, если он оборачивает другойIBindingList
реализация, которая поддерживает сортировку.ObservableCollection<T>
уже полная реализацияINotifyCollectionChanged
интерфейс (который имеет только одно событие). Он также имеет виртуальных членов, ноObservableCollection<T>
обычно выводится по той же причине, что и его базаCollection<T>
class: для настройки добавления / удаления элементов (например, в коллекции модели данных) вместо настройки функций привязки.
Копирование и упаковка
И то и другое ObservableCollection<T>
а также BindingList<T>
есть конструктор, который принимает уже существующий список. Хотя они ведут себя по-разному, когда они создаются другой коллекцией:
BindingList<T>
действует как видимая оболочка для предоставленного списка, и изменения, выполненные наBindingList<T>
будет отражено и в основной коллекции.ObservableCollection<T>
с другой стороны, проходит новыйList<T>
экземпляр на базуCollection<T>
конструктор и копирует элементы оригинальной коллекции в этот новый список. Конечно, еслиT
это ссылочный тип, изменения элементов будут видны из исходной коллекции, но сама коллекция не будет обновлена.
Еще одна большая разница между ObservableCollection
а также BindingList
это пригодится, и может быть фактором принятия решения по теме:
BindingList
Обработчик изменения списка:
ObservableCollection
Изменение коллекции:
Краткое изложение: если свойство элемента изменяется в
BindingList
,ListChanged
событие даст вам полную информацию о свойстве (в PropertyDescriptor) иObservableCollection
не дам тебе этого. по фактуObservableCollection
не будет вызывать событие изменения для свойства, измененного в элементе.
Выше вывод в отношении INotifyPropertyChanged
реализовано в модельных классах. По умолчанию никто не вызывает измененное событие, если свойство изменено в элементе.
Оба имеют преимущества и недостатки, которые требуют некоторого времени, чтобы обнаружить.
У меня были некоторые проблемы с BindingList, потому что событие уведомления об изменении происходит только после того , как элемент был удален, и предоставляет только индекс (это означает, что вы должны отслеживать, какой объект был в каком месте, если вы реализовали какой-то механизм после удаления). ObservableCollection, с другой стороны, дает вам список удаленных элементов.
BindingList имеет удобный метод AddNew(), который позволяет производному классу реализовать фабричный шаблон, например, инициализировать новые элементы значениями, зависящими от родительской коллекции (например, внешний ключ для родителя, если коллекция содержит дочерние элементы).
Также обратите внимание, что очень легко получить BindingList из ObservableCollection, используя (расширение ToBindingList в Entity Framework), и что возвращенный (производный) BindingList реализует функции, такие как сортировка, которых нет в простой ванили.