2015-04-17 121 views
0

我有一個有關過濾ObservableCollection(及其子)的問題。嵌套的ObservableCollection過濾

我有以下類:

public class SomeClass 
{ 
    public string Description { get; set; } 
    public string CodeFlag { get; set; } 
    public double Price { get; set; } 
    public List<SomeClass> Children { get; set; } 

    public SomeClass() 
    { 
     this.Children = new List<SomeClass>(); 
    } 

    public SomeClass Search(Func<SomeClass, bool> predicate) 
    { 
     // the node is a leaf 
     if (this.Children == null || this.Children.Count == 0) 
     { 
      if (predicate(this)) 
       return this; 
      else 
       return null; 
     } 
     else // the node is a branch 
     { 
      var results = Children.Select(i => i.Search(predicate)).Where(i => i != null).ToList(); 

      if (results.Any()) 
      { 
       var result = (SomeClass)MemberwiseClone(); 
       result.Children = results; 
       return result; 
      } 
      /* 
      * this is where I'm struggling 
      */ 

      return null; 
     } 
    } 
} 

並在視圖模型以下屬性:

private ObservableCollection<SomeClass> originalDataSource; 
public ObservableCollection<SomeClass> TreeViewDataSource { get; set; } 

originalDataSource被設置在構造而TreeViewDataSource是集綁定到TreeView。

我確定有更好的方法來完成這個(即只有一個集合),但我現在對此感到滿意。

最初,集合中的所有項目都將被顯示 - 我只是簡單地顯示每個項目的描述,代碼和價格屬性,迄今爲止非常好。

現在,視圖模型被告知當前過濾器已經改變,所以我想能夠過濾。

一個例子可以顯示「CodeFlag」爲「ABC」或「XYZ」的所有項目。

如果過濾器發生了變化,我設置了TreeViewDataSource這樣:

this.TreeViewDataSource = _getFilteredList(this.originalDataSource); 

private ObservableCollection<SomeClass> _getFilteredList(ObservableCollection<SomeClass> originalList) 
{ 
    var filteredItems = new ObservableCollection<SomeClass>(); 
    SomeClass filterResults = null; 

    switch (this.SelectedFilter) 
    { 
     case SomeEnum.SomeFilterOption: 
      filterResults = originalList[0].Search(x => x.CodeFlag.Equals("ABC") || x.CodeFlag.Equals("XYZ")); 
     break; 

     default: 
     break; 
    } 

    filteredItems.Add(filterResults); 

    return filteredItems; 
} 

預期這幾乎工程。

凡未按預期工作是如果一個項目有孩子其中濾波器確實適用。

在這種情況下,即使該項目本身與篩選器匹配,但其子項不匹配,將返回null

/* 
* this is where I'm struggling 
*/ 

的評論是,我認爲我需要額外的邏輯。

請注意,信貸原始的搜索方法去@遠野南

由於今天是週末,我可以在不同的時區,絕大多數的你,請不要如果我不馬上回應,我會感到不高興!

週末愉快!

回答

1

對於要顯示的項目,您不需要ObservableCollection,因爲整個集合會一次更改。您可以簡單地使用例如一個數組,並讓父類實現INotifyPropertyChanged來通知整個集合已更改的事實。

要回答關於返回的內容而不是null的問題,請使用與葉子相同的邏輯:返回與謂詞匹配的項目,否則返回null
您可以通過對條件進行重新排序來簡化您的代碼:首先讓所有滿足謂詞的孩子,如果沒有(因爲沒有孩子,或者因爲有孩子但他們不匹配 - 並不重要)然後將集合視爲一片葉子。

+0

謝謝你的回答。我已經實現了'BindableBase',因此沒有使用'ObservableCollection'的問題。 關於邏輯,如果謂詞滿足,那麼在返回項目之前,我仍然必須將子項設置爲結果(即無),否則該項目將具有其原始子項。 再次感謝你,這回答了我的問題! – user3235445