我有一个关于过滤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;
}
这几乎按预期工作。
如果项目没有按预期工作,那么过滤器 NOT 应用的项目是否为子项。
在这种情况下,即使项目本身与过滤器匹配,如其子项不匹配,也会返回 null 。
在
/*
* this is where I'm struggling
*/
评论是我认为我需要额外逻辑的地方。
请注意,原始搜索方法的功劳归于@ tono-nam
因为这是周末而且我和你们绝大多数人的时区不同,如果我不立即回应,请不要被冒犯!
周末愉快!
答案 0 :(得分:1)
您要显示的项目不需要ObservableCollection
,因为整个集合会立即更改。您可以简单地使用例如一个数组,让父类实现INotifyPropertyChanged
来通知整个集合已经改变的事实。
要回答关于返回什么而不是null
的问题,请使用与叶子相同的逻辑:如果项目与谓词匹配则返回该项目,否则返回null
。
您可以通过重新排序条件来简化代码:首先获取满足谓词的所有子项,如果没有,(或者因为没有子项,或者因为有子项但它们不匹配 - 无关紧要)将收藏品当作一片叶子。