C# 如何检测 ObservableCollection 中的项目是否已更改
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8986105/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to detect if an item in my ObservableCollection has changed
提问by Remotec
I have a datagrid which is bound to ObservableCollection<Product>. When the grid is updated this automatically updates the Product object in my collection.
我有一个绑定到ObservableCollection<Product>. 当网格更新时,这会自动更新我集合中的 Product 对象。
What I want to do now is to have some sort of even that is triggered when any object in the collection is updated -or- some sort of binding to the collection that will return true/false depedant on if any Product has been updated.
我现在想要做的是在更新集合中的任何对象时触发某种甚至触发 - 或者 - 某种绑定到集合,如果任何产品已更新,将返回真/假依赖。
The overall objective is to have a save button on my main window that is disabled if no changes have been made to my collection and enabled if changes have been made.
总体目标是在我的主窗口上有一个保存按钮,如果没有对我的收藏进行任何更改,则禁用该按钮,如果进行了更改,则启用该按钮。
I have read into INotifyPropertyChangebut I dont see how I can use this to monitor changes on a whole collection.
我已阅读,INotifyPropertyChange但我不知道如何使用它来监视整个集合的更改。
Additionally, if I implement this interface on my Product class I dont see how my UI can monitor every product in the collection - or can it?
此外,如果我在我的 Product 类上实现这个接口,我看不到我的 UI 如何监控集合中的每个产品 - 或者可以吗?
回答by Manish Basantani
The logic needs to go in your Model (Product class).
A clean approach would be to expose IsDirtyproperty (backed by field) in your model.
逻辑需要进入您的模型(产品类)。一种干净的方法是IsDirty在模型中公开属性(由字段支持)。
And your ViewModel would have a Command binding with CanSavechecking the internal collection, and return true if Any of the item in collection IsDirty=true.
并且您的 ViewModel 将具有CanSave检查内部集合的 Command 绑定,如果集合中的任何项目返回 true IsDirty=true。
回答by Orkun Ozen
I think subscribing to the PropertyChangedevent for each of the objects in your collection and firing this event, for example, in the setter of your objects can work.
我认为PropertyChanged为您的集合中的每个对象订阅事件并触发此事件,例如,在您的对象的 setter 中可以工作。
However, I think you don't need to do all this to figure out if a cell is changed in your grid. I think you can do something like what they do here instead:
但是,我认为您无需执行所有这些操作即可确定网格中的单元格是否已更改。我认为你可以做一些类似于他们在这里做的事情:
http://social.msdn.microsoft.com/Forums/en/wpf/thread/81131225-90fb-40f9-a311-066952c7bc43
http://social.msdn.microsoft.com/Forums/en/wpf/thread/81131225-90fb-40f9-a311-066952c7bc43
回答by Skalli
Just use the ObservableCollection. It has an event called CollectionChanged. If you register it, you can do what you want. Example:
只需使用 ObservableCollection。它有一个名为CollectionChanged的事件。如果你注册它,你可以做你想做的。例子:
ObservableCollection<string> strings = new ObservableCollection<string>();
strings.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(changed);
strings.Add("Hello");
strings[0] = "HelloHello";
And:
和:
private void changed(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args)
{
//You get notified here two times.
}
回答by chopikadze
- Implement
INotifyPropertyChangedin yourProductclass with notification for every property. - Implement
INotifyPropertyChangedin your viewmodel. - Add property
IsDirtyto your ViewModel (with notification throughINotifyPropertyChanged. In your viewmodel, subscribe to
CollectionChangedpublic 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; }Now you can bind to
IsDirtyproperty of your viewmodel, for example, you can bindButton.IsEnabledproperty directly to it.
INotifyPropertyChanged在您的Product班级中实施每个属性的通知。INotifyPropertyChanged在您的视图模型中实现。- 将属性添加
IsDirty到您的 ViewModel(通过INotifyPropertyChanged. 在您的视图模型中,订阅
CollectionChangedpublic 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属性直接绑定到它。

