c# .net wpf observablecollection wpf-4.0

c# - Diferencia entre ObservableCollection y BindingList



.net wpf (4)

Quiero saber la diferencia entre ObservableCollection y BindingList porque he usado ambos para notificar cualquier cambio de adición / eliminación en la Fuente, pero en realidad no sé cuándo preferir una sobre la otra.

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

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

o

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


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 utilizarías realmente en un proyecto de WPF a menos que realmente tuvieras que hacerlo.


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

Actuación

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

Lo completo

  • La interfaz IBindingList 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 , SupportsSorting y SupportsSearching indican si se pueden utilizar los métodos AddNew , ApplySort y Find , respectivamente. A menudo sorprende a las personas que BindingList<T> sí no admite la clasificación. En realidad, proporciona algunos métodos virtuales que permiten a las clases derivadas agregar las características que faltan. La clase DataView es un ejemplo para una implementación completa de IBindingList ; sin embargo, no es para colecciones mecanografiadas en primer lugar. Y la clase BindingSource en WinForms es un ejemplo híbrido: admite la clasificación si envuelve otra implementación de IBindingList , que admite la clasificación.

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

Copia contra envoltura

Tanto ObservableCollection<T> como 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 BindingList<T> también se reflejarán en la colección subyacente.
  • ObservableCollection<T> por otro lado, pasa una nueva instancia de List<T> al constructor de la colección base Collection<T> y copia los elementos de la colección original en esta nueva lista. Por supuesto, si T es 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á.

Un ObservableCollection se puede actualizar desde la interfaz de usuario exactamente como cualquier colección. La verdadera diferencia es bastante sencilla:

ObservableCollection<T> implementa INotifyCollectionChanged que proporciona una notificación cuando se modifica la colección (adivinado ^^) Permite al motor de enlace actualizar la interfaz de usuario cuando se actualiza ObservableCollection .

Sin embargo, BindingList<T> implementa IBindingList .

IBindingList proporciona notificaciones sobre cambios en la colección, pero no solo eso. Proporciona una gran cantidad de funciones que pueden ser utilizadas por la interfaz de usuario para proporcionar muchas más cosas que solo las actualizaciones de la interfaz de usuario según los cambios, como:

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

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

Otra diferencia es que BindingList retransmite notificaciones de cambio de elementos cuando sus elementos implementan INotifyPropertyChanged . Si un elemento genera un evento PropertyChanged , BindingList lo recibirá y ListChangedEvent un ListChangedEvent con ListChangedType.ItemChanged y OldIndex=NewIndex (si se reemplazó un elemento, OldIndex=-1 ). ObservableCollection no transmite notificaciones de elementos.

Tenga en cuenta que en Silverlight, BindingList no está disponible como una opción: Sin embargo, puede usar ObservableCollection s e ICollectionView (y IPagedCollectionView si recuerdo bien).


Una diferencia más grande entre ObservableCollection y BindingList que viene a la mano, y puede ser un factor de decisión de la oferta en el tema:

BindingList cambios de lista BindingList :

Cambio en la colección ObservableCollection :

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

Las conclusiones anteriores se INotifyPropertyChanged implementado en clases modelo. De forma predeterminada, ninguno provoca el evento modificado si se modifica una propiedad en un elemento.