Різниця між спостережуваною колекцією та BindingList


236

Я хочу знати різницю між ObservableCollectionі BindingListтому , що я використовував як для повідомлення для будь-якого додавання / видалення змін в джерелі, але я на самом деле не знаю , коли віддавати перевагу один над іншим.

Чому я б обрав одне з наступних над іншим?

ObservableCollection<Employee> lstEmp = new ObservableCollection<Employee>();

або

BindingList<Employee> lstEmp = new BindingList<Employee>();

Відповіді:


278

Оновлення 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не є опцією: однак ви можете використовувати ObservableCollections і ICollectionViewIPagedCollectionViewякщо я добре пам’ятаю).


5
Інша річ, яку слід враховувати, - це продуктивність, дивіться: themissingdocs.net/wordpress/?p=465
Jarek Mazur

Дякую, мені не було відомо про фактичну реалізацію BindingList. Я схильний використовувати ObservableCollection та ICollectionView
Eilistraee

5
Хоча інформація у цій відповіді правильна, будь-які користувачі WPF повинні остерігатися: BindingList не реалізує INotifyCollectionChanged і призведе до витоку пам’яті, якщо прив’язаний до властивості ItemSource управління. ObservableCollection реалізує інтерфейс і не спричинить таких витоків.
Брендон Гуд

1
Якщо BindingList реалізує сортування, то чому ви не можете сортувати сітку, прив’язану до BindingList?
Роберт Харві

Чи BindingListзастаріла?
Шиммі Вайцхандлер

27

Практична відмінність полягає в тому, що BindingList призначений для WinForms, а ObservableCollection - для WPF.

З точки зору WPF, BindingList не підтримується належним чином, і ви ніколи не використовуєте його в проекті WPF, якщо вам це не довелося.


1
Цікаво. Як розробник Silverlight, я цього не знав. Дякую. І якщо ви хочете сортувати та фільтрувати, реалізація ICollectionView - ваш друг ^^
Eilistraee

27
Чому він не підтримується? ViewManager (внутрішній) знаходиться в складі PresentationFramework і підтримує його. Наприклад, прив'яжіть його до ItemControl, і сповіщення про зміни будуть дотримані (тобто елементи додаються та видаляються). Якби він був специфічним для WinForms, чи не краще він розміщуватись у просторі імен Forms?
Девід Кіфф

7
За погодженням з Девідом, він знаходиться в просторі імен System.Collections, тому він повинен повністю підтримуватися WPF. WPF - це просто інший спосіб компонування інтерфейсу користувача.
Джастін

13
Погодьтесь із Девідом, я також часто використовую BindingList у WPF, оскільки ObservableCollection не буде міхувати сповіщення про зміну властивостей зі своїх елементів.
амнезія

3
Щоб навести приклад "не підтримує": я просто виявив витік пам'яті в моєму додатку WPF, який викликаний деякими BindingLists, які не реалізують INotifyCollectionChanged
Breeze

4

Найважливіші відмінності, такі як функції та сповіщення про зміни елементів, що містяться, вже згадуються прийнятою відповіддю, але є й інші, які також варто згадати:

Продуктивність

Коли 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>клас: для налаштування елементів додавання / видалення (наприклад, у колекції моделей даних), а не для коригування функцій прив’язки.

Копіювання проти обгортання

Обидва ObservableCollection<T>і BindingList<T>мають конструктор, який приймає вже існуючий список. Хоча вони поводяться інакше, коли інстанціюються іншою колекцією:

  • BindingList<T>виконує функції спостережуваної обгортки для поданого списку, і зміни, виконані на BindingList<T>заповіті, будуть відображені і на базовій колекції.
  • ObservableCollection<T>з іншого боку передає новий List<T>екземпляр базовому Collection<T>конструктору і копіює елементи оригінальної колекції в цей новий список. Звичайно, якщо Tє еталонний тип, зміни елементів будуть видні з оригінальної колекції, але сама колекція не буде оновлюватися.

1

Ще одна велика різниця між ObservableCollectionі BindingListщо попадеться під руку, і може бути фактором прийняття пропозиції на тему:

BindingList Обробник змін списку:

Зміна списку BindingList

ObservableCollection Зміна колекції:

Колекція ObervableCollection Змінена

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

Вищенаведений висновок стосується INotifyPropertyChangedвпроваджених в модельних класах. За замовчуванням жодна не викликає змінену подію, якщо властивість змінюється в елементі.


Я думаю, що це (PropertyDescriptor) може стати джерелом для витоку пам’яті
Абдулкарім Канаан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.