【问题标题】:Check if object has PropertyChanged Event attached to it检查对象是否附加了 PropertyChanged 事件
【发布时间】:2018-02-23 17:39:19
【问题描述】:

当我的窗口被加载时,我有一个 ObservableCollection 被填充并且一个 PropertyChanged 事件被添加到每个项目。但是,在初始加载项目之后可以将其添加到 ObservableCollection。我希望能够侦听 ObservableCollection 上的集合更改,检查是否添加了一个项目,然后如果添加了一个事件侦听器。

为此,我希望能够检查是否为每个单独的项目定义了 PropertyChanged 属性,如果没有,则附加一个 PropertyChanged 事件。

这是我的代码:

items.CollectionChanged += (object sender, NotifyCollectionChangedEventArgs e) =>
{
    foreach (var item in items.Where(o => o.PropertyChanged == null)) //error here
    {
        item.PropertyChanged += Item_PropertyChanged;
    }
};

但是,我收到一个编译错误:

“ModelBase.PropertyChanged”事件只能出现在 += 或 -= 的左侧

任何想法如何检查一个对象是否定义了其 PropertyChanged 属性事件?

【问题讨论】:

  • 您说的是“已定义”,但您的意思可能是“已分配”。请澄清,请参阅下面的答案。

标签: c# wpf


【解决方案1】:

您可以遍历 NotifyCollectionChangedEventArgs 的 OldItemsNewItems 属性。

对于System.Collections.ObjectModel.ObservableCollection,这适用于e.Action 的所有值,NotifyCollectionChangedAction.Reset 除外。

items.CollectionChanged += (s, e) =>
{
    if (e.OldItems != null)
    {
        foreach (var item in e.OldItems.OfType<INotifyPropertyChanged>())
        {
            item.PropertyChanged -= Item_PropertyChanged;
        }
    }
    if (e.NewItems != null)
    {
        foreach (var item in e.NewItems.OfType<INotifyPropertyChanged>())
        {
            item.PropertyChanged += Item_PropertyChanged;
        }
    }
};

【讨论】:

  • 谢谢,给了 Derrick 接受的答案,因为他是第一个。
【解决方案2】:

大概您正试图避免多次订阅PropertyChanged 事件。您可以使用NotifyCollectionChangedEventArgsNewItems 属性来执行此操作。

if (e.NewItems != null && e.NewItems.Count != 0)
{
    foreach (INotifyPropertyChanged item in e.NewItems)
        item.PropertyChanged += OnItemPropertyChanged;
}

您也可以使用OldItems 取消订阅。

if (e.OldItems != null && e.OldItems.Count != 0)
{
    foreach (INotifyPropertyChanged item in e.OldItems)
        item.PropertyChanged -= OnItemPropertyChanged;
}

如果您的集合中还有未实现 INotifyPropertyChanged 的项目,您可以将其与 Jonathan Allen 的答案结合起来过滤列表。

【讨论】:

    【解决方案3】:
    items.CollectionChanged += (object sender, NotifyCollectionChangedEventArgs e) =>
    {
        foreach (var item in items.OfType<INotifyPropertyChanged>()) //filter the list
        {
            item.PropertyChanged += Item_PropertyChanged;
        }
    };
    

    【讨论】:

      【解决方案4】:

      检查类是否实现INotifyPropertyChanged 接口。 在每个要实现 PropertyChange 方法的类中使用它。

      【讨论】:

        猜你喜欢
        • 2018-03-24
        • 2018-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-06
        • 1970-01-01
        • 1970-01-01
        • 2019-09-28
        相关资源
        最近更新 更多