C# 为什么未激发CollectionChanged的订阅事件?
我使用的是这个插入类,子类ObservableCollection在集合中的项发生更改时通知。它可以提高活动的成功率C# 为什么未激发CollectionChanged的订阅事件?,c#,observablecollection,C#,Observablecollection,我使用的是这个插入类,子类ObservableCollection在集合中的项发生更改时通知。它可以提高活动的成功率 public sealed class TrulyObservableCollection<T> : ObservableCollection<T> where T : INotifyPropertyChanged { public TrulyObservableCollection() { CollectionCh
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);
}
}
公共密封类TrulyObservableCollection:ObservableCollection
其中T:INotifyPropertyChanged
{
公共TrulyObservableCollection()
{
CollectionChanged+=FullObservableCollectionCollectionChanged;
}
公共TrulyObservableCollection(IEnumerable pItems):this()
{
foreach(pItems中的var项目)
{
本条增加(项目);
}
}
私有void FullObservableCollectionCollectionChanged(对象发送方,NotifyCollectionChangedEventArgs e)
{
如果(如NewItems!=null)
{
foreach(e.NewItems中的对象项)
{
((INotifyPropertyChanged)项)。PropertyChanged+=项PropertyChanged;
}
}
如果(例如,OldItems!=null)
{
foreach(e.OldItems中的对象项)
{
((INotifyPropertyChanged)项)。PropertyChanged-=项PropertyChanged;
}
}
}
私有void ItemPropertyChanged(对象发送方,PropertyChangedEventArgs e)
{
//在这里,当一个项目改变时,它工作。
System.Windows.MessageBox.Show(“ItemPropertyChanged fired!”);
NotifyCollectionChangedEventArgs args=新的NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace,sender,sender,IndexOf((T)sender));
OnCollectionChanged(args);
}
}
当项目更改时,会激发ItemPropertyChanged,但当我使用集合并向OnCollectionChanged订阅函数时,不会激发subscribed事件
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加载数据采集;
公共加载()
{
初始化组件();
LoadingDataCollection=new TrulyObservableCollection();
LoadingDataCollection.CollectionChanged+=ContentCollectionChanged;
//填满藏品
LoadingDataCollection=HelperClass.LoadItems();
}
public void ContentCollectionChanged(对象发送方,NotifyCollectionChangedEventArgs e)
{
//永远也到不了这里。
System.Windows.MessageBox.Show(“ContentCollectionChanged fired!”);
if(e.Action==NotifyCollectionChangedAction.Remove)
{
foreach(e.OldItems中的ModelObj项)
{
//删除的项目
item.PropertyChanged-=EntityViewModelPropertyChanged;
}
}
else if(e.Action==NotifyCollectionChangedAction.Add)
{
foreach(e.NewItems中的ModelObj项)
{
//新增项目
item.PropertyChanged+=EntityViewModelPropertyChanged;
}
}
}
public void EntityViewModelPropertyChanged(对象发送方,PropertyChangedEventArgs e)
{
//在这里,我想得到更改的属性并在数据库MySQL中更新它
System.Windows.MessageBox.Show(“EntityViewModelPropertyChanged”);
}
知道为什么会这样吗
编辑:已解决
正如Peter提到的,问题是我订阅了错误的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;
}
公共加载()
{
初始化组件();
//这是错误的一块
//LoadingDataCollection=new TrulyObservableCollection();
//Asign从HelperClass返回的集合
LoadingDataCollection=HelperClass.LoadItems();
//订阅
LoadingDataCollection.CollectionChanged+=ContentCollectionChanged;
}
此处的代码:
LoadingDataCollection = HelperClass.LoadItems();
正在将新集合分配给“LoadingDataCollection”变量,并清除将事件处理程序分配给先前占用该变量的集合的事实
如果将该代码更改为:
LoadingDataCollection.AddRange(HelperClass.LoadItems());
它应该可以工作。它说TrulyObservableCollection不包含AddRange的定义,如果这在TrulyObservableCollection中实现的话?您可以添加自己的AddRange函数,或者检查Peter识别为与您的问题重复的链接。您订阅了错误实例的通知
TrulyObservableCollection
。您未能提供一个好的方法,其中包括HelperClass.LoadItems()
方法,但该方法可能返回一个全新的实例,而不是使用当前值LoadingDataCollection
,因此您需要订阅该新实例上的事件,或者不创建新实例,而是直接将项目加载到您已经创建的实例中。有关其他详细信息,请参见标记的重复。HelperClass.LoadItems()返回一个新的TrulyObservableCollection对象,其中所有对象都已填充,这可能是问题所在。谢谢你,彼得。