锁定/解锁 ObservableCollection
我需要允许或阻止修改 ObservableCollection
(或至少是为 WPF 绑定实现 INotifyCollectionChanged
的类型)及其包含的对象在商业规则上。
我可以解决防止修改所包含对象的问题,但不确定如何防止更改集合本身。一种选择是订阅 CollectionChanged
事件并在发生更改后撤消更改,但这并不优雅,并且会给客户端带来令人困惑的契约。
还有哪些其他方法?
I have a requirement to allow or prevent modification to an ObservableCollection<T>
(or at least a type that implements INotifyCollectionChanged
for WPF binding) as well as the objects it contains based on a business rule.
I can solve the issue of preventing modification to contained objects, but am not sure how to approach preventing change to the collection itself. One option would be to subscribe to the CollectionChanged
event and undo changes after they happen, but that is not elegant and represents a confusing contract to the client.
What other approaches are there?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以声明自己的类来实现 ICollection(及其朋友)接口,并使底层集合成为该类的成员。您不想继承,因为有人可能会简单地将对象引用强制转换为基类,而您就失去了保护。
在正常情况下,将所有更新委托给基础类,直到集合被锁定。当它被锁定时,开始抛出断言而不是转发下面的调用。并且所有读取操作始终被委托。
这本质上是装饰器模式
You could declare your own class that implements ICollection (and friends) interfaces and have the underlying collection be a member of that class. You wouldn't want to inherit because then someone might simply cast object reference to the base class and you've lost your protection.
Under normal conditions, delegate all updates to the underlying class until the collection becomes locked. When it's locked, start throwing assertions instead of forwarding the calls below. And all read operations are always delegated.
This would essentially be a decorator pattern
您可以创建自己的集合类型并继承
ObservableCollection
。这是一个潜在的选择吗?You could create your own collection type and inherit
ObservableCollection<T>
. Is that a potential option?我采纳了包装
ObservableCollection
的建议。这是我的实现,以防它对任何人有帮助。此方法的一个缺点是所包含对象上的 ILockable.Locked 是公共的,因此可以解锁各个所包含对象,如:wrappedCollection.Item(0).Locked = false;
。另外,我还没有实现索引器,因为 EF 索引器上的阻塞< /a>.如果您不使用 EF,请随意添加索引器。实现
ILockable
的包含对象仍必须强制执行Locked
属性,例如:I went with the suggestions to wrap an
ObservableCollection<T>
. Here's my implementation in case it helps anyone. One drawback of this approach is that ILockable.Locked on the contained object is public, so individual contained objects could be unlocked like:wrappedCollection.Item(0).Locked = false;
. Also, I have not implemented an indexer because EF chokes on indexers. Feel free to add an indexer if you're not using EF.The contained object that implements
ILockable
must still enforce theLocked
property, e.g. something like this: