user5814565
user5814565

Reputation:

Color a node of treeview with different color

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

Upvotes: 7

Views: 24526

Answers (3)

Zippy
Zippy

Reputation: 1824

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

Upvotes: 7

György Kőszeg
György Kőszeg

Reputation: 18013

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

Upvotes: 6

Gediminas Masaitis
Gediminas Masaitis

Reputation: 3212

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

Upvotes: -1

Related Questions