Differenza tra ObservableCollection e BindingList


236

Voglio sapere la differenza tra ObservableCollectione BindingListperché ho usato entrambi per notificare qualsiasi modifica di aggiunta / eliminazione in Source, ma in realtà non so quando preferire l'uno rispetto all'altro.

Perché dovrei scegliere uno dei seguenti rispetto all'altro?

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

o

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

Risposte:


278

Un ObservableCollectionpuò essere aggiornato dall'interfaccia utente esattamente come qualsiasi raccolta. La vera differenza è piuttosto semplice:

ObservableCollection<T>implementa INotifyCollectionChangedche fornisce notifica quando la raccolta viene modificata (avete indovinato ^^) Consente al motore di associazione di aggiornare l'interfaccia utente quando ObservableCollectionviene aggiornata.

Tuttavia, BindingList<T>implementa IBindingList.

IBindingListfornisce notifiche sulle modifiche alla raccolta, ma non solo. Fornisce un sacco di funzionalità che possono essere utilizzate dall'interfaccia utente per fornire molte più cose rispetto ai soli aggiornamenti dell'interfaccia utente in base alle modifiche, come:

  • Ordinamento
  • ricerca
  • Aggiungi tramite factory (funzione membro AddNew).
  • Elenco di sola lettura (proprietà CanEdit)

Tutte queste funzionalità non sono disponibili in ObservableCollection<T>

Un'altra differenza è che BindingListinoltra le notifiche di modifica degli articoli quando vengono implementate INotifyPropertyChanged. Se un oggetto genera un PropertyChangedevento, lo BindingListriceverà un genera un ListChangedEventcon ListChangedType.ItemChangede OldIndex=NewIndex(se un oggetto è stato sostituito, OldIndex=-1). ObservableCollectionnon inoltra le notifiche degli articoli.

Nota che in Silverlight BindingListnon è disponibile come opzione: puoi comunque usare ObservableCollections e ICollectionView(e IPagedCollectionViewse ricordo bene).


5
Un'altra cosa da considerare è la performance, vedi: themissingdocs.net/wordpress/?p=465
Jarek Mazur

Grazie, non ero a conoscenza dell'attuazione effettiva di BindingList. Tendo a usare ObservableCollection e ICollectionView
Eilistraee il

5
Mentre le informazioni contenute in questa risposta sono corrette, tutti gli utenti WPF devono fare attenzione: BindingList non implementa INotifyCollectionChanged e causerà una perdita di memoria se associato alla proprietà ItemsSource di un controllo. ObservableCollection implementa l'interfaccia e non causerà tali perdite.
Brandon Hood,

1
Se BindingList implementa l'ordinamento, perché non è possibile ordinare una griglia associata a un BindingList?
Robert Harvey,

È BindingListobsoleto?
Shimmy Weitzhandler,

27

La differenza pratica è che BindingList è per WinForms e ObservableCollection è per WPF.

Dal punto di vista WPF, BindingList non è supportato correttamente e non lo useresti mai in un progetto WPF a meno che non lo avessi realmente fatto.


1
Interessante. Come Silverlight Dev, non lo sapevo. Grazie. E se vuoi ordinare e filtrare, le implementazioni di ICollectionView sono le tue amiche ^^
Eilistraee,

27
Perché è "Non supportato"? ViewManager (interno) si trova nell'assembly PresentationFramework e lo supporta. Associarlo ad un ItemsControl per esempio e le notifiche di modifica sono rispettate (ovvero gli elementi vengono aggiunti e rimossi). Se fosse specifico per WinForms, non dovrebbe essere collocato meglio nello spazio dei nomi Forms?
David Kiff,

7
D'accordo con David, è nello spazio dei nomi System.Collections, quindi dovrebbe essere pienamente supportato da WPF. WPF è solo un modo diverso di layout dell'interfaccia utente.
Giustino,

13
Concordo anche con David, uso spesso BindingList in WPF perché ObservableCollection non eliminerà le notifiche di modifica della proprietà dai suoi elementi.
amnesia,

