1.先准备两张图片downdrop.png、downdrop_open.png放在项目Resources里
2.新建用户控件BaseTreeView控件
3.重写控件继承TreeView,记得删除AutoScaleMode这一行,否则会报错
public partial class BaseTreeView : TreeView
{
//这个属性貌似不起作用,还是得配置BackColor不知道是咋回事
private Color nodeNormalBackColor = Color.FromArgb(10, 52, 112);
public Color NodeNormalBackColor
{
get
{
return nodeNormalBackColor;
}
set
{
nodeNormalBackColor = value;
}
}
private Color nodeSelectBackColor = Color.FromArgb(15, 92, 164);
public Color NodeSelectBackColor
{
get
{
return nodeSelectBackColor;
}
set
{
nodeSelectBackColor = value;
}
}
private Color nodeHoverBackColor = Color.FromArgb(103, 161, 207);
public Color NodeHoverBackColor
{
get
{
return nodeHoverBackColor;
}
set
{
nodeHoverBackColor = value;
}
}
private Color nodeTestColor = Color.FromArgb(203, 239, 255);
public Color NodeTestColor
{
get
{
return nodeTestColor;
}
set
{
nodeTestColor = value;
}
}
public BaseTreeView()
{
InitializeComponent();
this.DrawMode = TreeViewDrawMode.OwnerDrawAll;
this.FullRowSelect = true;
this.ItemHeight = 46;
this.HotTracking = true;
this.ShowLines = true;
}
protected override void OnDrawNode(DrawTreeNodeEventArgs e)
{
base.OnDrawNode(e);
//节点背景绘制
if (e.Node.IsSelected)
{
//e.Graphics.DrawImage(Properties.Resources.tree_bg, e.Bounds);
e.Graphics.FillRectangle(new SolidBrush(nodeSelectBackColor), e.Bounds);
}
else if ((e.State & TreeNodeStates.Hot) != 0)//|| currentMouseMoveNode == e.Node)
{
//e.Graphics.DrawImage(Properties.Resources.tree_bg, e.Bounds);
e.Graphics.FillRectangle(new SolidBrush(nodeHoverBackColor), e.Bounds);
}
else if (e.Node.BackColor != null) {
//这个是用于特殊单独需要在代码里设置结点背景颜色时使用
Color color = e.Node.BackColor; // 获取背景色的全部分量
e.Graphics.FillRectangle(new SolidBrush(color), e.Bounds);
}
else{
e.Graphics.FillRectangle(new SolidBrush(nodeNormalBackColor), e.Bounds);
}
//节点头图标绘制
if (e.Node.IsExpanded)
{
e.Graphics.DrawImage(Resources.downdrop_open, e.Node.Bounds.X - 18, e.Node.Bounds.Y + 10);
}
else if (e.Node.IsExpanded == false && e.Node.Nodes.Count > 0)
{
e.Graphics.DrawImage(Resources.downdrop, e.Node.Bounds.X - 18, e.Node.Bounds.Y + 10);
}
//文本绘制
using (Font foreFont = new Font(this.Font, FontStyle.Regular))
using (Brush drawTextBrush = new SolidBrush(nodeTestColor))
{
e.Graphics.DrawString(e.Node.Text, foreFont, drawTextBrush, e.Node.Bounds.Left + 15, e.Node.Bounds.Top + 5);
}
}
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
TreeNode tn = this.GetNodeAt(e.Location);
this.SelectedNode = tn;
}
TreeNode currentNode = null;
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
TreeNode tn = this.GetNodeAt(e.Location);
Graphics g = this.CreateGraphics();
if (currentNode != tn)
{
//绘制当前节点的hover背景
if (tn != null)
OnDrawNode(new DrawTreeNodeEventArgs(g, tn, new Rectangle(0, tn.Bounds.Y, this.Width, tn.Bounds.Height), TreeNodeStates.Hot));
//取消之前hover的节点背景
if (currentNode != null)
OnDrawNode(new DrawTreeNodeEventArgs(g, currentNode, new Rectangle(0, currentNode.Bounds.Y, this.Width, currentNode.Bounds.Height), TreeNodeStates.Default));
}
currentNode = tn;
g.Dispose();
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
//移出控件时取消Hover背景
if (currentNode != null)
{
Graphics g = this.CreateGraphics();
OnDrawNode(new DrawTreeNodeEventArgs(g, currentNode, new Rectangle(0, currentNode.Bounds.Y, this.Width, currentNode.Bounds.Height), TreeNodeStates.Default));
}
}
/// <summary>
/// 防止treeNode闪屏
/// </summary>
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
if (!DesignMode)
{
cp.ExStyle |= 0x02000000;// Turn on WS_EX_COMPOSITED
}
return cp;
}
}
}
4.重新生成程序,在工具箱中就会出现BaseTreeView控件,拉到界面中即可使用
5.在使用界面中为TreeView添加几个数据测试
//创建父节点
TreeNode treeNode = baseTreeView1.Nodes.Add("组织结构");
//创建子节点
TreeNode treeNode_1 = new TreeNode("C");
TreeNode treeNode_2 = new TreeNode("C++");
TreeNode treeNode_3 = new TreeNode("C#");
//给父节点添加子节点
treeNode.Nodes.Add(treeNode_1);
treeNode.Nodes.Add(treeNode_2);
treeNode.Nodes.Add(treeNode_3);
将文字设置大一点,背景颜色设置的深一点更好看