我有一个名为 ItemType 的对象的集合,每个集合都有一个 Item 的子集合。顶级集合被包装到一个 ObservableCollection 中,因此它会在用户从集合中添加或删除内容时做出响应。这绑定(bind)到 TreeView,以便每个 ItemType 在下面显示其子项。
我希望能够做的是使用过滤器去除设置为已删除的子项对象。我很挣扎,因为 Filter 需要一个 bool 谓词,当然,只有顶级 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;
}
但这最终实际上是从基础集合中删除项目,而不是执行实际的过滤器。
有什么方法可以过滤子集合吗?
最佳答案
假设您的 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;
}
关于c# - 在 ICollectionView 中过滤对象的子项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33876474/