wpf ObservableCollection<> CollectionChanged 未触发

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36507584/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:45:02  来源:igfitidea点击:

ObservableCollection<> CollectionChanged Not Firing

c#wpfmvvm

提问by PlTaylor

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

我在 WPF 应用程序中有一个数据网格,它像这样绑定到 ObservableCollection

<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?

我的数据显示正常,我可以编辑网格中的数据,但是当我手动编辑网格中的数据时,它不会触发 PublishSpringChange 事件。底层数据发生变化,但事件没有触发,我错过了什么?

With a model of Spring that has the following

使用具有以下功能的 Spring 模型

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

使用 SpringData 类

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

回答by Cheesebaron

INotifyCollectionChangedonly 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 SpringDataobject is changed.

INotifyCollectionChanged仅在您实际修改集合时触发。这是您在集合中添加、删除、移动、替换或重置项目的时间。当SpringData对象中的属性之一发生更改时,它不会触发。

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

为了侦听 SpringData 对象的更改,假设它实现了INotifyPropertyChanged,您需要将侦听器连接到PropertyChanged每个项目的事件。

回答by Tim Rutter

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:

像上面一样处理 CollectionChanged:

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

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

现在,为集合中所有添加和删除的对象添加一个处理程序到 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
}