在服务上实施 INotifyCollectionChanged 或 INotifyPropertyChanged 可以吗?
Posted
技术标签:
【中文标题】在服务上实施 INotifyCollectionChanged 或 INotifyPropertyChanged 可以吗?【英文标题】:Implement INotifyCollectionChanged on a service or INotifyPropertyChanged is fine? 【发布时间】:2012-08-18 11:44:38 【问题描述】:假设我有一个服务,它的接口是这样的:
public interface IProxyRotator
ProxyRotationMode RotationMode get; set;
void Add(Proxy proxy);
void AddRange(IEnumerable<Proxy> proxies);
bool Remove(Proxy proxy);
void Clear();
Proxy Peek();
问题在于我应该如何将服务中包含的代理绑定到视图。
我正在做的方式是在服务接口上创建一个 ProxyList 数组并通知对该属性的更改。像这样:
public interface IProxyRotator : INotifyPropertyChanged
// ... omited for brevity
Proxy[] ProxyList get;
在 ViewModel 上,我有另一个用于代理的数组属性。当 ViewModel 被实例化时,它会订阅 IProxyRotator PropertyChanged 事件并“转发”该事件,以便 View 可以实际看到代理数组已更改。像这样:
public class ViewModel : INotifyPropertyChanged
public ViewModel(IProxyRotator proxyRotator)
this.proxyRotator = proxyRotator;
this.proxyRotator.PropertyChanged += (sender, e) =>
if (e.PropertyName == "ProxyList")
this.RaisePropertyChanged("ProxyList");
public Proxy[] ProxyList
get return this.proxyRotator.ProxyList;
private IProxyRotator proxyRotator;
问题在于,必须拦截服务 PropertyChanged 事件并转发它的开销让我感到困惑,感觉……错了。当我不得不依赖实现 INotifyPropertyChanged 的众多不同对象而不是正确实现 INotifyCollectionChanged 时,这也是一个主要缺点。 我是否应该考虑在 IProxyRotator 服务上实现 INotifyCollectionChanged(我知道这也意味着实现 IEnumerable)并简单地引用 ViewModel 上的服务,将视图直接绑定到服务实例?
非常感谢您在这方面的 cmets! 谢谢!
【问题讨论】:
【参考方案1】:INotifyCollectionChanged 将通知您(或视图)有关添加/删除的信息,但不会通知您(或视图)属性的更改(在更新的情况下)。 IPropertyChanged 可以通知视图某个属性(对于实例 ProxyList)已更改(但不能通知此集合中项目的属性的更改)。
另外,我认为您的服务不需要 INotifyCollectionChanged 接口。只需对 ProxyList 使用适当的实现,例如:
public interface IProxyRotator : INotifyPropertyChanged
// ... omited for brevity
ObservableCollection<Proxy> ProxyList get;
【讨论】:
感谢您的回答!当我用餐时,我正在考虑将 add/remove/clear/addrange 移动到特定属性,就像您所做的那样,而不是重新实现所有方法。当线程安全成为问题时,问题就出现了,但我认为我可以锁定在 Get 访问器内部以返回对 ObservableCollection 实例的引用。谢谢老哥! 我设计了一个 ObservableList以上是关于在服务上实施 INotifyCollectionChanged 或 INotifyPropertyChanged 可以吗?的主要内容,如果未能解决你的问题,请参考以下文章
在 Exchange ActiveSync 客户端上实施配置
在 Android 12 上实施 STILL_IMAGE_CAPTURE_SECURE