我有一系列嵌套集合,我需要检测从最上层到最下层的任何位置的更改。首先,我将展示我的代码:
public class CategoricalDataItem
{
public string XValue { get; set; }
public double YValue { get; set; }
public SolidColorBrush Color { get; set; }
public CategoricalDataItemCollection SimpleSubData { get; set; }
}
[Serializable]
public class CategoricalDataItemCollection : ObservableCollection<CategoricalDataItem>
{
public string Descriptor { get; set; }
}
此代码的结构用于下钻图表。基本上,我允许5层深。开发人员可以创建CategoricalDataItemCollection的实例,并且对于该集合中的每个CategoricalDataItem,可以创建CategoricalDataItemCollection的新实例,依此类推。我需要知道是否在任何这些嵌套集合中添加或删除了任何项目。 CollectionChanged事件仅检测第一层中的更改。建议将不胜感激。
答案 0 :(得分:1)
诀窍是监控集合的变化。以下是这样做的示例。
我添加了一个小型测试类,它会在添加新项目时吐出消息。
需要注意的一点是,您实际上正在使用自己继承的CollectionChanged
事件,这样您就可以监控进出的孩子并在收集更改时进行监听。请特别注意,这只是一个示例,需要对MyCollectionChanged(...)
进行一些抛光和测试,因为还需要处理其他NotifyCollectionChangedAction
。
[Serializable]
public class CategoricalDataItemCollection : ObservableCollection<CategoricalDataItem>
{
public string Descriptor { get; set; }
public CategoricalDataItemCollection()
{
this.CollectionChanged += MyCollectionChanged;
}
void MyCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
{
// There are other actions to handle. This is purely an example.
if (args.OldItems != null)
{
foreach (var oldItem in args.OldItems.Cast<CategoricalDataItem>())
{
if (args.Action == NotifyCollectionChangedAction.Remove)
oldItem.SimpleSubData.CollectionChanged -= InvokeCollectionChanged;
}
}
if (args.NewItems != null)
{
foreach (var newItem in args.NewItems.Cast<CategoricalDataItem>())
{
if (args.Action == NotifyCollectionChangedAction.Add)
newItem.SimpleSubData.CollectionChanged += InvokeCollectionChanged;
}
}
}
void InvokeCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
{
// This is the tricky part. Nothing actually changed in our collection, but we
// have to signify that something did.
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
public class TestClass
{
public void TestNotify()
{
var parent = new CategoricalDataItemCollection();
parent.CollectionChanged += (sender, args) => Debug.Print("Parent Collection Changed");
var child = new CategoricalDataItem {SimpleSubData = new CategoricalDataItemCollection()};
child.SimpleSubData.CollectionChanged += (sender, args) => Debug.Print("Child Collection Changed");
var grandChild = new CategoricalDataItem { SimpleSubData = new CategoricalDataItemCollection()};
grandChild.SimpleSubData.CollectionChanged += (sender, args) => Debug.Print("Grand Child Collection Changed");
//Should only output "Parent"
parent.Add(child);
//Should only output "Child" and then "Parent"
child.SimpleSubData.Add(grandChild);
//Should now output "Grand Child" and then "Child" and then "Parent" messages.
grandChild.SimpleSubData.Add(new CategoricalDataItem(){SimpleSubData = new CategoricalDataItemCollection()});
}
}