3
Per fare un esempio di "non supportet": ho appena trovato una perdita di memoria nella mia applicazione WPF causata da alcune BindingList che non implementano INotifyCollectionChanged
Breeze

4

Le differenze più importanti come funzionalità e notifiche di modifica relative agli elementi contenuti sono già menzionate nella risposta accettata, ma ce ne sono altre, che vale anche la pena menzionare:

Prestazione

Quando AddNewviene chiamato, BindingList<T>cerca l'elemento aggiunto tramite una IndexOfricerca. E se Timplementa INotifyPropertyChangedl'indice di un elemento modificato viene anche cercato da IndexOf(anche se non esiste una nuova ricerca purché lo stesso elemento cambi ripetutamente). Se memorizzi migliaia di elementi nella raccolta, allora ObservableCollection<T>(o IBindingListun'implementazione personalizzata con costo di ricerca O (1)) può essere più preferibile.

Completezza

  • L' IBindingListinterfaccia è enorme (forse non il design più pulito) e consente agli implementatori di implementare solo un sottoinsieme delle sue funzionalità. Ad esempio, i AllowNew, SupportsSortinge SupportsSearchingproprietà indicano se AddNew, ApplySorte Findmetodi possono essere utilizzati, rispettivamente. Sorprende spesso le persone che di per BindingList<T>sé non supportano l'ordinamento. In realtà fornisce alcuni metodi virtuali che consentono alle classi derivate di aggiungere le funzionalità mancanti. La DataViewclasse è un esempio per IBindingListun'implementazione completa ; tuttavia, non è per le raccolte tipizzate in primo luogo. E la BindingSourceclasse in WinForms è un esempio ibrido: supporta l'ordinamento se avvolge un'altra IBindingListimplementazione, che supporta l'ordinamento.

  • ObservableCollection<T>è già un'implementazione completa INotifyCollectionChangeddell'interfaccia (che ha solo un singolo evento). Ha anche membri virtuali, ma in ObservableCollection<T>genere è derivato per lo stesso motivo della sua Collection<T>classe di base : per personalizzare gli elementi Aggiungi / Rimuovi (ad es. In una raccolta di modelli di dati) piuttosto che regolare le funzionalità di rilegatura.

Copia vs. avvolgimento

Entrambi ObservableCollection<T>e BindingList<T>hanno un costruttore, che accetta un elenco già esistente. Sebbene si comportino diversamente quando vengono istanziati da un'altra raccolta:

  • BindingList<T>funge da wrapper osservabile per l'elenco fornito e le modifiche apportate su BindingList<T>si rifletteranno anche sulla raccolta sottostante.
  • ObservableCollection<T>d'altra parte passa una nuova List<T>istanza al Collection<T>costruttore di base e copia gli elementi della raccolta originale in questo nuovo elenco. Ovviamente, se si Ttratta di un tipo di riferimento, le modifiche sugli elementi saranno visibili dalla raccolta originale ma la raccolta stessa non verrà aggiornata.

1

Un'altra grande differenza tra ObservableCollectione BindingListche è utile, e può essere un fattore decisionale di offerta sull'argomento:

BindingList Gestore modifica elenco:

Modifica elenco BindingList

ObservableCollection Cambio raccolta:

Collezione ObervableCollection modificata

Brief of Above: Se una proprietà di un oggetto viene cambiata in BindingList, l' ListChangedevento ti fornirà i dettagli completi della proprietà (in PropertyDescriptor) e ObservableCollectionnon ti darà quello. In realtà ObservableCollectionnon genererà un evento di modifica per una proprietà modificata in un elemento.

Le conclusioni di cui sopra riguardano l' INotifyPropertyChangedimplementazione in classi di modelli. Per impostazione predefinita, nessuno genera l'evento modificato se una proprietà viene modificata in un elemento.


Penso che questo (PropertyDescriptor) potrebbe essere una fonte per una perdita di memoria
Abdulkarim Kanaan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.