我在Windows窗体UI上有一个treeview控件,它有几个节点(有多个子节点)。
我想查询节点集合,比如说,
1.选择名称以' x'
开头的人
2.选择Node.Tag字段中没有任何数据的那些。
有人可以建议我这样做的方法。 Linq会让它变得简单而整洁,但我在Linq上找不到任何查询TreeNodeCollection的内容。
谢谢,
答案 0 :(得分:35)
因为TreeNodeCollection
早于.NET 2.0,所以它不是通用集合,因此它不实现IEnumerable<T>
,这是LINQ良好的“主”类型。
但是,您可以在.Cast<TreeNode>()
上致电TreeNodeCollection
,然后获得IEnumerable<TreeNode>
,您可以然后执行所有LINQy善意。
(此方法适用于实现IEnumerable
但不实现IEnumerable<T>
的任何此类集合
答案 1 :(得分:3)
您可以尝试使用Fixpoint运算符来允许递归lambdas
// Fix point operator
public static Func<T, T> Fix<T>(Func<Func<T, T>, Func<T, T>> f)
{
return t => f(Fix<T>(f))(t);
}
然后
// your treeView
var tv = new TreeView();
// Your filter Func
Func<TreeNode, bool> filterStartWithXorNoData =
node => node.Text.StartsWith("x") || string.IsNullOrEmpty(node.Text);
// Your recursive lambda
var filteredNodes = Fix<IEnumerable<TreeNode>>(
f =>
nodeList =>
nodeList.SelectMany(node => f(node.ChildNodes.Cast<TreeNode>()))
.Union(nodeList.Where(filterStartWithXorNoData)))
(tv.Nodes.Cast<TreeNode>());
答案 2 :(得分:2)
由于每个父级下的嵌套节点集合,我最近尝试过类似的东西,并且很难使用LINQ方法。
我用搜索所有节点的递归函数解决了我的问题。相当优雅。
VB:
Private Function FindNode(name As String, root As TreeNode) As TreeNode
For Each n As TreeNode In root.Nodes
If n.Name = name Then
'Found, get out
Return n
Else
'Recursively call FindNode to search this node's children
Dim soughtNode = FindNode(name, n)
If soughtNode IsNot Nothing Then
Return soughtNode
End If
End If
Next
Return Nothing
End Function