【问题标题】:ObservableCollection<> CollectionChanged Not FiringObservableCollection<> CollectionChanged 未触发
【发布时间】:2016-04-08 19:16:32
【问题描述】:

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

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

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

使用具有以下特性的 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!
    }
}

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

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

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

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

    【讨论】:

    • 有没有办法从 SpringData 的事件中触发 INotifyCollectionChanged?
    • 您为什么要这样做有什么特殊原因吗?
    • 与让每个项目单独处理事件相比,仅从项目通知集合更改事件使我的代码更简单、更健壮。
    【解决方案2】:

    有时为所有属性更改使用单个处理程序非常有用。以下是你可以做到的。

    像上面一样处理 CollectionChanged:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 2013-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多