Reputation:
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
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
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
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