2015-11-23 2 views
1

У меня есть коллектив объекта ItemType, каждый из которых имеет дочернюю коллекцию Item. Коллекция верхнего уровня завернута в ObservableCollection, поэтому он отвечает, когда пользователи добавляют или удаляют вещи из коллекции. Это связано с TreeView, так что каждый ItemType отображает дочерние элементы ниже.Фильтровать дочерние элементы объектов в ICollectionView

Что бы я хотел сделать, это использовать фильтр, чтобы избавиться от дочерних объектов Item, которые установлены для удаления. Я изо всех сил, потому что фильтр нужно логическое сказуемое и, конечно же, только на высшем уровне 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

Да. Узнавайте, почему это лучшая практика немного поздно в тот же день. –

Смежные вопросы