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

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

相关推荐
王强你强2 分钟前
Spring Boot 启动参数终极解析:如何优雅地控制你的应用?
java·spring boot·后端
Lonwayne8 分钟前
当编程语言有了人格
java·javascript·c++·python·php
qq_5895681028 分钟前
java学习笔记——多线程
java·笔记·学习·intellij-idea
编程的大耳朵38 分钟前
Java 实现将Word 转换成markdown
java·word
nlog3n1 小时前
MySQL 常见面试问题总结
java·数据库·mysql·面试
小灰灰是码农...1 小时前
java中的泛型和反射
java·反射·泛型
申尧强1 小时前
Flink Credit-based机制解析
java·网络·flink
杨凯凡1 小时前
Apache Shiro 全面指南:从入门到高级应用
java·后端·shiro
oioihoii2 小时前
深入解析 C++20 中的 std::bind_front:高效函数绑定与参数前置
java·算法·c++20