为什么ReadOnlyObservableCollection.CollectionChanged不公开?

为什么ReadOnlyObservableCollection.CollectionChanged受保护而不公开(如相应的ObservableCollection.CollectionChanged )?

如果我无法访问CollectionChanged事件,那么实现INotifyCollectionChanged的集合的用法是什么?

下面是解决scheme: ReadOnlyObservableCollection上的CollectionChanged事件

您必须将集合投射INotifyCollectionChanged

我已经find了如何做到这一点的方法:

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

您只需要通过INotifyCollectionChanged接口显式引用您的集合。

您可能会投票支持Microsoft Connect上描述此问题的错误条目: https : //connect.microsoft.com/VisualStudio/feedback/details/641395/readonlyobservablecollection-t-collectionchanged-event-should-be-public

想要在ReadOnlyObservableCollection上订阅收集已更改的通知肯定有很好的理由。 因此,作为将集合转换为INotifyCollectionChanged的替代方法,如果碰巧是inheritance ReadOnlyObservableCollection ,那么以下提供了一种更简便的语法访问方式来访问CollectionChanged事件:

  public class ReadOnlyObservableCollectionWithCollectionChangeNotifications<T> : ReadOnlyObservableCollection<T> { public ReadOnlyObservableCollectionWithCollectionChangeNotifications(ObservableCollection<T> list) : base(list) { } event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanged2 { add { CollectionChanged += value; } remove { CollectionChanged -= value; } } } 

这对我以前的工作很好。

我知道这个post是老的,但是,人们应该花时间去理解.NET中使用的模式,然后再评论。 只读集合是现有集合上的一个封装,它可以防止消费者直接修改它,查看ReadOnlyCollection ,你会发现它是一个IList<T>的包装,它可能是或者可能不是可变的。 不可变集合是一个不同的问题,并被新的不可变集合库所覆盖

换句话说,只读不是一成不变的!

除此之外, ReadOnlyObservableCollection应该隐含地实现INotifyCollectionChanged

这是谷歌的热门,所以我想我会添加我的解决scheme,以防其他人看这个。

使用上面的信息(关于需要投到INotifyCollectionChanged ),我做了两种扩展方法来注册和注销。

我的解决scheme – 扩展方法

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

IThing.cs

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

使用扩展方法

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

OP的解决scheme

 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; } 

替代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; }