5

How do i change the Plus Minus icon of TreeView Control to some other icon using C#.Net.

Shahid Iqbal
  • 2,095
  • 8
  • 31
  • 51
  • Possible duplicate of [How to change my treeView icons insted of +,- like a windows explorer treeview in c#.net win forms](http://stackoverflow.com/questions/13625420/how-to-change-my-treeview-icons-insted-of-like-a-windows-explorer-treeview-i) – Kraang Prime Aug 07 '16 at 22:53

1 Answers1

12

When you want to customize your TreeView control, Microsoft provides a property named TreeViewDrawMode on the TreeView control, its value is an enum which has 3 values: Normal, OwnerDrawText, OwnerDrawAll, in your situation, you must use OwnerDrawAll.

After you set that property to TreeViewDrawMode.OwnerDrawAll, when the TreeView's nodes are showing, an event named DrawNode will be triggered, so you can process your drawing there. When you draw it by yourself, usually you need to draw 3 things: expand/collapse icon, node icon, node text.

My sample is below:

//define the icon file path
string minusPath = Application.StartupPath + Path.DirectorySeparatorChar + "minus.png";
string plusPath = Application.StartupPath + Path.DirectorySeparatorChar + "plus.png";
string nodePath = Application.StartupPath + Path.DirectorySeparatorChar + "directory.png";

public FrmTreeView()
{
    InitializeComponent();
    //setting to customer draw
    this.treeView1.DrawMode = TreeViewDrawMode.OwnerDrawAll;
    this.treeView1.DrawNode += new DrawTreeNodeEventHandler(treeView1_DrawNode);
}

void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
    Rectangle nodeRect = e.Node.Bounds;

    /*--------- 1. draw expand/collapse icon ---------*/
    Point ptExpand = new Point(nodeRect.Location.X - 20, nodeRect.Location.Y + 2);
    Image expandImg = null;
    if (e.Node.IsExpanded || e.Node.Nodes.Count < 1)
        expandImg = Image.FromFile(minusPath);
    else
        expandImg = Image.FromFile(plusPath);
    Graphics g = Graphics.FromImage(expandImg);
    IntPtr imgPtr = g.GetHdc();
    g.ReleaseHdc();
    e.Graphics.DrawImage(expandImg, ptExpand);

    /*--------- 2. draw node icon ---------*/
    Point ptNodeIcon = new Point(nodeRect.Location.X - 4, nodeRect.Location.Y + 2);
    Image nodeImg = Image.FromFile(nodePath);
    g = Graphics.FromImage(nodeImg);
    imgPtr = g.GetHdc();
    g.ReleaseHdc();
    e.Graphics.DrawImage(nodeImg, ptNodeIcon);

    /*--------- 3. draw node text ---------*/
    Font nodeFont = e.Node.NodeFont;
    if (nodeFont == null)
        nodeFont = ((TreeView)sender).Font;
    Brush textBrush = SystemBrushes.WindowText;
    //to highlight the text when selected
    if ((e.State & TreeNodeStates.Focused) != 0)
        textBrush = SystemBrushes.HotTrack;
    //Inflate to not be cut
    Rectangle textRect = nodeRect;
    //need to extend node rect
    textRect.Width += 40;
    e.Graphics.DrawString(e.Node.Text, nodeFont, textBrush, 
        Rectangle.Inflate(textRect, -12, 0));
}

the result of my test

Ghost4Man
  • 1,040
  • 1
  • 12
  • 19
Scott Yang
  • 567
  • 2
  • 6
  • when I expand treeview it render text from root node also – Vignesh Nethaji Sep 28 '17 at 04:23
  • 1
    hi Vignesh, I guess that you need to adjust the location point of text. – Scott Yang Oct 09 '17 at 10:46
  • I tried the above sample code .but its cause an error for me. if I click any node .it will draw on that node location and also draw on first root node. I want to stop the child node was draw on first root node. this is my output screen https://s1.postimg.org/84fhr5dnf3/treeview.png – Vignesh Nethaji Oct 16 '17 at 04:58
  • hi Vignesh, sorry for late response, I guess you already figured it out, if not, please give me your code by a link or mail. – Scott Yang Dec 04 '17 at 01:23
  • if (e.Node.Bounds.X != 0 ) { //Drawnode logic write inside this condition then its works good } – Vignesh Nethaji Dec 19 '17 at 09:12
  • Thank you for the example. One minor point - It needs to be updated to dispose of the graphics resources. Otherwise there will be memory leaks. – Michael Jordan Jun 10 '21 at 16:34