Diferencia entre ObservableCollection y BindingList

236

Quiero saber la diferencia entre ObservableCollectiony BindingListporque he usado ambos para notificar cualquier cambio de agregar / eliminar en Fuente, pero en realidad no sé cuándo preferir uno sobre el otro.

¿Por qué elegiría uno de los siguientes sobre el otro?

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

o

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

Respuestas:

278

Se ObservableCollectionpuede actualizar desde UI exactamente como cualquier colección. La verdadera diferencia es bastante sencilla:

ObservableCollection<T>implementa INotifyCollectionChangedque proporciona notificación cuando se cambia la colección (adivinó ^^) Permite que el motor de enlace actualice la IU cuando ObservableCollectionse actualiza.

Sin embargo, BindingList<T>implementos IBindingList.

IBindingListproporciona notificaciones sobre cambios en la colección, pero no solo eso. Proporciona un montón de funcionalidades que la interfaz de usuario puede usar para proporcionar muchas más cosas que solo actualizaciones de la interfaz de usuario de acuerdo con los cambios, como:

  • Clasificación
  • buscando
  • Agregar a través de la fábrica (función de miembro AddNew).
  • Lista de solo lectura (propiedad CanEdit)

Todas estas funcionalidades no están disponibles en ObservableCollection<T>

Otra diferencia es que BindingListretransmite notificaciones de cambio de elementos cuando se implementan sus elementos INotifyPropertyChanged. Si un artículo genera un PropertyChangedevento, BindingListlo recibirá y aumenta un ListChangedEventcon ListChangedType.ItemChangedy OldIndex=NewIndex(si un artículo fue reemplazado OldIndex=-1). ObservableCollectionno retransmite notificaciones de artículos.

Tenga en cuenta que en Silverlight, BindingListno está disponible como una opción: sin embargo, puede usar ObservableCollectionsy ICollectionView(y IPagedCollectionViewsi no recuerdo mal).

Eilistraee
fuente
55
Otra cosa a considerar es el rendimiento, ver: themissingdocs.net/wordpress/?p=465
Jarek Mazur
Gracias, no estaba al tanto de la implementación real de BindingList. Tiendo a usar ObservableCollection e ICollectionView
Eilistraee
55
Si bien la información en esta respuesta es correcta, cualquier usuario de WPF debe tener cuidado: BindingList no implementa INotifyCollectionChanged y causará una pérdida de memoria si está vinculado a la propiedad ItemsSource de un control. ObservableCollection implementa la interfaz y no causará tales fugas.
Brandon Hood
1
Si BindingList implementa la ordenación, ¿por qué no puede ordenar una cuadrícula vinculada a una BindingList?
Robert Harvey
Es BindingListobsoleto?
Shimmy Weitzhandler
27

La diferencia práctica es que BindingList es para WinForms y ObservableCollection es para WPF.

Desde la perspectiva de WPF, BindingList no se admite correctamente, y nunca lo usaría realmente en un proyecto de WPF a menos que realmente tuviera que hacerlo.

Dean Chalk
fuente
1
Interesante. Como desarrollador de Silverlight, no lo sabía. Gracias. Y si desea ordenar y filtrar, las implementaciones de ICollectionView son su amigo ^^
Eilistraee
27
¿Por qué es "No compatible"? ViewManager (interno) está dentro del ensamblaje PresentationFramework y eso lo admite. Vincúlelo a un control de elementos, por ejemplo, y se respetan las notificaciones de cambio (es decir, se agregan y eliminan elementos). Si fuera específico de WinForms, ¿no debería colocarse mejor en el espacio de nombres de Formularios?
David Kiff
77
De acuerdo con David, está en el espacio de nombres System.Collections, por lo que debe ser totalmente compatible con WPF. WPF es solo una forma diferente de diseño de interfaz de usuario.
Justin
13
También estoy de acuerdo con David, uso BindingList con frecuencia en WPF porque ObservableCollection no burbujeará las notificaciones de cambio de propiedad de sus elementos.
amnesia
3
Para dar un ejemplo de "no compatible": acabo de encontrar una pérdida de memoria en mi aplicación WPF causada por algunas BindingLists que no implementan INotifyCollectionChanged
Breeze
4

La respuesta aceptada ya menciona las diferencias más importantes, como las características y las notificaciones de cambios sobre los elementos contenidos, pero hay más, que también vale la pena mencionar:

Actuación

Cuando AddNewse llama, BindingList<T>busca el elemento agregado mediante una IndexOfbúsqueda. Y si Timplementa INotifyPropertyChangedel índice de un elemento modificado también se busca IndexOf(aunque no hay una nueva búsqueda siempre que el mismo elemento cambie repetidamente). Si almacena miles de elementos en la colección, entonces ObservableCollection<T>(o una IBindingListimplementación personalizada con un costo de búsqueda O (1)) puede ser más preferible.

Lo completo

  • La IBindingListinterfaz es enorme (quizás no sea el diseño más limpio) y permite a los implementadores implementar solo un subconjunto de sus características. Por ejemplo, las AllowNew, SupportsSortingy SupportsSearchingpropiedades dicen si AddNew, ApplySorty Findmétodos se pueden utilizar, respectivamente. A menudo sorprende a la gente que en BindingList<T>sí misma no admite la clasificación. En realidad, proporciona algunos métodos virtuales que permiten que las clases derivadas agreguen las características que faltan. La DataViewclase es un ejemplo para una IBindingListimplementación completa ; sin embargo, no es para colecciones escritas en primer lugar. Y la BindingSourceclase en WinForms es un ejemplo híbrido: admite la clasificación si envuelve otra IBindingListimplementación, que admite la clasificación.

  • ObservableCollection<T>ya es una implementación completa de la INotifyCollectionChangedinterfaz (que tiene un solo evento). También tiene miembros virtuales, pero ObservableCollection<T>generalmente se deriva por la misma razón que su Collection<T>clase base : para personalizar elementos de agregar / quitar (por ejemplo, en una colección de modelo de datos) en lugar de ajustar las características de enlace.

Copiar vs envolver

Ambos ObservableCollection<T>y BindingList<T>tienen un constructor, que acepta una lista ya existente. Aunque se comportan de manera diferente cuando son instanciados por otra colección:

  • BindingList<T>actúa como un contenedor observable para la lista proporcionada, y los cambios realizados en el BindingList<T>se reflejarán también en la colección subyacente.
  • ObservableCollection<T>por otro lado, pasa una nueva List<T>instancia al Collection<T>constructor base y copia los elementos de la colección original en esta nueva lista. Por supuesto, si se Ttrata de un tipo de referencia, los cambios en los elementos serán visibles desde la colección original, pero la colección en sí no se actualizará.
György Kőszeg
fuente
1

Una gran diferencia más entre eso ObservableCollectiony BindingListque es útil, y puede ser un factor de decisión sobre el tema:

BindingList Controlador de cambio de lista:

Cambio de lista de BindingList

ObservableCollection Cambio de colección:

Colección ObervableCollection cambiada

Resumen de lo anterior: si se cambia una propiedad de un elemento BindingList, el ListChangedevento le dará detalles completos de la propiedad (en PropertyDescriptor) y ObservableCollectionno le dará eso. De hecho ObservableCollection, no se generará un evento de cambio para una propiedad modificada en un artículo.

La conclusión anterior se refiere a lo INotifyPropertyChangedimplementado en las clases modelo. De forma predeterminada, ninguno genera el evento modificado si se cambia una propiedad en un elemento.

Kylo Ren
fuente
Creo que esto (PropertyDescriptor) podría ser una fuente de pérdida de memoria
Abdulkarim Kanaan