【问题标题】:How do I loop through all layers of Treeview nodes?如何循环遍历 Treeview 节点的所有层?
【发布时间】:2010-10-18 08:49:54
【问题描述】:

首先阅读 EDIT 2

我正在尝试设置某种方式来直观地区分 winform 应用程序中的节点。例如,交替颜色。

有人可以让我走上这条路吗?另外,以前有没有其他人必须这样做,你是怎么做到的?

谢谢

编辑

我也看到了背景色设置(谢谢),但我无法让它工作。我没有看到树视图的 Paint() 事件。我尝试将下面的代码放在我的 Form Load() 中,但它不起作用。可能是因为树视图已经加载了??

        private void frmCaseNotes_Load(object sender, System.EventArgs e)
    {
        foreach (TreeNode treeNode in treeView1.Nodes[0].Nodes)
        {
            treeNode.BackColor = Color.DeepSkyBlue;
        }
    }

编辑 2

好的,我在 Form_Load() 上使用下面的方法解决了最初的问题

            foreach (TreeNode treeNode in treeView1.Nodes)
        {
            if (treeNode.Index % 2 == 0)
            {
                 treeNode.ForeColor = Color.DodgerBlue;
            }
            else
            {
                treeNode.ForeColor = Color.Goldenrod;
            }

现在我需要在某人的帮助下弄清楚如何循环遍历 ALL 层节点并应用我的交替着色。如果我按照以下方式做一些事情,我可以实现这个。

            foreach (TreeNode treeNode in treeView1.Nodes[1].Nodes[0].Nodes)
        {
            if (treeNode.Index % 2 == 0)
            {
                 treeNode.ForeColor = Color.DodgerBlue;
            }
            else
            {
                treeNode.ForeColor = Color.Goldenrod;
            }

如何以编程方式遍历所有层?

【问题讨论】:

  • 只要您在一个根节点下的子节点已经加载到控件中,您的代码应该可以工作。

标签: c# winforms .net-3.5 loops


【解决方案1】:

老兄,这个麻烦大了。广泛搜索很容易,但你是对的。深度搜索很痛苦。我希望它对你有帮助。遗憾的是,由于该网站上的问题数量众多,如此好的技巧可能会被遗忘。深度算法有点粗糙,假设头节点没有兄弟节点。

//depth search on TreeView

TreeNode node = trv.Nodes[0];
Stack<TreeNode> list = new Stack<TreeNode>();
list.Push(node);

while (list.Count > 0)
{
    while (node.Nodes.Count > 0)
    {
        list.Push(node.Nodes[0]);
        node = node.Nodes[0];
    }

    //Will always have a leaf here as the current node. The leaf is not pushed.
    //If it has a sibling, I will try to go deeper on it.
    if (node.NextNode != null)
    {
        node = node.NextNode;
        continue;
    }

    //If it does NOT have a sibling, I will pop as many parents I need until someone
    //has a sibling, and go on from there.
    while (list.Count > 0 && node.NextNode == null)
    {
        node = list.Pop();
    }
    if (node.NextNode != null) node = node.NextNode;
}

//broadth search on TreeView

Queue<TreeNode> list = new Queue<TreeNode>();
foreach(TreeNode node in trv.Nodes)
{
    list.Enqueue(node);
}
foreach(TreeNode node in list)
{
    foreach(TreeNode childNode in node.Nodes)
    {
        list.Enqueue(childNode);
    }
}

【讨论】:

    【解决方案2】:

    递归?

    编辑:添加了消除颜色重复的代码

    protected void ColorNodes(TreeNode root, Color firstColor, Color secondColor)
    {
       Color nextColor;
       foreach (TreeNode childNode in root.Nodes)
       {     
          nextColor = childNode.ForeColor = childNode.Index % 2 == 0 ? firstColor : secondColor;
    
          if (childNode.Nodes.Count > 0)
          {
             // alternate colors for the next node
             if (nextColor == firstColor)
                  ColorNodes(childNode, secondColor, firstColor);
             else
                  ColorNodes(childNode, firstColor, secondColor);
          }
       }
    }
    
      private void frmCaseNotes_Load(object sender, System.EventArgs e)
        {
           foreach (TreeNode rootNode in treeView1.Nodes)
           {
              ColorNodes(rootNode, Color.Goldenrod, Color.DodgerBlue);
           }
        }
    

    【讨论】:

    • 关闭,谢谢!除了跳过对第一(根)层着色之外,它工作得很好。
    • 这已经足够接近了。我会弄清楚其余的并将其发布在此处以用于存档目的。感谢您的帮助!
    【解决方案3】:

    使用 TreeView 根中的子控件对 Control 类型递归执行此操作,并检查 Control 类型是否是您要查找的节点的类型,转换,更改背景颜色,然后就完成了。

    【讨论】:

      【解决方案4】:

      好的,这就是我得到的结果。不幸的是,它非常难看,我仍在手动编写 DEEP 的代码。它也不会阻止类似的颜色彼此相邻。有什么建议吗?

      foreach (TreeNode treeNode in treeView1.Nodes)
              {
                  treeNode.ForeColor = treeNode.Index % 2 == 0 ? Color.DodgerBlue : Color.Goldenrod;
      
                  foreach (TreeNode childNode in treeNode.Nodes)
                  {
                      childNode.ForeColor = childNode.Index % 2 == 0 ? Color.Goldenrod : Color.DodgerBlue;
      
                      foreach (TreeNode childChildNode in childNode.Nodes)
                      {
                          childChildNode.ForeColor = childChildNode.Index % 2 == 0 ? Color.DodgerBlue : Color.Goldenrod;
      
                          foreach (TreeNode childChildChildNode in childChildNode.Nodes)
                          {
                              childChildChildNode.ForeColor = childChildChildNode.Index % 2 == 0 ? Color.Goldenrod : Color.DodgerBlue;
                          }
                      }
                  }
              }
      

      【讨论】:

        【解决方案5】:

        最好的方法是重写 OnPaint 事件,并提供您自己的代码以在控件中绘图。

        您可以在网上找到许多关于覆盖 onPaint 方法的示例。

        编辑:我实际上对此进行了更多研究,您已经可以单独设置树视图节点的背景色。

        Me.TreeView1.Nodes(0).BackColor = Color.AliceBlue  
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-03-30
          • 1970-01-01
          • 2015-04-19
          • 1970-01-01
          • 2014-02-03
          • 2013-02-16
          • 1970-01-01
          • 2020-05-07
          相关资源
          最近更新 更多