【问题标题】:Get a list of all tree nodes (in all levels) in TreeView Controls获取 TreeView 控件中所有树节点(在所有级别中)的列表
【发布时间】:2011-01-15 20:47:08
【问题描述】:

如何在TreeView 控件中获取所有树节点(在所有级别)的列表?

【问题讨论】:

    标签: c# asp.net treeview


    【解决方案1】:

    您可以使用两种递归扩展方法。您可以拨打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;
    }
    

    【讨论】:

    • 为我运行将_self.ChildNodes 更改为_self.Nodes。请记住将这两个方法写入一个新的静态类:public static class TreeViewExtensions
    • @daniherrera 谢谢,我修正了错误。不知道为什么我首先使用ChildNodes
    【解决方案2】:

    假设您有一棵具有一个根节点的树,以下代码将始终将树节点循环到最深,然后再返回一层,依此类推。它将打印每个节点的文本。 (未经我的头顶测试)

    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);
      }
    }
    

    【讨论】:

      【解决方案3】:

      惰性 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;
      }
      

      【讨论】:

        【解决方案4】:

        更新 Krumelur 的答案(用这个替换他/她解决方案的前 2 行):

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

        【讨论】:

        • 是的,如果有多个根,它会吐出所有子树。但实际上:具有多个节点的树在自然界中很少见 :-) 哦,它是“他的”;)
        • 事实上,这在自然界中是一种很常见的现象 :) 在编程中,我可以想象一些有用的场景。例如:包含公司部门的树视图,每个部门都有子部门等。你可能不会有任何超级部门。
        • 对不起,你们俩都需要编辑答案。 @Krumelur 您的 foreach 拼写错误和 dzendras,您的 'var' 不正确。它不应该是TreeNode的某种形式吗?在 C# 中,无法识别 var。
        • 虽然 var 确实可以被新的 C# 编译器识别,但它必须知道类型才能正常工作,并且 Nodes 是 IEnumerable,而不是 IEnumerable,因此将被键入为对象。
        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

          我认为我的解决方案更优雅,它使用泛型(因为 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);
          

          【讨论】:

            【解决方案7】:

            如果您需要对树视图的所有节点进行一些处理,您可以使用堆栈而不是递归方法:

            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);
            }
               
            

            【讨论】:

              【解决方案8】:

              因为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

              【讨论】:

                【解决方案9】:

                此代码可帮助您遍历所有 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);
                

                【讨论】:

                  猜你喜欢
                  • 2021-04-28
                  • 1970-01-01
                  • 2010-09-15
                  • 2010-11-25
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-12-19
                  • 1970-01-01
                  相关资源
                  最近更新 更多