Différence entre ObservableCollection et BindingList

236

Je veux connaître la différence entre ObservableCollectionet BindingListparce que j'ai utilisé les deux pour notifier tout changement d'ajout / suppression dans Source, mais en fait je ne sais pas quand préférer l'un plutôt que l'autre.

Pourquoi devrais-je choisir l'un des éléments suivants plutôt que l'autre?

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

ou

BindingList<Employee> lstEmp = new BindingList<Employee>();
Azhar
la source

Réponses:

278

Un ObservableCollectionpeut être mis à jour à partir de l'interface utilisateur exactement comme n'importe quelle collection. La vraie différence est assez simple:

ObservableCollection<T>implements INotifyCollectionChangedqui fournit une notification lorsque la collection est modifiée (vous l'avez deviné ^^) Il permet au moteur de liaison de mettre à jour l'interface utilisateur lorsque le ObservableCollectionest mis à jour.

Cependant, BindingList<T>implémente IBindingList.

IBindingListfournit une notification sur les changements de collection, mais pas seulement. Il fournit tout un tas de fonctionnalités qui peuvent être utilisées par l'interface utilisateur pour fournir beaucoup plus de choses que les seules mises à jour de l'interface utilisateur en fonction des changements, comme:

  • Tri
  • Recherche
  • Ajouter via l'usine (fonction membre AddNew).
  • Liste en lecture seule (propriété CanEdit)

Toutes ces fonctionnalités ne sont pas disponibles dans ObservableCollection<T>

Une autre différence est que les BindingListrelais relaient les notifications de changement d'élément lorsque ses éléments sont implémentés INotifyPropertyChanged. Si un élément déclenche un PropertyChangedévénement, le BindingListrecevra un déclenche un ListChangedEventavec ListChangedType.ItemChangedet OldIndex=NewIndex(si un élément a été remplacé, OldIndex=-1). ObservableCollectionne transmet pas les notifications d'articles.

Notez que dans Silverlight, BindingListn'est pas disponible en option: vous pouvez cependant utiliser ObservableCollections et ICollectionView(et IPagedCollectionViewsi je me souviens bien).

Eilistraee
la source
5
Une autre chose à considérer est la performance, voir: themissingdocs.net/wordpress/?p=465
Jarek Mazur
Merci, je n'étais pas au courant de l'implémentation réelle de BindingList. J'ai tendance à utiliser ObservableCollection et ICollectionView
Eilistraee
5
Bien que les informations de cette réponse soient correctes, tous les utilisateurs WPF doivent se méfier: BindingList n'implémente pas INotifyCollectionChanged et provoquera une fuite de mémoire s'il est lié à la propriété ItemsSource d'un contrôle. ObservableCollection met en œuvre l'interface et ne provoquera pas de telles fuites.
Brandon Hood
1
Si BindingList implémente le tri, alors pourquoi ne pouvez-vous pas trier une grille liée à une BindingList?
Robert Harvey
Est BindingListobsolète?
Shimmy Weitzhandler
27

La différence pratique est que BindingList est pour WinForms et ObservableCollection est pour WPF.

Du point de vue WPF, BindingList n'est pas correctement pris en charge, et vous ne l'utiliseriez jamais vraiment dans un projet WPF, sauf si vous en avez vraiment besoin.

Dean Chalk
la source
1
Intéressant. En tant que développeur Silverlight, je ne le savais pas. Merci. Et si vous voulez trier et filtrer, les implémentations ICollectionView sont votre ami ^^
Eilistraee
27
Pourquoi est-il «non pris en charge»? ViewManager (interne) se trouve dans l'assemblage PresentationFramework et le prend en charge. Liez-le à un ItemsControl par exemple et les notifications de changement sont respectées (c'est-à-dire que les éléments sont ajoutés et supprimés). S'il était spécifique à WinForms, ne devrait-il pas être mieux placé dans l'espace de noms Forms?
David Kiff
7
D'accord avec David, il se trouve dans l'espace de noms System.Collections, il devrait donc être entièrement pris en charge par WPF. WPF est juste une façon différente de mettre en page l'interface utilisateur.
Justin
13
D'accord avec David également, j'utilise BindingList fréquemment dans WPF car ObservableCollection ne fera pas bouillonner les notifications de changement de propriété de ses éléments.
amnésie
3
Pour donner un exemple pour "not supportet": Je viens de trouver une fuite de mémoire dans mon application WPF qui est causée par certaines BindingLists qui n'implémentent pas INotifyCollectionChanged
Breeze
4

Les différences les plus importantes telles que les fonctionnalités et les notifications de modification des éléments contenus sont déjà mentionnées par la réponse acceptée, mais il y en a d'autres, qui méritent également d'être mentionnées:

Performance

Lorsque AddNewest appelé, BindingList<T>recherche l'élément ajouté par une IndexOfrecherche. Et si Timplémente, INotifyPropertyChangedl'index d'un élément modifié est également recherché par IndexOf(bien qu'il n'y ait pas de nouvelle recherche tant que le même élément change à plusieurs reprises). Si vous stockez des milliers d'éléments dans la collection, alors ObservableCollection<T>(ou une IBindingListimplémentation personnalisée avec un coût de recherche O (1)) peut être plus préférable.

Complétude

  • L' IBindingListinterface est énorme (peut-être pas la conception la plus propre) et permet aux implémenteurs d'implémenter uniquement un sous-ensemble de ses fonctionnalités. Par exemple, les AllowNew, SupportsSortinget les SupportsSearchingpropriétés indiquent si AddNew, ApplySortet Findméthodes peuvent être utilisées, respectivement. Cela surprend souvent les gens qui BindingList<T>ne supportent pas le tri. En fait, il fournit des méthodes virtuelles permettant aux classes dérivées d'ajouter les fonctionnalités manquantes. La DataViewclasse est un exemple pour une IBindingListimplémentation complète ; cependant, ce n'est pas pour les collections typées en premier lieu. Et la BindingSourceclasse dans WinForms est un exemple hybride: elle prend en charge le tri si elle encapsule une autre IBindingListimplémentation, qui prend en charge le tri.

  • ObservableCollection<T>est déjà une implémentation complète de l' INotifyCollectionChangedinterface (qui n'a qu'un seul événement). Il a également des membres virtuels mais ObservableCollection<T>est généralement dérivé pour la même raison que sa Collection<T>classe de base : pour personnaliser l'ajout / la suppression d'éléments (par exemple dans une collection de modèles de données) plutôt que pour ajuster les fonctions de liaison.

Copie vs habillage

Les deux ObservableCollection<T>et BindingList<T>un constructeur qui accepte une liste déjà existante. Bien qu'ils se comportent différemment lorsqu'ils sont instanciés par une autre collection:

  • BindingList<T>agit comme un wrapper observable pour la liste fournie, et les modifications effectuées sur le BindingList<T>seront également répercutées sur la collection sous-jacente.
  • ObservableCollection<T>d'autre part, passe une nouvelle List<T>instance au Collection<T>constructeur de base et copie les éléments de la collection d'origine dans cette nouvelle liste. Bien sûr, si Tc'est un type de référence, les modifications sur les éléments seront visibles depuis la collection d'origine mais la collection elle-même ne sera pas mise à jour.
György Kőszeg
la source
1

Une plus grande différence entre ObservableCollectionet BindingListqui est pratique et peut être un facteur de décision d'enchère sur le sujet:

BindingList Gestionnaire de changement de liste:

Modification de la liste BindingList

ObservableCollection Changement de collection:

Collection ObervableCollection modifiée

Brief of Above: Si une propriété d'un élément est modifiée BindingList, l' ListChangedévénement vous donnera les détails complets de la propriété (dans PropertyDescriptor) et ObservableCollectionne vous le donnera pas. En fait ObservableCollection, ne déclenchera pas d'événement de modification pour une propriété modifiée dans un élément.

La conclusion ci-dessus concerne l' INotifyPropertyChangedimplémentation dans les classes de modèle. Par défaut, aucun ne déclenche l'événement modifié si une propriété est modifiée dans un élément.

Kylo Ren
la source
Je pense que cela (PropertyDescriptor) pourrait être une source de fuite de mémoire
Abdulkarim Kanaan