Разница между 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Обработчик изменения списка:

Изменение списка BindingList

ObservableCollectionИзменение коллекции:

Коллекция ObervableCollection изменена

Краткое изложение: если свойство элемента изменяется в BindingList, ListChanged событие даст вам полную информацию о свойстве (в PropertyDescriptor) и ObservableCollection не дам тебе этого. по факту ObservableCollection не будет вызывать событие изменения для свойства, измененного в элементе.

Выше вывод в отношении INotifyPropertyChanged реализовано в модельных классах. По умолчанию никто не вызывает измененное событие, если свойство изменено в элементе.

Оба имеют преимущества и недостатки, которые требуют некоторого времени, чтобы обнаружить.

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

BindingList имеет удобный метод AddNew(), который позволяет производному классу реализовать фабричный шаблон, например, инициализировать новые элементы значениями, зависящими от родительской коллекции (например, внешний ключ для родителя, если коллекция содержит дочерние элементы).

Также обратите внимание, что очень легко получить BindingList из ObservableCollection, используя (расширение ToBindingList в Entity Framework), и что возвращенный (производный) BindingList реализует функции, такие как сортировка, которых нет в простой ванили.

Другие вопросы по тегам