获取TreeView控件中所有节点(各级别)的列表

14

如何获取 TreeView 控件中所有层级的节点列表?

9个回答

29

您可以使用两个递归扩展方法。您可以调用 myTreeView.GetAllNodes()myTreeNode.GetAllNodes():

public static List<TreeNode> GetAllNodes(this TreeView _self)
{
    List<TreeNode> result = new List<TreeNode>();
    foreach (TreeNode child in _self.Nodes)
    {
        result.AddRange(child.GetAllNodes());
    }
    return result;
}

public static List<TreeNode> GetAllNodes(this TreeNode _self)
{
    List<TreeNode> result = new List<TreeNode>();
    result.Add(_self);
    foreach (TreeNode child in _self.Nodes)
    {
        result.AddRange(child.GetAllNodes());
    }
    return result;
}

2
请将“_self.ChildNodes”更改为“_self.Nodes”,然后在新的静态类“public static class TreeViewExtensions”中编写这两种方法。 - dani herrera
@daniherrera 谢谢,我已经修复了错误。不确定为什么我一开始使用了 ChildNodes - Martin Braun

22

假设您有一棵只有一个根节点的树,以下代码将始终循环树节点到最深处,然后返回一级。它将打印每个节点的文本。(从我的头部未经测试)

TreeNode oMainNode = oYourTreeView.Nodes[0];
PrintNodesRecursive(oMainNode);

public void PrintNodesRecursive(TreeNode oParentNode)
{
  Console.WriteLine(oParentNode.Text);

  // Start recursion on all subnodes.
  foreach(TreeNode oSubNode in oParentNode.Nodes)
  {
    PrintNodesRecursive(oSubNode);
  }
}

10
懒惰的LINQ方法,以防您正在寻找类似的内容:
private void EnumerateAllNodes()
{
    TreeView myTree = ...;

    var allNodes = myTree.Nodes
        .Cast<TreeNode>()
        .SelectMany(GetNodeBranch);

    foreach (var treeNode in allNodes)
    {
        // Do something
    }
}

private IEnumerable<TreeNode> GetNodeBranch(TreeNode node)
{
    yield return node;

    foreach (TreeNode child in node.Nodes)
        foreach (var childChild in GetNodeBranch(child))
            yield return childChild;
}

6

更新Krumelur的回答(将他/她解决方案的前两行替换为以下内容):

foreach ( var node in oYourTreeView.Nodes )
{
    PrintNodesRecursive( node );
}

是的,如果有多个根节点,它将输出所有子树。但事实上,在自然界中具有多个节点的树非常罕见 :-) 哦,它是“他”的 ;) - Krumelur
事实上,在自然界中,这是一种相当常见的现象 :) 在编程中,我可以想象出一些有用的场景。例如:包含公司部门的树形视图,每个部门都有子部门等等。您可能不会有任何超级部门。 - dzendras
1
抱歉,各位需要编辑你们的答案。@Krumelur,你的foreach拼写错误了,而dzendras,你的“var”不正确。它不应该是某种类型转换为TreeNode吗?在C#中,var是无法识别的。 - Fandango68
尽管 var 变量在新版本的 C# 编译器中被认可,但是它需要知道正确的类型才能正常工作。而且 Nodes 是 IEnumerable 而不是 IEnumerable<TreeNode>,因此它的类型将会被确定为 object。 - bkqc

2

如果您不需要节点键是唯一的,只需将所有节点键设置为空字符串(""),然后可以执行 Treeview1.Nodes.Find("", true); 返回 TreeView 中的所有节点。


2
如果您需要在树视图的所有节点上进行一些处理,可以使用堆栈而不是递归方法:
Stack<TreeNode> nodeStack = new Stack<TreeNode>(treeview1.Nodes.Cast<TreeNode>());
while(nodeStack.Count > 0)
{
   TreeNode node = nodeStack.Pop();

   // Do your processing on the node here...

   // Add all children to the stack
   if(node.Nodes.Count > 0)
     foreach(TreeNode child in node.Nodes)
        nodeStack.Push(child);
}
   

1
由于TreeView有许多级别,所以需要使用递归函数:
   public void AddNodeAndChildNodesToList(TreeNode node)
    {
        listBox1.Items.Add(node.Text);    // Adding current nodename to ListBox     

        foreach (TreeNode actualNode in node.Nodes)
        {
            AddNodeAndChildNodesToList(actualNode); // recursive call
        }
    }

请对TreeView中所有一级节点调用此函数:
    foreach (TreeNode actualNode in treeView1.Nodes)         // Begin with Nodes from TreeView
    {
         AddNodeAndChildNodesToList(actualNode);
    }

代码来自网站 C# TreeView

1
我认为我的解决方案更加优雅,它使用泛型(因为TreeView可以存储从TreeNode派生的任何对象),并且只有一个递归调用的函数。将其转换为扩展应该也很简单。
    List<T> EnumerateAllTreeNodes<T>(TreeView tree, T parentNode = null) where T : TreeNode
    {
        if (parentNode != null && parentNode.Nodes.Count == 0)
            return new List<T>() { };

        TreeNodeCollection nodes = parentNode != null ? parentNode.Nodes : tree.Nodes;
        List<T> childList = nodes.Cast<T>().ToList();

        List<T> result = new List<T>(1024); //Preallocate space for children
        result.AddRange(childList); //Level first

        //Recursion on each child node
        childList.ForEach(n => result.AddRange(EnumerateAllTreeNodes(tree,n)));

        return result;
    }

使用方法很简单,只需要调用:

    List<MyNodeType> allnodes = EnumerateAllTreeNodes<MyNodeType>(tree);

0

这段代码可以帮助您遍历所有TreeView列表,并确定当前深度级别。该代码可用于将TreeView项目保存到XML文件和其他用途。

int _level = 0;
        TreeNode _currentNode = treeView1.Nodes[0];
        do
        {
            MessageBox.Show(_currentNode.Text + " " + _level);
            if (_currentNode.Nodes.Count > 0)
            {
                _currentNode = _currentNode.Nodes[0];
                _level++;
            }
            else
            {
                if (_currentNode.NextNode != null)
                    _currentNode = _currentNode.NextNode;
                else
                {
                    _currentNode = _currentNode.Parent.NextNode;
                    _level--;
                }
            }
        }
        while (_level > 0);

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