6

I have a treeview with some nodes. Under some condition I want to color each node with different color along with their children. I have written a function that colors node and its children.

Will anyone please let me know is there any possibility that I have Color.Green as a variable such that I wont write the whole function for each color? I mean as an input parameter in function.

Here is the function:

public void ColorChild(TreeNode nodes, int indx)
{
    foreach (TreeNode node_tmp in nodes.Nodes[indx].Nodes)
    {
       System.Drawing.Color = Green;
       node_tmp.ForeColor = color;
       foreach (TreeNode node_tmp2 in node_tmp.Nodes)
       {
          node_tmp2.ForeColor = Color.Green;
          foreach (TreeNode node_tmp3 in node_tmp2.Nodes)
          {
             node_tmp3.ForeColor = Color.Green;
             foreach (TreeNode node_tmp4 in node_tmp3.Nodes)
             {
                node_tmp4.ForeColor = Color.Green;
                foreach (TreeNode node_tmp5 in node_tmp4.Nodes)
                {
                   node_tmp5.ForeColor = Color.Green;
                }
             }
          }
      }
   }
}

3 Answers3

6

You could use recursion to iterate through all your nodes.

Something like:

void ColorNode(TreeNodeCollection nodes, System.Drawing.Color Color)
{

    foreach (TreeNode child in nodes)
    {
        child.ForeColor= Color;
        if(child.Nodes != null && child.Nodes.Count>0)
          ColorNode(child.Nodes, Color);
    }
}

And call it from you method like:

public void ColorChild(TreeNode nodes, int indx)
{
   ColorNode(nodes.Nodes, Color.Green);
}
Zippy
  • 1,804
  • 5
  • 27
  • 36
  • See updated answer. You need to change the `var` in the foreach with a `TreeNode` element – Zippy Feb 02 '16 at 14:19
6

Your solution is extreme slow if the tree is large. Just color the nodes on demand when you draw them. To do so you need to set the drawing mode:

treeView1.DrawMode = TreeViewDrawMode.OwnerDrawText;

And then, when a node is about to drawn, ask its color on demand:

private void tree_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
    TreeNodeStates state = e.State;
    Font font = e.Node.NodeFont ?? e.Node.TreeView.Font;
    Color foreColor;
    Color backColor;

    // node is selected
    // if you want to see the color of a selected node, too,
    // you can use inverted fore/back colors instead of system selection colors 
    if ((state & TreeNodeStates.Selected) == TreeNodeStates.Selected)
    {
        bool isFocused = (state & TreeNodeStates.Focused) == TreeNodeStates.Focused;
        backColor = SystemColors.Highlight;
        foreColor = isFocused ? SystemColors.HighlightText : SystemColors.InactiveCaptionText;
        e.Graphics.FillRectangle(SystemBrushes.Highlight, e.Bounds);
        if (isFocused)
            ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, foreColor, backColor);
        TextRenderer.DrawText(e.Graphics, e.Node.Text, font, e.Bounds, foreColor, TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.SingleLine | TextFormatFlags.EndEllipsis | TextFormatFlags.NoPrefix);
    }
    // node is not selected
    else
    {
        backColor = GetBackColor(e.Node); // GetBackColor: return some color by condition
        foreColor = GetForeColor(e.Node); // GetForeColor: return some color by condition
        using (Brush background = new SolidBrush(backColor))
        {
            e.Graphics.FillRectangle(background, e.Bounds);
            TextRenderer.DrawText(e.Graphics, e.Node.Text, font, e.Bounds, foreColor, TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.SingleLine | TextFormatFlags.EndEllipsis);
        }
    }
}

If conditions are changed just invalidate the tree:

treeView1.Invalidate(); // this will re-draw the visible nodes
György Kőszeg
  • 17,093
  • 6
  • 37
  • 65
-1

Well, if you want Color as a parameter to your function, there is nothing stopping you.

public void ColorChild(TreeNode nodes, int indx, Color color)
{
    foreach (TreeNode node_tmp in nodes.Nodes[indx].Nodes)
    {
       node_tmp.ForeColor = color;
       foreach (TreeNode node_tmp2 in node_tmp.Nodes)
       {
          node_tmp2.ForeColor = color;
          foreach (TreeNode node_tmp3 in node_tmp2.Nodes)
          {
             node_tmp3.ForeColor = color;
             foreach (TreeNode node_tmp4 in node_tmp3.Nodes)
             {
                node_tmp4.ForeColor = color;
                foreach (TreeNode node_tmp5 in node_tmp4.Nodes)
                {
                   node_tmp5.ForeColor = color;
                }
             }
          }
      }
   }
}

Then just call it like

ColorChild(nodes, indx, Color.Green);
Gediminas Masaitis
  • 3,172
  • 14
  • 35