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 ReadOnlyObservableCollectionla colección interna se ve obligado a derivar de ObservableCollectionpor 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 ReadOnlyObservableCollectioncambia la expuesta ). En lugar de lanzar su propia implementación, solo desea exponer CollectionChangedel ReadOnlyObservableCollection. En lugar de obligar al consumidor a hacer una suposición sobre la implementación del ReadOnlyObservableCollection, simplemente intercambia el ReadOnlyObservableCollectioncon este personalizadoObservableReadOnlyCollection y listo.
Se ObservableReadOnlyCollectionoculta ReadOnlyObservableCollection.CollectionChangedcon los suyos y simplemente pasa todos los eventos modificados de la colección a cualquier controlador de eventos adjunto.