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