我目前正在使用像这样定义的树结构
public class TreeNode
{
private ObservableCollection<TreeItem> nodeItems;
private ObservableCollection<TreeNode> nodeChildren;
//public "NodeItems" and "NodeChildren" getters and setters
}
public class TreeItem
{
private bool isSelected;
private string Name;
//public "IsSelected" and "Name" getters and setters
}
public class Tree
{
private TreeNode rootNode;
//public getters and setters properties
}
我正在尝试编写一个函数或public
属性,递归获取nodeItems
中Tree
的所有isSelected == true
并使其成为一个扁平集合
所以我在TreeNode
类中编写了这个函数,递归地遍历了孩子:
public ObservableCollection<TreeItem> SelectedItems()
{
ObservableCollection<TreeItem> tempCollection = new ObservableCollection<TreeItem>();
if (nodeItems != null)
{
foreach (TreeItem item in nodeItems)
{
if (item.IsSelected == true)
{
tempCollection.Add(item);
}
}
}
if (nodeChildren != null)
{
foreach (TreeNode node in nodeChildren)
{
tempCollection.Concat(node.SelectedItem());
}
}
return tempCollection;
}
但总是在最后返回一个空集合。
我如何纠正它,并可能改进它(使用 Lambda 表达式或属性)?
答案 0 :(得分:1)
Concat
上的ObservableCollection
函数不会修改任何参数。您必须将结果对象分配给tempCollection
。
if (nodeChildren != null)
{
foreach (TreeNode node in nodeChildren)
{
tempCollection = new ObservableCollection<TreeNode>(tempCollection.Concat(node.SelectedItem()));
}
}
编辑:或者,您可以使用重载的私有方法来不使用这么多临时集合:
public ObservableCollection<TreeItem> SelectedItems()
{
ObservableCollection<TreeItem> toReturn = new ObservableCollection<TreeItem>();
SelectedItems(toReturn);
return toReturn;
}
private void SelectedItems(ObservableCollection<TreeItem> tempCollection)
{
if (nodeItems != null)
{
foreach (TreeItem item in nodeItems)
{
if (item.IsSelected == true)
{
tempCollection.Add(item);
}
}
}
if (nodeChildren != null)
{
foreach (TreeNode node in nodeChildren)
{
node.SelectedItems(tempCollection);
}
}
}
答案 1 :(得分:1)
您可以将树的定义简化为:
public class Tree : ObservableCollection<Tree>
{
public ObservableCollection<TreeItem> nodeItems;
}
现在你可以这样做:
public IEnumerable<TreeItem> FlattenIsSelected(Tree tree)
{
return tree.nodeItems.Where(x => x.isSelected)
.Concat(tree.SelectMany(t => FlattenIsSelected(t)));
}
如果你保持现有的定义,这并不困难。