如何检测我的ObservableCollection中的项是否已更改?

24

我有一个数据表格,它绑定了 ObservableCollection<Product>。当更新数据表格时,它会自动更新我的集合中的 Product 对象。

现在我想要做的是,当集合中的任何对象更新时触发某种事件 - 或者绑定到该集合的一些内容,这将根据是否有任何 Product 被更新返回 true/false。

总体目标是在我的主窗口上有一个保存按钮,如果没有对集合进行更改,则该按钮被禁用,如果已经进行了更改,则该按钮被启用。

我读过 INotifyPropertyChange,但我不知道如何使用它来监视整个集合的更改。

此外,如果我在我的 Product 类上实现此接口,我不知道我的 UI 是否可以监视集合中的每个产品 - 这是可能的吗?


1
请点击这里查看:https://dev59.com/uXM_5IYBdhLWcg3wUxZB - SwDevMan81
1
我正在使用这个链接: https://dev59.com/-2oy5IYBdhLWcg3wiecp - Noich
4个回答

22
  • 在您的Product类中实现INotifyPropertyChanged,并为每个属性提供通知。
  • 在您的视图模型中实现INotifyPropertyChanged
  • 向您的视图模型添加IsDirty属性(通过INotifyPropertyChanged进行通知)。
  • 在您的视图模型中订阅CollectionChanged

public YourViewModel()
{
    ...
    YourCollection.CollectionChanged += YourCollection_CollectionChanged; 
    ...
}

private void YourCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args)
{
    if (args.OldItems != null)
        foreach(var oldItem in args.OldItems)
            oldItem.PropertyChanged -= YourItem_PropertyChanged;

    if (args.NewItems != null)
        foreach(var newItem in args.NewItems)
            newItem.PropertyChanged += YourItem_PropertyChanged;
}

private void Youritem_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs args)
{
    IsDirty = true;
}
现在你可以绑定到你的视图模型的IsDirty属性,例如,你可以直接将Button.IsEnabled属性与其绑定。

这应该被设置为答案。 - Oystein
1
为了使这段代码正常工作,应将 foreach(var oldItem in args.OldItems) 更改为 foreach(Product oldItem in args.OldItems),并将 foreach(var newItem in args.NewItems) 更改为 foreach(Product newItem in args.NewItems)。此外,应接受此答案。 - Junior

2

只需使用ObservableCollection。 它有一个名为CollectionChanged的事件。如果您注册它,您可以做您想要的事情。例如:

ObservableCollection<string> strings = new ObservableCollection<string>();
strings.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(changed);
strings.Add("Hello");
strings[0] = "HelloHello";

同时:

private void changed(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args)
{
    //You get notified here two times.
}

29
尽管MSDN文档这样写,但是当集合中的对象发生更改时,CollectionChanged不会被调用,只有在集合本身添加或删除对象时才会被调用。 - Stealth Rabbi

1
逻辑应该放在您的模型(Product 类)中。 一种干净的方法是在您的模型中公开由字段支持的 IsDirty 属性。
而您的 ViewModel 将与 CanSave 绑定命令,检查内部集合,并且如果集合中的任何项 IsDirty=true,则返回 true。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接