2014-02-11 36 views
0

我有一系列嵌套集合,我需要檢測從最高層到最低層的任何位置的更改。首先,我將顯示我的代碼:如何獲取嵌套集合更改事件以冒泡

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事件僅檢測第一層中的更改。建議將不勝感激。

回答

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()}); 
    } 
} 
+0

我對事件很糟糕,所以請原諒我的無知。最上層實際上是CategoricalDataItemCollection而不是CategoricalDataItem。那麼,我是否需要在CategoricalDataItemCollection類中重複這種方法,以便我可以在我的調用類中訂閱該事件? – flyNflip

+0

@flyNflip我已經更新了我的回答,讓集合進行監控。祝你好運! – TyCobb

+0

非常感謝。我現在就試試看。 – flyNflip