【问题标题】:Why subscribed event to CollectionChanged is not being fired? [duplicate]为什么没有触发 CollectionChanged 的​​订阅事件? [复制]
【发布时间】:2019-09-10 00:50:31
【问题描述】:

我正在使用这个 https://stackoverflow.com/a/5256827 插入类,它是 ObservableCollection 的子类,当集合中的项目发生更改时会发出通知。它可以引发事件。

public sealed class TrulyObservableCollection<T> : ObservableCollection<T>
    where T : INotifyPropertyChanged
{
    public TrulyObservableCollection()
    {
        CollectionChanged += FullObservableCollectionCollectionChanged;
    }

    public TrulyObservableCollection(IEnumerable<T> pItems) : this()
    {
        foreach (var item in pItems)
        {
            this.Add(item);
        }
    }

    private void FullObservableCollectionCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems != null)
        {
            foreach (Object item in e.NewItems)
            {
                ((INotifyPropertyChanged)item).PropertyChanged += ItemPropertyChanged;
            }
        }
        if (e.OldItems != null)
        {
            foreach (Object item in e.OldItems)
            {
                ((INotifyPropertyChanged)item).PropertyChanged -= ItemPropertyChanged;
            }
        }
    }

    private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
    {    
// Here when an item changes it works.
 System.Windows.MessageBox.Show("ItemPropertyChanged fired!");        
        NotifyCollectionChangedEventArgs args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, sender, sender, IndexOf((T)sender));
        OnCollectionChanged(args);
    }
}

当一个项目发生变化时 ItemPropertyChanged 被触发,但是当我使用集合并将函数订阅到 OnCollectionChanged 时,订阅的事件不会被触发。

public TrulyObservableCollection<ModelObj> LoadingDataCollection;




public Loading()
{            
    InitializeComponent();
    LoadingDataCollection = new TrulyObservableCollection<ModelObj>();
    LoadingDataCollection.CollectionChanged += ContentCollectionChanged;
    // Fill the collection
    LoadingDataCollection = HelperClass.LoadItems();
}


public void ContentCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    // Never reaches here.
    System.Windows.MessageBox.Show("ContentCollectionChanged fired!");

    if (e.Action == NotifyCollectionChangedAction.Remove)
    {
        foreach (ModelObj item in e.OldItems)
        {
            //Removed items
            item.PropertyChanged -= EntityViewModelPropertyChanged;
        }
    }
    else if (e.Action == NotifyCollectionChangedAction.Add)
    {
        foreach (ModelObj item in e.NewItems)
        {
            //Added items
            item.PropertyChanged += EntityViewModelPropertyChanged;
        }
    }
}

public void EntityViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    //Also Never reaches here. Here I want to get the changed property and update it in the database MySQL

    System.Windows.MessageBox.Show("EntityViewModelPropertyChanged");
}

知道为什么会发生这种情况吗?

编辑:已解决

正如彼得所说,问题在于我订阅了错误的 TrulyObservableCollection 实例。 我没有创建新的 TrulyObservableCollection,而是分配了 HelperClass 返回的值。

public Loading()
        {    
            InitializeComponent();

            // This was the wrong piece
            //LoadingDataCollection = new TrulyObservableCollection<ModelObj>();

            // Asign the collection returned from HelperClass
            LoadingDataCollection = HelperClass.LoadItems();

            // Subscribe
            LoadingDataCollection.CollectionChanged += ContentCollectionChanged;
        }

【问题讨论】:

  • 您订阅了错误的TrulyObservableCollection&lt;ModelObj&gt; 实例通知。您未能提供一个好的minimal reproducible example,其中包含HelperClass.LoadItems() 方法,但推测该方法返回一个全新的实例,而不是使用LoadingDataCollection 的当前值,因此您需要订阅that 新实例上的事件,或者不创建新实例,而是将项目直接加载到您已经创建的实例中。有关更多详细信息,请参阅标记的重复项。
  • HelperClass.LoadItems() 返回一个新的 TrulyObservableCollection 对象,其中填充了所有对象,也许这可能是问题所在。谢谢彼得。

标签: c# observablecollection


【解决方案1】:

这段代码就在这里:

LoadingDataCollection = HelperClass.LoadItems();

正在为“LoadingDataCollection”变量分配一个新集合,并消除您为之前占用该变量的集合分配事件处理程序的事实。

如果您将该代码更改为:

LoadingDataCollection.AddRange(HelperClass.LoadItems()); 

它应该可以工作。

【讨论】:

  • 它说 TrulyObservableCollection 不包含 AddRange 的定义应该在 TrulyObservableCollection 中实现吗?
  • 您可以添加自己的 AddRange 函数或检查 Peter 确定为与您的问题重复的链接。
猜你喜欢
  • 2013-09-03
  • 1970-01-01
  • 2016-12-11
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 2016-09-03
  • 2012-03-11
相关资源
最近更新 更多