Solución
ReadOnlyObservableCollection.CollectionChanged
no está expuesto (por razones válidas descritas en otras respuestas), así que hagamos nuestra propia clase contenedora que lo exponga:
public class ObservableReadOnlyCollection<T> : ReadOnlyObservableCollection<T>
{
public new NotifyCollectionChangedEventHandler CollectionChanged;
public ObservableReadOnlyCollection(ObservableCollection<T> list) : base(list) { }
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs args) =>
CollectionChanged?.Invoke(this, args);
}
Explicación
La gente ha preguntado por qué querría observar cambios en una colección de solo lectura, así que explicaré una de las muchas situaciones válidas; cuando la colección de solo lectura envuelve una colección interna privada que puede cambiar.
Aquí hay uno de esos escenarios:
Suponga que tiene un servicio que permite agregar y eliminar elementos a una colección interna desde fuera del servicio. Ahora suponga que desea exponer los valores de la colección pero no quiere que los consumidores manipulen la colección directamente; por lo que envuelve la colección interna en un ReadOnlyObservableCollection
.
Tenga en cuenta que para envolver la colección interna con ReadOnlyObservableCollection
la colección interna se ve obligado a derivar de ObservableCollection
por el constructor de ReadOnlyObservableCollection
.
Ahora suponga que desea notificar a los consumidores del servicio cuando cambia la colección interna (y, por lo tanto, cuando ReadOnlyObservableCollection
cambia la expuesta ). En lugar de lanzar su propia implementación, solo desea exponer CollectionChanged
el ReadOnlyObservableCollection
. En lugar de obligar al consumidor a hacer una suposición sobre la implementación del ReadOnlyObservableCollection
, simplemente intercambia el ReadOnlyObservableCollection
con este personalizadoObservableReadOnlyCollection
y listo.
Se ObservableReadOnlyCollection
oculta ReadOnlyObservableCollection.CollectionChanged
con los suyos y simplemente pasa todos los eventos modificados de la colección a cualquier controlador de eventos adjunto.