查询TreeNodeCollection

时间:2012-04-13 11:31:55

标签: c# winforms linq

我在Windows窗体UI上有一个treeview控件,它有几个节点(有多个子节点)。 我想查询节点集合,比如说, 1.选择名称以' x'
开头的人 2.选择Node.Tag字段中没有任何数据的那些。

有人可以建议我这样做的方法。 Linq会让它变得简单而整洁,但我在Linq上找不到任何查询TreeNodeCollection的内容。

谢谢,

3 个答案:

答案 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