[c#] Why is ReadOnlyObservableCollection.CollectionChanged not public?


Answers

I've found a way for you of how to do this:

ObservableCollection<string> obsCollection = new ObservableCollection<string>();
INotifyCollectionChanged collection = new ReadOnlyObservableCollection<string>(obsCollection);
collection.CollectionChanged += new NotifyCollectionChangedEventHandler(collection_CollectionChanged);

You just need to refer to your collection explicitly by INotifyCollectionChanged interface.

Question

Why is ReadOnlyObservableCollection.CollectionChanged protected and not public (as the corresponding ObservableCollection.CollectionChanged is)?

What is the use of a collection implementing INotifyCollectionChanged if I can't access the CollectionChanged event?




I know this post is old, however, people should take their time to understand the patterns used in .NET before commenting. A read only collection is a wrapper on an existing collection that prevents consumers from modifying it directly, look at ReadOnlyCollection and you will see that it is a wrapper on a IList<T> which may or may not be mutable. Immutable collections are a different matter and are covered by the new immutable collections library

In other words, read only is not the same as immutable!!!!

That aside, ReadOnlyObservableCollection should implicitly implement INotifyCollectionChanged.




This was top hit on google so I figured I'd add my solution in case other people look this up.

Using the information above (about needing to cast to INotifyCollectionChanged), I made two extension methods to register and unregister.

My Solution - Extension Methods

public static void RegisterCollectionChanged(this INotifyCollectionChanged collection, NotifyCollectionChangedEventHandler handler)
{
    collection.CollectionChanged += handler;
}

public static void UnregisterCollectionChanged(this INotifyCollectionChanged collection, NotifyCollectionChangedEventHandler handler)
{
    collection.CollectionChanged -= handler;
}

Example

IThing.cs

public interface IThing
{
    string Name { get; }
    ReadOnlyObservableCollection<int> Values { get; }
}

Using the Extension Methods

public void AddThing(IThing thing)
{
    //...
    thing.Values.RegisterCollectionChanged(this.HandleThingCollectionChanged);
}

public void RemoveThing(IThing thing)
{
    //...
    thing.Values.UnregisterCollectionChanged(this.HandleThingCollectionChanged);
}

OP's Solution

public void AddThing(IThing thing)
{
    //...
    INotifyCollectionChanged thingCollection = thing.Values;
    thingCollection.CollectionChanged += this.HandleThingCollectionChanged;
}

public void RemoveThing(IThing thing)
{
    //...
    INotifyCollectionChanged thingCollection = thing.Values;
    thingCollection.CollectionChanged -= this.HandleThingCollectionChanged;
}

Alternative 2

public void AddThing(IThing thing)
{
    //...
    (thing.Values as INotifyCollectionChanged).CollectionChanged += this.HandleThingCollectionChanged;
}

public void RemoveThing(IThing thing)
{
    //...
    (thing.Values as INotifyCollectionChanged).CollectionChanged -= this.HandleThingCollectionChanged;
}



Links