Różnica między ObservableCollection a BindingList

236

Chcę poznać różnicę między, ObservableCollectiona BindingListponieważ użyłem obu, aby powiadomić o każdej zmianie dodania / usunięcia w źródle, ale tak naprawdę nie wiem, kiedy wolę jedną od drugiej.

Dlaczego miałbym wybrać jedną z poniższych opcji?

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

lub

BindingList<Employee> lstEmp = new BindingList<Employee>();
Azhar
źródło

Odpowiedzi:

278

ObservableCollectionMogą być aktualizowane z UI dokładnie tak jak każdej kolekcji. Prawdziwa różnica jest raczej prosta:

ObservableCollection<T>implementuje, INotifyCollectionChangedktóry zapewnia powiadomienie o zmianie kolekcji (zgadłeś ^^) Pozwala silnikowi powiązań na aktualizację interfejsu użytkownika po ObservableCollectionaktualizacji.

Jednak BindingList<T>implementuje IBindingList.

IBindingListzapewnia powiadomienia o zmianach w kolekcji, ale nie tylko. Zapewnia całą gamę funkcji, które mogą być używane przez interfejs użytkownika w celu dostarczenia znacznie więcej rzeczy niż tylko aktualizacje interfejsu użytkownika zgodnie ze zmianami, takie jak:

  • Sortowanie
  • Badawczy
  • Dodaj przez fabrykę (funkcja dodawania nowego członka).
  • Lista tylko do odczytu (właściwość CanEdit)

Wszystkie te funkcje nie są dostępne w ObservableCollection<T>

Kolejną różnicą jest to, że BindingListprzekazuje powiadomienia o zmianie elementu, gdy jego elementy zostaną zaimplementowane INotifyPropertyChanged. Jeśli przedmiot wywołuje PropertyChangedzdarzenie, BindingListotrzyma go podbija za ListChangedEventpomocą ListChangedType.ItemChangedi OldIndex=NewIndex(jeśli przedmiot został wymieniony, OldIndex=-1). ObservableCollectionnie przekazuje powiadomień o przedmiotach.

Pamiętaj, że w Silverlight BindingListnie jest dostępna jako opcja: możesz jednak użyć ObservableCollections i ICollectionView(i IPagedCollectionViewjeśli dobrze pamiętam).

Eilistraee
źródło
5
Kolejną rzeczą do rozważenia jest wydajność, patrz: themissingdocs.net/wordpress/?p=465
Jarek Mazur
Dziękuję, nie byłem świadomy faktycznej implementacji BindingList. Zwykle używam ObservableCollection i ICollectionView
Eilistraee
5
Chociaż informacje w tej odpowiedzi są poprawne, wszyscy użytkownicy WPF powinni się wystrzegać: BindingList nie implementuje INotifyCollectionChanged i spowoduje wyciek pamięci, jeśli zostanie powiązany z właściwością ItemsSource kontrolki. ObservableCollection implementuje interfejs i nie spowoduje takich wycieków.
Brandon Hood,
1
Jeśli BindingList implementuje sortowanie, to dlaczego nie możesz sortować siatki powiązanej z BindingList?
Robert Harvey
Jest BindingListprzestarzały?
Shimmy Weitzhandler
27

Praktyczną różnicą jest to, że BindingList jest dla WinForms, a ObservableCollection jest dla WPF.

Z perspektywy WPF BindingList nie jest odpowiednio obsługiwany i nigdy tak naprawdę nie użyłbyś go w projekcie WPF, chyba że naprawdę musiałbyś.

Dean Chalk
źródło
1
Ciekawy. Jako twórca Silverlight nie wiedziałem o tym. Dzięki. A jeśli chcesz sortować i filtrować, implementacje ICollectionView są twoim przyjacielem ^^
Eilistraee
27
Dlaczego jest to „nieobsługiwane”? ViewManager (wewnętrzny) znajduje się w zespole PresentationFramework i obsługuje go. Powiąż go na przykład z ItemsControl, a powiadomienia o zmianie są przestrzegane (tzn. Elementy są dodawane i usuwane). Jeśli byłby specyficzny dla WinForms, czy nie powinien być lepiej umieszczony w przestrzeni nazw Forms?
David Kiff
7
Uzgodniony z Davidem, znajduje się w przestrzeni nazw System.Collections, więc powinien być w pełni obsługiwany przez WPF. WPF to po prostu inny sposób układu interfejsu użytkownika.
Justin
13
Zgadzam się także z Davidem, często używam BindingList w WPF, ponieważ ObservableCollection nie powoduje bąbelkowych powiadomień o zmianie właściwości z jego elementów.
amnezja
3
Aby podać przykład „nieobsługiwany”: Właśnie znalazłem wyciek pamięci w mojej aplikacji WPF, który jest spowodowany przez niektóre BindingLists nie implementujące INotifyCollectionChanged
Breeze
4

