1

假设我有一个服务,它的接口是这样的:

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 上的服务,将视图直接绑定到服务实例?

非常感谢您对此的评论!谢谢!

4

1 回答 1

2

INotifyCollectionChanged 将通知您(或视图)有关添加/删除的信息,但不会通知您(或视图)属性的更改(在更新的情况下)。IPropertyChanged 可以通知视图某个属性(对于实例 ProxyList)已更改(但不能通知此集合中项目的属性更改)。

此外,我认为您的服务不需要 INotifyCollectionChanged 接口。只需对 ProxyList 使用适当的实现,例如:

public interface IProxyRotator : INotifyPropertyChanged
{
    // ... omited for brevity    
    ObservableCollection<Proxy> ProxyList { get; }
}
于 2012-08-23T02:10:48.483 回答