views:

1846

answers:

5

Read EDIT 2 first

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

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??

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

EDIT 2

Okay, I have the initial problem out of the way using the below on 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 ALL layers of nodes and apply my alternating coloring. If I do something along the below lines I can achieve this.

            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?

+2  A: 

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

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

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
Jon
A: 

Okay, this is how far I got. Unfortunately it is very ugly and I am still manually coding how DEEP I 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;
                    }
                }
            }
        }
Refracted Paladin
+1  A: 

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.

JP Alioto
+3  A: 

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);
       }
    }
mjmarsh
Close, thank you! It works perfectly EXCEPT that it skips coloring the first(root) layer.
Refracted Paladin
This is close enough to count. I will figure the rest out and post it here for archival purposes. Thanks for the help!
Refracted Paladin
+1  A: 

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