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

本文关键字:项目 是否 ObservableCollection 何检测 检测 | 更新日期: 2023-09-27 18:21:19

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

我现在想做的是,在更新集合中的任何对象时,甚至可以触发某种绑定,或者与集合绑定,如果更新了任何产品,则会返回true/false depedant。

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

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

此外,如果我在我的Product类上实现了这个接口,我不知道我的UI如何监控集合中的每一个产品——或者可以吗?

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

  • Product类中实现INotifyPropertyChanged,并为每个属性发出通知
  • 在视图模型中实现INotifyPropertyChanged
  • 将属性IsDirty添加到ViewModel中(通过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属性绑定到它

只需使用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.
}

逻辑需要进入Model(Product类)。一个干净的方法是在模型中公开IsDirty属性(由字段支持)。

您的ViewModel将具有一个命令绑定,CanSave将检查内部集合,如果集合IsDirty=true中的任何项为true,则返回true。

我认为为集合中的每个对象订阅PropertyChanged事件并触发此事件(例如,在对象的setter中)是可行的。

然而,我认为你不需要做所有这些来判断网格中的一个单元格是否发生了变化。我认为你可以做一些像他们在这里做的事情:

http://social.msdn.microsoft.com/Forums/en/wpf/thread/81131225-90fb-40f9-a311-066952c7bc43