知道集合中的变量是否已更改

时间:2013-03-10 14:01:42

标签: c# wpf observablecollection inotify

我的ObservableCollection包含类:MyClass

    private ObservableCollection<MyClass> _myCollection;

    public ObservableCollection<MyClass> MyCollection
    {
        get { return _myCollection; }
        set
        {
            _myCollection= value;
        }
    }

我想在C#代码中知道,如果集合发生了变化。

所以我注册了集合的事件:CollectionChanged它在我添加/删除记录时有效。

此处注册:

   MyCollection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(MyCollection_CollectionChanged);

我想让这个事件在类中发生变化时起作用(或注册另一个事件)。

起初我想要注册课程的PropertyChanged事件,然后通过它来运行事件CollectionChanged - 这似乎很复杂且没必要。

我认为,由于binding的{​​{1}}可以识别类中的更改以及集合本身的更改,因此可以通过代码执行此操作。

我错了吗? (更确切的问题是:有没有人知道这种方法?)

2 个答案:

答案 0 :(得分:4)

正如Nik所说,PropertyChanged活动是正确的方法。但我认为你不应该手动调用CollectionChanged事件或以这种方式“强制”它。您应该在事件中重构代码,如下所示:

public class MyClass : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; OnPropertyChanged("Name"); }
    }

    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class Class1
{
    private ObservableCollection<MyClass> _myCollection = new ObservableCollection<MyClass>();
    public ObservableCollection<MyClass> MyCollection
    {
        get { return _myCollection; }
        // set { _myCollection = value; } // see Clemens' comment
    }

    public Class1()
    {
        // hook up this event at the appropriate place, does not have to be the ctor
        MyCollection.CollectionChanged += MyCollection_CollectionChanged;

        MyClass m = new MyClass() { Name = "Example" };

        MyCollection.Add(m); // calls ExecuteOnAnyChangeOfCollection
        m.Name = "ChangedValue"; // calls ExecuteOnAnyChangeOfCollection
    }

    void MyCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems != null)
        {
            foreach (MyClass item in e.NewItems)
                item.PropertyChanged += MyClass_PropertyChanged;
        }

        if (e.OldItems != null)
        {
            foreach (MyClass item in e.OldItems)
                item.PropertyChanged -= MyClass_PropertyChanged;
        }

        ExecuteOnAnyChangeOfCollection();
    }

    void MyClass_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        ExecuteOnAnyChangeOfCollection();
    }

    private void ExecuteOnAnyChangeOfCollection()
    {
        // handling code ...
        System.Windows.MessageBox.Show("Collection has changed.");
    }

答案 1 :(得分:2)

你是对的。从MyClass获取通知的最简单方法是订阅PropertyChanged事件(如果MyClass实现了INotifyPropertyChanged)。

然后要更新UI,您可以删除然后添加更改的项目(这将自动提升CollectionChanged)或手动调用带有Reset参数的CollectionChanged事件(您需要扩展ObservableCollection类来执行此操作,但这是一项相当容易的任务)。