参考链接:https://stackoverflow.com/questions/20125131/treeview-change-plus-minus-icon
原文:
How do i change the Plus Minus icon of TreeView Control to some other icon using C#.Net.
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));
}
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
if (e.Node.Bounds.X != 0 )
{ //Drawnode logic write inside this condition then its works good }
中文翻译
如何使用C#.Net将TreeView控件的加减图标更改为其他图标。
当您要自定义TreeView控件时,Microsoft在TreeView控件上提供一个名为TreeViewDrawMode的属性,其值是一个枚举,它有3个值:Normal、OwnerDrawText、OwnerDrawAll。在您的情况下,必须使用OwnerDrawAll。
将该属性设置为TreeViewDrawMode.OwnerDrawAll后,当TreeView的节点显示时,将触发名为DrawNode的事件,以便在其中处理绘图。当你自己画的时候,通常需要画三个东西:展开/折叠图标,节点图标,节点文本。
我的样品如下:
//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();
//设置为自主绘图
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 绘制展开/折叠图标 ---------*/
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 绘制节点图标 ---------*/
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);
/*--------- 2 绘制节点文本 ---------*/
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));
}
我试过上面的示例代码,但这对我来说是个错误。如果我单击任何节点,它将在该节点位置上绘制,并在第一个根节点上绘制。我想停止子节点被绘制在第一个根节点上。这是我的输出屏幕
if (e.Node.Bounds.X != 0 )
{ //绘制节点的逻辑写在这个条件中,那么它工作正常 }