2015-11-23 20 views
1

我有一個名爲ItemType的對象的集合,每個對象都有一個Item的子集合。頂級集合包裝到ObservableCollection中,以便用戶在集合中添加或刪除東西時進行響應。這綁定到一個TreeView,以便每個ItemType顯示其下面的子項目。在ICollectionView中過濾對象的子項目

我希望能夠做的是使用Filter來擺脫設置爲刪除的子項目對象。我掙扎,因爲過濾器需要一個布爾謂語,當然,只有頂級的ItemType獲取通過例如:

public void UpdateObservableCollection() 
{ 
    QuoteItemTypesView = CollectionViewSource.GetDefaultView(QuoteItemTypes); 
    QuoteItemTypesView.Filter = FilterDeleted; 
} 

public bool FilterDeleted(object item) 
{ 
    ItemType it = item as ItemType; // only ItemType is ever passed in 
    if(it.IsDeleted) 
    { 
     return false; 
    } 
    return true; 
} 

是沒有好,因爲它消除了ItemType的,而不是任何的下面的項目。

我試着這樣做:

public bool FilterDeleted(object item) 
{ 
    ItemType it = item as ItemType; 
    var itemsToRemove = new List<Item>(); 
    foreach (Item i in it.Items) 
    { 
     if (i.IsDeleted) 
     { 
      itemsToRemove.Add(i); 
     } 
    } 

    foreach (var foo in meh) 
    { 
     it.Items.Remove(foo); 
    } 

    return true; 
} 

但這最終實際上是從底層集合刪除的項目,而不是執行實際的過濾器。

有什麼辦法可以過濾孩子的收藏嗎?

回答

1

假設你ItemType被聲明爲

public class ItemType : INotifyPropertyChanged 
{ 
    public string Name { get; set; // Raise property changed event } 
    public string IsDeleted { get; set; // Raise property changed event } 

    //// Other properties 

    public List<ItemType> Children { get; set; } 

    //// Filter based on provided perdicate 
    public Node Search(Func<Node, bool> predicate) 
    { 
     if(this.Children == null || this.Children.Count == 0) 
     { 
      if (predicate(this)) 
       return this; 
      else 
       return null; 
     } 
     else 
     { 
      var results = Children 
           .Select(i => i.Search(predicate)) 
           .Where(i => i != null).ToList(); 

      if (results.Any()){ 
       var result = (Node)MemberwiseClone(); 
       result.Items = results; 
       return result; 
      } 
      return null; 
     }    
    } 
} 

然後你可以過濾結果爲:

public bool FilterDeleted(object item) 
{ 
    ItemType it = item as ItemType; // only ItemType is ever passed in 
    it = it.Search(x=> x.IsDeleted); 
    return true; 
} 
+0

+1 - 這是輝煌的。不幸的是,我不能使用它,因爲ItemType是一個EF對象 - 我無法訪問其子項,直到它創建:( –

+1

根據最佳實踐,你應該映射EF模型到ViewModel,以便表示層只綁定到ViewModel和沒有直接使用EF/DB模型 – user1672994

+0

是的。瞭解爲什麼這是當天晚些時候的最佳做法。 –