How to detect property changes in items contained in ObservableCollection<T> [duplicate]

对着背影说爱祢 提交于 2019-12-13 07:17:38

问题


 private ObservableCollection<Employee> models = new ObservableCollection<Employee>();

My model has 2 fields (Name and a boolean field called activeDuty)

In my constructor, I

 this.models.CollectionChanged += this.OnCollectionChanged;


void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)

I've never used an ObservableCollection, could someone tell me how I would detect if the activeDuty field was modified?(I did some digging and saw many posts about OnCollectionChanged and OnItemPropertyChanged but didnt understand the difference or why one is preferred over another


回答1:


ObservableCollection.CollectionChanged is raised when an item is added to, or removed from, the collection. ObservableCollection also implements INotifyPropertyChanged, only to raise notifications for changes of its own personal properties -- and so will also raise a PropertyChanged event for its Count property when an item is added or removed (you've got zero reason to care about that right now, but we may as well toss it out there for what it's worth).

So: Your ObservableCollection of Employee won't raise any events when one of its containees has a property change, regardless of whether or not the containee implements INotifyPropertyChanged. The containee should implement INotifyPropertyChanged itself, and raise events when its own property values change -- but an ObservableCollection containing it won't listen for those events. We don't need to notify absolutely everybody about absolutely everything.

But you do need to know when activeDuty changes. Easy.

When you create new Employee instances, you could handle their PropertyChanged events with your OnItemPropertyChanged handler:

//  Fred's not what you'd call active.
var fred = new Employee { Name = "Fred", activeDuty = false };

fred.PropertyChanged += OnItemPropertyChanged;

models.Add(fred);

If Employee implements INotifyPropertyChanged correctly, any detectable increase in Fred's activity level will be perceived immediately in OnItemPropertyChanged. The object sender parameter will be Fred, and e.PropertyName will be the string "activeDuty".

public class Employee : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private bool _activeDuty = false;
    public bool activeDuty {
        get { return _activeDuty; }
        set {
            _activeDuty = value;
            PropertyChanged?.Invoke(this, 
                new PropertyChangedEventArgs(nameof(activeDuty)));
        }
    }

    //  Name implemented similarly -- either that, or give it a protected 
    //  setter and initialize it in the constructor, to prevent accidents.
}

I don't think you need to be handling models.CollectionChanged unless random other viewmodels could be adding to it. If they could be, then that's a very handy place to put PropertyChanged handlers on new Employees.



来源:https://stackoverflow.com/questions/36873983/how-to-detect-property-changes-in-items-contained-in-observablecollectiont

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!