简体   繁体   中英

ObservableCollection<> CollectionChanged Not Firing

I have a datagrid in a WPF app that is bound to an ObservableCollection like so

<DataGrid ItemsSource="{Binding Spring.SpringData, Mode=OneWay}" />

My data displays fine, and I can edit the data in my grid, but it does not fire the PublishSpringChange event when I manually edit the data in the grid. The underlying data changes, but the event does not fire, what am I missing?

With a model of Spring that has the following

public class Spring : INotifyPropertyChanged
{

    private ObservableCollection<SpringData> _SpringData;

    public ObservableCollection<SpringData> SpringData
    {
        get { return _SpringData; }
    }

     public Spring()
    {
        ....

        _SpringData = new ObservableCollection<SpringData>();
        SpringData.CollectionChanged += PublishSpringChange;

       ...
    }
    private void PublishSpringChange(object sender, NotifyCollectionChangedEventArgs e)
    {
        // Code that does not run!
    }
}

with a SpringData class of

public class SpringData: BindableBase
{
    private double _force;
    private double _displacement;

    public SpringData(double displacement, double force)
    {
        Displacement = displacement;
        Force = force;
    }

    public double Displacement
    {
        get { return _displacement; }
        set { SetProperty(ref _displacement, value); }
    }

    public double Force
    {
        get { return _force; }
        set { SetProperty(ref _force, value); }
    }
}

INotifyCollectionChanged only fires when you actually modify the collection. This is when you Add, Remove, Move, Replace or Reset items in the collection. It will not fire when one of the properties in a SpringData object is changed.

In order to listen to changes for a SpringData object, assuming it implements INotifyPropertyChanged , you will need to hook up listeners to the PropertyChanged event of each of the items.

Its quite useful to have a single handler for all properties changing sometimes. Here's how you can do it.

Handle CollectionChanged as you are above:

_SpringData = new ObservableCollection<SpringData>();
SpringData.CollectionChanged += PublishSpringChange;

Now for all added and removed objects to the collection add a handler to PropertyChanged:

private void PublishSpringChange(object sender, NotifyCollectionChangedEventArgs e)
{
    foreach (INotifyPropertyChanged added in e.NewItems)
    {
        added.PropertyChanged += SpringDataOnPropertyChanged;
    }

    foreach (INotifyPropertyChanged removed in e.OldItems)
    {
        removed.PropertyChanged -= SpringDataOnPropertyChanged;
    }
}

private SpringDataOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
    //your code here
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM