C#三态及可禁用TreeView树形视图实现

本文介绍如何在C#中实现一个具备勾选、不勾选、部分勾选三态,并且可以禁用不勾选节点的TreeView。通过重绘CheckBox并利用TreeNode的Tooltip来定义节点状态,当节点状态变化时,实现上下联动更新。文章提供详细思路、实现步骤及完整代码。
摘要由CSDN通过智能技术生成

因为项目需要,需要生成一个TreeView,具体的要求是:实现每个节点有:勾选(所有子节点勾选)、不勾选(所有子节点不勾选)、部分勾选(部分子节点勾选),三种状态。同时,还要能禁用不勾选节点,只能显示,不能勾选。(这里没有做禁用可勾选节点,因为项目不需要~,大家也可以按照我这个思路去实现)
查了很多资料,下了很多代码,发现没有能够完全实现上述的方法,有人说用TreeViewde的icon来实现,但是这样就相当于把TreeeView的check事件给阉割抛弃了,只能用select事件,同时要勾选某个节点必须要选中这个节点才能实现,这样的用户体验是不够好的。
自己决定撸起袖子做一个,作为一个接触c#不到两周的人,不足之处,批评指正。

整个实现方案,参考了以下两位博主的内容:

整体思路

重画TreeView的CheckBox,为了省事,采取覆盖的方式去重画,因此,本方法目前只适合win7以上系统界面,xp上会……不太好看,因为xp的复选框太大,会盖不住,下步会增加改进
1.利用每个TreeNode的ToolTips对每个节点的状态进行定义
2.ToolTips的值为1:勾选、2:不选、3:部分勾选
3.当TreeNode.foreColor为Gray时,灰色,代表这个节点被禁用
4.当然也可以用TreeNode的name、Tag属性进行定义,由于我的项目都用到了,不得不用ToolTips进行定义。
5.重画treeView的复选框,画复选框时,先判断foreColor是否是灰色,是灰色则画禁用框,不是则根据TreeNode的ToolTips来画形态。

到此,一个三态加禁用不可勾选的的TreeView就定义好了,在需要设置的时候,通过设置TreeNode的foreColor和ToolTips即可 。

下面设置当一个节点被勾选或勾除时,上下联动的机制
这个机制我专门定义了一个静态类来操作TreeViewHandler
当一个节点被勾选时,需要改变它本身、所有子节点、所有父节点的状态,
1. 本身:
a) 如果本身不是被禁用节点则打钩
b) 如果所有子节点中有禁用节点,则本身改成部分选中
2. 子节点:
a) 方法同本身
3. 父节点
a) 判断本身的所有兄弟节点的状态
b) 都勾选,则父节点为勾选
c) 否则,则父节点为部分勾选
当一个节点被勾除时
1. 本身:
a) 变成勾除状态
2. 子节点
a) 都变成勾除状态
3. 父节点
a) 判断本身所有兄弟节点的状态
b) 都勾除,则父节点为勾除
c) 否则,父节点为部分勾除

由于节点在做联动时,并不能百分之百引发TreeView的重画机制,(当节点在勾选状态变成部分勾选状态时就不会,双击某个节点复选框时,节点的重画机制就会延迟),所以专门定义了一个方法setNodeState()做节点的勾选与勾除,主要做法实际是将这个节点反复勾一次,确保系统对其进行重画。
最后附上代码:

具体代码

MyTreeView.cs

namespace TreeView
{
    enum CheckState
    {
        选中,
        不勾选,
        部分被选,
        禁用
    }
    /// <summary>
    /// 本类复写TreeView,实现了复选框的三态功能,且每个节点能够被禁用
    /// 使用方法:
    /// 勾选一个节点,将其ToolTipsText 设置为“1”
    /// 取消勾选一个节点,将其ToolTipsText 设置为“2”
    /// 部分勾选一个节点,将其ToolTipsText 设置为“3”
    /// 禁用某个节点(不勾选),将其ForeColor设置为 Color.gray
    /// </summary>
    public class MyTreeView : System.Windows.Forms.TreeView
    {
        private Brush b = null;//节点字体颜色  
        private Point p;//画CheckBox的位置  
        public MyTreeView()
        {
            this.DrawMode = TreeViewDrawMode.OwnerDrawText;//自己画文本  
        }
        protected override void OnDrawNode(DrawTreeNodeEventArgs e)
        {
            b = Brushes.Black;//默认字体为黑色  
            if (e.Node.ForeColor == Color.Gray)
            {
                drawCheckBox(CheckState.禁用, e);
            }
            else//画可选择框
            {
                switch (e.Node.ToolTipText)
                {
                    case ("1" ) :
                        drawCheckBox(CheckState.选中, e);
                        break;
                    case "2":
                        drawCheckBox(CheckState.不勾选, e);
                        break
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值