如何遍历treeView控件的所有节点。C#

5

我正在选取表单中的所有控件。

如果控件是树形视图(Treeviews),我将迭代它们所拥有的所有节点。

我需要像这样的代码:

foreach (Control c in PanelSM.Controls)
{
    if (c is TreeView) 
    {    
        TreeNodeCollection myNodes = c.Nodes;//<<<<< Here is a mistake
        foreach (TreeNode n in myNodes)
        {
            String text = rm.GetString(n.Name);
            //And more things
            //...
            //...
            //...
       }
    }
    //...
}

有什么想法吗?

谢谢你。


1
啊啊啊.. 对不起。是我的错。 - David
1
等一下...你只需要 ((TreeView)c).Nodes 吗? - Darren Kopp
这有帮助吗?(http://msdn.microsoft.com/zh-cn/library/wwc698z7(v=vs.90).aspx) - Sriram Sakthivel
我在Sriram Sakthivel那里看到了它。问题是:我做不到:TreeNodeCollection myNodes = c.Nodes;// <<<<< 这里错误。 - Jean
@Darren Kopp 天啊!这非常简单。非常感谢你! - Jean
6个回答

39

你需要使用递归。像这样的一个方法应该就足够了。

IEnumerable<TreeNode> Collect(TreeNodeCollection nodes)
{
    foreach(TreeNode node in nodes)
    {
        yield return node;

        foreach (var child in Collect(node.Nodes))
            yield return child;
    }
}

那么在你的方法中,你只需执行以下操作:

 foreach (var node in Collect(tree.Nodes))
 {
     // you will see every child node here
 }

嘿,@Darren Kopp,非常感谢你!你太棒了! - Jean

11

这很容易:

void TraverseTree(TreeNodeCollection nodes)
{
    foreach (var child in nodes)
    {
        DoSomethingWithNode(child);
        TraverseTree(child.Nodes);
    }
}

并使用以下方式进行调用:

TraverseTree(MyTreeView.Nodes);

非常感谢您,@Jim Mischel。 - Jean
这个答案对我在asp.net中起作用了。谢谢。 - A Ghazal

2
我更喜欢简单易懂的东西,这里是我的简单解决方案:
    protected void TraverseNodes(TreeNodeCollection nodes, string action, int maxDepth = 2) 
    {
        foreach (TreeNode node in nodes)
        {
            if (node.ChildNodes.Count > 0 && node.Depth < maxDepth)
                TraverseNodes(node.ChildNodes, action, maxDepth);

            //do something!!!
            var x = node.Text;
            node.Checked = !node.Checked;
        }
    }

我决定加入一个“最大深度”的额外功能,希望你会喜欢。
按照以下方式调用:
```html

Call it as follows:

```
                TraverseNodes(this.Activities.Nodes, "");

与这里发布的一些示例不同,我实际测试了这个(哎呀!我可以听到他们说)。


2
你的错误在于变量c实际上是一个类型为Control的变量,它没有Nodes成员。你需要将其转换为TreeView类型。
你可以采用以下两种方法之一:
if (c is TreeView) 
{
    TreeNodeCollection myNodes = ((TreeView) c).Nodes; // <<--- Note the cast
    ...
}

或者

TreeView tv = c as TreeView;
if (tv != null)
{
        TreeNodeCollection myNodes = tv.Nodes;
        ...
}

非常感谢!@elgonzo - Jean

0

试试这个

    foreach (TreeNode t in tvMenu.Nodes)
    {
        for (int iParent = 0; iParent < t.ChildNodes.Count; iParent++)
        {
            for (int iChild = 0; iChild < t.ChildNodes[iParent].ChildNodes.Count; iChild++)
            {
                if (t.ChildNodes[iParent].ChildNodes[iChild].Text == "")
                {

                }
            }
        }
    }

0
在 Darren 出色的回答基础之上,您可以结合递归和类扩展来进行编程。
在您的命名空间中声明:
public static class MyExtensions
{
    public static IEnumerable<TreeNode> All( this TreeNodeCollection nodes )
    {
        foreach( TreeNode n in nodes )
        {
            yield return n;
            foreach( TreeNode child in n.Nodes.All( ) )
                yield return child;
        }
    }
}

请注意方法第一个参数前的“this”。
然后您可以在所有树视图中使用这个新方法:
foreach( TreeNode n in myTreeview.Nodes.All() ) ...

你可以将大多数方法转换为扩展方法。在这里,仅将其转换为扩展方法并没有真正添加任何内容到答案中。此外,你一开始选择的遍历树的实现方式并不是特别好(https://dev59.com/UmLVa4cB1Zd3GeqP1PJS#10253591)。 - Servy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接