Najważniejsze różnice, takie jak funkcje i powiadomienia o zmianach w zawartych elementach, są już wspomniane w zaakceptowanej odpowiedzi, ale jest ich więcej, o których również warto wspomnieć:

Występ

Po AddNewwywołaniu BindingList<T>wyszukuje dodany element przez IndexOfwyszukiwanie. A jeśli Timplementuje, INotifyPropertyChangedindeks zmienionego elementu jest również przeszukiwany przez IndexOf(chociaż nie ma nowego wyszukiwania, o ile ten sam element zmienia się wielokrotnie). Jeśli przechowujesz tysiące elementów w kolekcji, wtedy ObservableCollection<T>(lub niestandardowa IBindingListimplementacja z kosztem wyszukiwania O (1)) może być bardziej preferowana.

Kompletność

  • IBindingListInterfejs jest ogromny jeden (może nie najczystsze konstrukcja) i pozwala implementors wdrożyć tylko podzbiór jego cech. Na przykład AllowNew, SupportsSortingi SupportsSearchingwłaściwości powiedzieć, czy AddNew, ApplySorti Findmetody mogą być stosowane odpowiednio. Często zaskakuje ludzi, którzy BindingList<T>sami nie obsługują sortowania. W rzeczywistości zapewnia pewne wirtualne metody pozwalające klasom pochodnym dodać brakujące funkcje. DataViewKlasa jest przykładem dla pełnego IBindingListwdrożenia; nie dotyczy to jednak przede wszystkim kolekcji maszynowych. A BindingSourceklasa w WinForm jest przykładem hybrydowym: obsługuje sortowanie, jeśli otacza inną IBindingListimplementację, która obsługuje sortowanie.

  • ObservableCollection<T>jest już pełną implementacją INotifyCollectionChangedinterfejsu (który ma tylko jedno zdarzenie). Ma także wirtualne elementy, ale ObservableCollection<T>zazwyczaj pochodzi z tego samego powodu, co jego podstawowa Collection<T>klasa: do dostosowywania dodawania / usuwania elementów (np. W kolekcji modelu danych) zamiast dostosowywania funkcji wiązania.

Kopiowanie a zawijanie

Zarówno ObservableCollection<T>i BindingList<T>mieć konstruktora, który akceptuje już istniejącej listy. Chociaż zachowują się inaczej, gdy są tworzone przez inną kolekcję:

  • BindingList<T>działa jako obserwowalne opakowanie dla podanej listy, a zmiany dokonane na BindingList<T>zostaną odzwierciedlone również w podstawowej kolekcji.
  • ObservableCollection<T>z drugiej strony przekazuje nową List<T>instancję do Collection<T>konstruktora podstawowego i kopiuje elementy oryginalnej kolekcji na nową listę. Oczywiście, jeśli Tjest to typ odniesienia, zmiany w elementach będą widoczne z oryginalnej kolekcji, ale sama kolekcja nie zostanie zaktualizowana.
György Kőszeg
źródło
1

Jeszcze jedna wielka różnica między tym ObservableCollectiona BindingListtym, co jest przydatne, i może być czynnikiem decydującym o stawce na ten temat:

BindingList Moduł zmiany listy:

Zmiana listy BindingList

ObservableCollection Zmiana kolekcji:

Zmieniono kolekcję ObervableCollection

Brief of Above: Jeśli właściwość elementu zostanie zmieniona BindingList, ListChangedwydarzenie poda pełne szczegóły właściwości (w PropertyDescriptor) i ObservableCollectiontego nie da. W rzeczywistości ObservableCollectionnie podniesie zdarzenia zmiany dla właściwości zmienionej w elemencie.

Powyższe wnioski dotyczą INotifyPropertyChangedimplementacji w klasach modeli. Domyślnie żaden nie wywołuje zmienionego zdarzenia, jeśli właściwość jest zmieniana w elemencie.

Kylo Ren
źródło
Myślę, że ten (PropertyDescriptor) może być źródłem wycieku pamięci
Abdulkarim Kanaan