在服务上实施 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,它继承自 ObservableCollection 并支持 AddRange 方法,该方法将引发单个 CollectionChanged 事件并将其包装在我拥有的 ReadOnlyObservableCollection 对象中在我的服务中从财产公开提供。效果很好,再次感谢您的回答!

以上是关于在服务上实施 INotifyCollectionChanged 或 INotifyPropertyChanged 可以吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 Exchange ActiveSync 客户端上实施配置

在亚马逊美食评论数据集上实施的朴素贝叶斯问题

yaffs2在am335x上实施

在 Android 12 上实施 STILL_IMAGE_CAPTURE_SECURE

使用 AWS 弹性 beanstalk 负载均衡器在 Rails 上实施 https 连接

需要有关在 GAE 上实施安全支付页面 (HTTPS) 的想法(使用 Stripe)