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

C# 知道集合中的变量是否已更改,c#,wpf,observablecollection,inotify,C#,Wpf,Observablecollection,Inotify,我有一个包含class:MyClass的ObservableCollection private ObservableCollection<MyClass> _myCollection; public ObservableCollection<MyClass> MyCollection { get { return _myCollection; } set { _myColl

我有一个包含class:
MyClass
ObservableCollection

    private ObservableCollection<MyClass> _myCollection;

    public ObservableCollection<MyClass> MyCollection
    {
        get { return _myCollection; }
        set
        {
            _myCollection= value;
        }
    }
我希望在类中发生更改时,此事件能够正常工作(或注册另一个事件)

起初我想注册类的
PropertyChanged
事件,然后通过它运行event
CollectionChanged
——这看起来很复杂,也不必要

我认为,由于
wpf
binding
可以识别类中的更改和集合本身的更改,因此可以通过代码来实现这一点


我错了吗?(更准确的问题是:有人知道怎么做吗?

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


然后,要更新UI,您可以删除并添加更改的项(这将自动引发CollectionChanged),或者手动调用带有重置参数的CollectionChanged事件(您需要扩展ObservableCollection类才能完成此操作,但这是一项相当简单的任务)。

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


然后,要更新UI,您可以删除并添加更改的项(这将自动增加CollectionChanged),或者手动调用带有重置参数的CollectionChanged事件(您需要扩展ObservableCollection类来完成此操作,但这是一项相当简单的任务)。

正如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.");
    }
公共类MyClass:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
私有字符串\u名称;
公共字符串名
{
获取{return\u name;}
设置{u name=value;OnPropertyChanged(“name”);}
}
私有void OnPropertyChanged(字符串propertyName)
{
if(PropertyChanged!=null)
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
公共班级1
{
私有ObservableCollection_myCollection=新ObservableCollection();
公共可观测集合MyCollection
{
获取{return\u myCollection;}
//设置{u myCollection=value;}//参见克莱门斯的评论
}
公共类别1()
{
//在适当的地方连接此事件,不必是ctor
MyCollection.CollectionChanged+=MyCollection\u CollectionChanged;
MyClass m=新的MyClass(){Name=“Example”};
MyCollection.Add(m);//调用ExecuteOnAnyChangeOfCollection
m、 Name=“ChangedValue”;//调用ExecuteOnAnyChangeOfCollection
}
void MyCollection\u CollectionChanged(对象发送方,NotifyCollectionChangedEventArgs e)
{
如果(如NewItems!=null)
{
foreach(e.NewItems中的MyClass项)
item.PropertyChanged+=MyClass\u PropertyChanged;
}
如果(例如,OldItems!=null)
{
foreach(e.OldItems中的MyClass项)
item.PropertyChanged-=MyClass\u PropertyChanged;
}
执行集合()的任何更改;
}
void MyClass_PropertyChanged(对象发送方,PropertyChangedEventArgs e)
{
执行集合()的任何更改;
}
私有void ExecuteOnAnyChangeOfCollection()的执行
{
//处理代码。。。
System.Windows.MessageBox.Show(“集合已更改”);
}

正如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.");
    }
公共类MyClass:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
私有字符串\u名称;
公共字符串名
{
获取{return\u name;}
设置{u name=value;OnPropertyChanged(“name”);}
}
私有void OnPropertyChanged(字符串propertyName)
{
if(PropertyChanged!=null)
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
公共班级1
{
私有ObservableCollection_myCollection=新ObservableCollection();
公共可观测集合MyCollection
{
获取{return\u myCollection;}
//设置{u myCollection=value;}//参见克莱门斯的评论
}
公共类别1()
{
//在适当的地方连接此事件,不必是ctor
MyCollection.CollectionChanged+=MyCollection\u CollectionChanged;
MyClass m=新的MyClass(){Name=“Example”};
MyCollection.Add(m);//调用ExecuteOnAnyChangeOfCollection
m、 Name=“ChangedValue”;//调用ExecuteOnAnyChangeOfCollection
}
void MyCollection\u CollectionChanged(对象发送方,NotifyCollectionChangedEventArgs e)
{
如果(如NewItems!=null)
{
foreach(e.NewItems中的MyClass项)
item.PropertyChanged+=MyClass\u PropertyChanged;
}
如果(例如,OldItems!=null)
{
foreach(e.OldItems中的MyClass项)
item.PropertyChanged-=MyClass\u PropertyChanged;
}
执行集合()的任何更改;
}
void MyClass_PropertyChanged(对象发送方,PropertyChangedEventArgs e)
{
执行集合()的任何更改;
}
私有void ExecuteOnAnyChangeOfCollection()的执行
{
//处理代码。。。
System.Windows.MessageBox.Show(“集合已更改”);
}

+1,但您必须在
MyCollection
属性设置程序中添加/删除
MyCollection\u CollectionChanged
处理程序。@Clemens:我可以看到您在说什么,而不是在做什么。@Clemens: