C# 如何循环遍历 Treeview 节点的所有层?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/730860/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 22:57:23  来源:igfitidea点击:

How do I loop through all layers of Treeview nodes?

c#winforms.net-3.5loops

提问by Refracted Paladin

Read EDIT 2 first

首先阅读编辑 2

I am trying to set up some way to visually distinguish the nodes in a winform app. For example, alternating colors.

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

Can some one start me down that path? Also, has anyone else had to do that before and how did you do it?

有人可以让我走上这条路吗?另外,之前是否有其他人必须这样做,您是如何做到的?

Thanks

谢谢

EDIT

编辑

I had seen the backcolor setting as well(Thank You) but I am having trouble getting it to work. I do not see a Paint() event for treeviews. I tried putting the below code in my Form Load() but it isn't working. Possibly because the treeview is loaded yet??

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

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

EDIT 2

编辑 2

Okay, I have the initial problem out of the way using the below on Form_Load()

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

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

Now what I need to figure out, with someone's help, is how to Loop through ALLlayers of nodes and apply my alternating coloring. If I do something along the below lines I can achievethis.

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

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

How do I iterate through ALL layers programatically?

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

采纳答案by Mike Marshall

Recursion?

递归?

Edit: added code for eliminating color repetition

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

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

回答by jgallant

The best way to do this would be to override the OnPaint event, and provide your own code for drawing in the control.

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

You can find many examples on overriding the onPaint method online.

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

EDIT: I actually looked into this some more, and you can set the BackColor of treeview nodes individually already.

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

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

回答by Refracted Paladin

Okay, this is how far I got. Unfortunately it is very ugly and I am still manually coding how DEEPI go into it. Also it doesn't prevent like colors being next to each other. Suggestions?

好的,这就是我得到的程度。不幸的是,它非常丑陋,我仍在手动编码我进入它的深度。它也不会阻止类似的颜色彼此相邻。建议?

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

回答by JP Alioto

Do it recursively on a Control type using the children control from the TreeView root and check to see if the Control type is the type of the node you are looking for, cast, change backcolor and you are done.

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

回答by Leahn Novash

Dude, this one was serious trouble. The Broadth Search was easy, but you were right. Depth Search was a pain. I hope it helps you. Shame that such nice trick will probably fall into oblivion due to the sheer ammount of questions on this site. The depth algorithm is kind of crude and assume a head node without siblings.

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

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