C#重写treeView控件

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

将文字设置大一点,背景颜色设置的深一点更好看

相关推荐
小雅痞1 分钟前
[Java][Leetcode middle] 55. 跳跃游戏
java·leetcode
com未来7 分钟前
使用 NSSM 安装 Tomcat 11.0.6 为 Windows 服务
java·windows·tomcat
TDengine (老段)12 分钟前
基于 TSBS 标准数据集下 TimescaleDB、InfluxDB 与 TDengine 性能对比测试报告
java·大数据·开发语言·数据库·时序数据库·tdengine·iotdb
养军博客14 分钟前
spring boot3.0自定义校验注解:文章状态校验示例
java·前端·spring boot
lgily-122515 分钟前
常用的设计模式详解
java·后端·python·设计模式
IT成长史21 分钟前
deepseek梳理java高级开发工程师微服务面试题
java·微服务
茶本无香21 分钟前
Feign+Resilience4j实现微服务熔断机制:原理与实战
java·微服务·feignclient·熔断·resilience4j
遇见火星22 分钟前
Ansible模块——从控制节点向目标主机复制文件!
java·服务器·ansible
小码ssim24 分钟前
通过POI实现对word基于书签的内容替换、删除、插入
java·word
香饽饽~、39 分钟前
函数式方法的实现(JDK8+)
java·服务器