Unterschied zwischen ObservableCollection und BindingList


236

Ich möchte den Unterschied zwischen ObservableCollectionund kennen, BindingListweil ich beide verwendet habe, um über Änderungen in der Quelle beim Hinzufügen / Löschen zu benachrichtigen, aber ich weiß eigentlich nicht, wann ich eine der anderen vorziehen soll.

Warum sollte ich eine der folgenden Optionen der anderen vorziehen?

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

oder

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

Antworten:


278

Ein ObservableCollectionkann über die Benutzeroberfläche genau wie jede Sammlung aktualisiert werden. Der wahre Unterschied ist ziemlich einfach:

ObservableCollection<T>implementiert, INotifyCollectionChangeddas eine Benachrichtigung bereitstellt, wenn die Sammlung geändert wird (Sie haben es erraten ^^). Es ermöglicht der Bindungs-Engine, die Benutzeroberfläche zu aktualisieren, wenn die ObservableCollectionaktualisiert wird.

Allerdings BindingList<T>implementiert IBindingList.

IBindingListbietet Benachrichtigung über Sammlungsänderungen, aber nicht nur das. Es bietet eine ganze Reihe von Funktionen, die von der Benutzeroberfläche verwendet werden können, um viel mehr Dinge als nur Aktualisierungen der Benutzeroberfläche gemäß Änderungen bereitzustellen, wie z.

  • Sortierung
  • Suchen
  • Werkseitig hinzufügen (AddNew-Mitgliedsfunktion).
  • Schreibgeschützte Liste (CanEdit-Eigenschaft)

Alle diese Funktionen sind in nicht verfügbar ObservableCollection<T>

Ein weiterer Unterschied besteht darin, dass BindingListBenachrichtigungen über Elementänderungen weitergeleitet werden, wenn die Elemente implementiert werden INotifyPropertyChanged. Wenn ein Gegenstand ein PropertyChangedEreignis BindingListauslöst, erhält er einen ListChangedEventmit ListChangedType.ItemChangedund OldIndex=NewIndex(wenn ein Gegenstand ersetzt wurde OldIndex=-1). ObservableCollectionleitet keine Artikelbenachrichtigungen weiter.

Beachten Sie, dass in Silverlight BindingListnicht als Option verfügbar ist: Sie können jedoch ObservableCollections und verwenden ICollectionView(und IPagedCollectionViewwenn ich mich gut erinnere).


5
Eine andere Sache zu berücksichtigen ist Leistung, siehe: themissingdocs.net/wordpress/?p=465
Jarek Mazur

Vielen Dank, mir war die tatsächliche Implementierung von BindingList nicht bekannt. Ich neige dazu, ObservableCollection und ICollectionView
Eilistraee

5
Obwohl die Informationen in dieser Antwort korrekt sind, sollten alle WPF-Benutzer aufpassen: BindingList implementiert INotifyCollectionChanged nicht und verursacht einen Speicherverlust, wenn es an die ItemsSource-Eigenschaft eines Steuerelements gebunden ist. ObservableCollection implementiert die Schnittstelle und verursacht keine derartigen Lecks.
Brandon Hood

1
Wenn BindingList die Sortierung implementiert, warum können Sie dann kein an eine BindingList gebundenes Raster sortieren?
Robert Harvey

Ist BindingListveraltet?
Shimmy Weitzhandler

27

Der praktische Unterschied besteht darin, dass BindingList für WinForms und ObservableCollection für WPF gilt.

Aus WPF-Sicht wird BindingList nicht richtig unterstützt, und Sie würden es niemals wirklich in einem WPF-Projekt verwenden, wenn Sie es nicht wirklich müssten.


1
Interessant. Als Silverlight-Entwickler wusste ich das nicht. Vielen Dank. Und wenn Sie sortieren und filtern möchten, sind ICollectionView-Implementierungen Ihr Freund ^^
Eilistraee

27
Warum wird es "nicht unterstützt"? ViewManager (intern) befindet sich in der PresentationFramework-Assembly und wird unterstützt. Binden Sie es beispielsweise an ein ItemsControl, und die Änderungsbenachrichtigungen werden berücksichtigt (dh Elemente werden hinzugefügt und entfernt). Wenn es WinForms-spezifisch wäre, sollte es nicht besser im Forms-Namespace platziert werden?
David Kiff

7
In Übereinstimmung mit David befindet es sich im System.Collections-Namespace, sodass es von WPF vollständig unterstützt werden sollte. WPF ist nur eine andere Art des UI-Layouts.
Justin

13
Ich stimme auch David zu, ich verwende BindingList häufig in WPF, da ObservableCollection keine Benachrichtigungen über Eigenschaftsänderungen aus seinen Elementen in die Luft sprudelt.
Amnesie

