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, lasAllowNew
,SupportsSorting
ySupportsSearching
indican si se pueden utilizar los métodosAddNew
,ApplySort
yFind
, respectivamente. A menudo sorprende a las personas queBindingList<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 claseDataView
es un ejemplo para una implementación completa deIBindingList
; sin embargo, no es para colecciones mecanografiadas en primer lugar. Y la claseBindingSource
en WinForms es un ejemplo híbrido: admite la clasificación si envuelve otra implementación deIBindingList
, que admite la clasificación.ObservableCollection<T>
ya es una implementación completa de la interfazINotifyCollectionChanged
(que tiene un solo evento). También tiene miembros virtuales, peroObservableCollection<T>
generalmente se deriva por la misma razón que su claseCollection<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 enBindingList<T>
también se reflejarán en la colección subyacente. -
ObservableCollection<T>
por otro lado, pasa una nueva instancia deList<T>
al constructor de la colección baseCollection<T>
y copia los elementos de la colección original en esta nueva lista. Por supuesto, siT
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 eventoListChanged
le dará detalles completos de la propiedad (en PropertyDescriptor) yObservableCollection
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.