为什么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; }