3
Um ein Beispiel für "not supportet" zu geben: Ich habe gerade einen Speicherverlust in meiner WPF-Anwendung gefunden, der durch einige BindingLists verursacht wird, die INotifyCollectionChanged
Breeze

4

Die wichtigsten Unterschiede wie Funktionen und Änderungsbenachrichtigungen zu den enthaltenen Elementen werden bereits in der akzeptierten Antwort erwähnt, es gibt jedoch noch weitere, die ebenfalls erwähnenswert sind:

Performance

Wenn AddNewaufgerufen wird, wird BindingList<T>durch eine IndexOfSuche nach dem hinzugefügten Element gesucht. Und wenn Timplementiert, wird auch INotifyPropertyChangedder Index eines geänderten Elements durchsucht IndexOf(obwohl es keine neue Suche gibt, solange sich dasselbe Element wiederholt ändert). Wenn Sie Tausende von Elementen in der Sammlung speichern, kann ObservableCollection<T>(oder eine benutzerdefinierte IBindingListImplementierung mit O (1) Suchkosten) vorzuziehen sein.

Vollständigkeit

  • Die IBindingListSchnittstelle ist riesig (möglicherweise nicht das sauberste Design) und ermöglicht es den Implementierern, nur einen Teil ihrer Funktionen zu implementieren. Zum Beispiel der AllowNew, SupportsSortingund SupportsSearchingsagen Eigenschaften , ob AddNew, ApplySortund FindVerfahren verwendet werden kann, respectively. Es überrascht die Leute oft, dass BindingList<T>das Sortieren selbst nicht unterstützt wird. Tatsächlich bietet es einige virtuelle Methoden, mit denen die abgeleiteten Klassen die fehlenden Funktionen hinzufügen können. Die DataViewKlasse ist ein Beispiel für eine vollständige IBindingListImplementierung. Es ist jedoch in erster Linie nicht für typisierte Sammlungen gedacht. Die BindingSourceKlasse in WinForms ist ein hybrides Beispiel: Sie unterstützt das Sortieren, wenn sie eine andere IBindingListImplementierung umschließt , die das Sortieren unterstützt.

  • ObservableCollection<T>ist bereits eine vollständige Implementierung der INotifyCollectionChangedSchnittstelle (die nur ein einziges Ereignis hat). Es hat auch virtuelle Mitglieder, ObservableCollection<T>wird jedoch normalerweise aus demselben Grund wie seine Basisklasse abgeleitet Collection<T>: zum Anpassen von Elementen zum Hinzufügen / Entfernen (z. B. in einer Datenmodellsammlung), anstatt Bindungsfunktionen anzupassen.

Kopieren gegen Verpacken

Beide ObservableCollection<T>und BindingList<T>haben einen Konstruktor, der eine bereits vorhandene Liste akzeptiert. Obwohl sie sich anders verhalten, wenn sie von einer anderen Sammlung instanziiert werden:

  • BindingList<T>fungiert als beobachtbarer Wrapper für die bereitgestellte Liste, und die an der Liste vorgenommenen Änderungen wirken BindingList<T>sich auch auf die zugrunde liegende Sammlung aus.
  • ObservableCollection<T>Auf der anderen Seite übergibt eine neue List<T>Instanz an den Basiskonstruktor Collection<T>und kopiert die Elemente der ursprünglichen Sammlung in diese neue Liste. Wenn Tes sich um einen Referenztyp handelt, sind Änderungen an den Elementen in der ursprünglichen Sammlung sichtbar, aber die Sammlung selbst wird nicht aktualisiert.

1

Ein weiterer großer Unterschied zwischen ObservableCollectionund BindingListdas ist praktisch und kann ein Gebotsentscheidungsfaktor für das Thema sein:

BindingList List Change Handler:

Änderung der Bindungslistenliste

ObservableCollection Sammlungsänderung:

ObervableCollection Collection geändert

Kurz oben: Wenn eine Eigenschaft eines Elements in geändert wird, erhalten Sie durch BindingListdas ListChangedEreignis vollständige Details der Eigenschaft (in PropertyDescriptor) und ObservableCollectionnicht. Tatsächlich ObservableCollectionwird kein Änderungsereignis für eine in einem Element geänderte Eigenschaft ausgelöst.

Die obigen Schlussfolgerungen beziehen sich auf die INotifyPropertyChangedImplementierung in Modellklassen. Standardmäßig löst none das geänderte Ereignis aus, wenn eine Eigenschaft in einem Element geändert wird.


Ich denke, dies (PropertyDescriptor) könnte eine Quelle für ein Speicherleck sein
Abdulkarim Kanaan
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.