Frage

I have ObservableCollection that contains class: MyClass.

    private ObservableCollection<MyClass> _myCollection;

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

I want to know in C# code, if the collection changed.

So I registered to event of the collection: CollectionChanged it works when I add / delete a record.

Here the registred:

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

I want this event to work (or register another event) when something changes within the class.

At first I thought to register for PropertyChanged event of the class, then through it run the event CollectionChanged - it seems complicated and unnecessary.

I think that as the binding of wpf can recognize a change in the class and a change in the collection itself, then it is possible to do this through code.

Am I wrong? (More precise question is: Does anyone know a way to this?)

War es hilfreich?

Lösung

As already stated by Nik, the PropertyChanged event is the right way to go. But I think you shouldn't invoke the CollectionChanged event manually or "force" it that way. You should just refactor your code inside the event, like this:

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.");
    }

Andere Tipps

You are right. The easiest way to get notifications from MyClass is to subscribe to PropertyChanged event (if MyClass implements INotifyPropertyChanged).

Then to update UI you can either Remove and then Add the changed item (this will rise CollectionChanged automatically) or invoke CollectionChanged event with Reset parameter manually (you will need to extend ObservableCollection class to do so, but thats a fairly easy task).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top