0

我有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可以wpf识别类的变化和集合本身的变化,那么可以通过代码来做到这一点。

我错了吗?(更准确的问题是:有谁知道解决这个问题的方法吗?)

4

2 回答 2

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.");
    }
于 2013-03-10T15:33:00.080 回答
2

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

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

于 2013-03-10T14:11:43.907 回答