【发布时间】:2015-04-17 23:28:06
【问题描述】:
我有一个关于过滤 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
*/
评论是我认为我需要额外逻辑的地方。
请注意,原始搜索方法的功劳归于@tono-nam
由于是周末,我可能与绝大多数人处于不同的时区,如果我没有立即回复,请不要生气!
周末愉快!
【问题讨论】:
标签: c# filtering observablecollection