zoukankan      html  css  js  c++  java
  • 自定义 TreeView 第三种状态(C#自定义控件)

    本文核心部分采用 http://blog.csdn.net/am2004/article/details/1621349 此网站代码.
    在增加了部份事件的同时,将点击图片更改节点选中状态 这一小地方作了改进.
    目前点击节点前的加减符号不会更改节点状态.
     
    此处有添加一个含有三个图片的ImageList 控件,里面 0 不选 1 部分选 2 选中 三个ICO 文件,大家可网上下载.
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace SimpleCustomControl
    {
        public partial class MyTreeView : TreeView
        {
            private int imageWidth = 0x12;
    
            public MyTreeView()
            {
                InitializeComponent();
                // 如果更改 ImageList 中图片大小,此处设置可能有用.未测试.可注释掉.
                imageWidth = imageList1.ImageSize.Width + 2;
            }
    
            //规则1:取消选定
            //规则1.1:检查是否有子节点,需清除所有子节点的选定状态;
            //规则1.2:检查是否有父节点,如有,则根据兄弟节点的选定状态修改父节点的选定状态
            //规则2:选定
            //规则2.1:检查是否有子节点,设置所有子节点为选定状态
            //规则2.2:检查是否有父节点,如有,则根据兄弟节点的选定状态修改父节点的选定状态
            /// <summary>
            /// 鼠标点击节点触发事件
            /// </summary>
            private void MyTreeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
            {
                if (e.Button == MouseButtons.Left)
                {
                    Rectangle rc = e.Node.Bounds;
                    rc = new Rectangle(rc.X - imageWidth, rc.Y, rc.Width + imageWidth, rc.Height);
                    if (rc.Contains(e.Location))
                    {
                        if (e.Node.Level == 0 && e.Node.Index == 0)
                            NodeUnSelected();
                        else
                            NodeClick(e.Node);
                    }
                }
            }
    
            /// <summary>
            /// 节点点击
            /// </summary>
            /// <param name="tn">点击的节点</param>
            public void NodeClick(TreeNode tn)
            {
                if (tn.ImageIndex == 2)
                {
                    NodeUnSelected(tn);
                }
                else
                {
                    NodeSelected(tn);
                }
            }
    
            /// <summary>
            /// 不管现在节点状态
            /// 将节点设置为选中
            /// </summary>
            /// <param name="tn">待更改状态的节点</param>
            public void NodeSelected(TreeNode tn)
            {
                tn.SelectedImageIndex = 2;
                tn.ImageIndex = 2;
                SetNodeImg21(tn);
                SetNodeImg22(tn);
            }
    
            /// <summary>
            /// 不管现在节点状态
            /// 去掉节点选中状态
            /// </summary>
            /// <param name="tn">待更改状态的节点</param>
            public void NodeUnSelected(TreeNode tn)
            {
                tn.SelectedImageIndex = 0;
                tn.ImageIndex = 0;
                SetNodeImg11(tn);
                SetNodeImg12(tn);
            }
    
            /// <summary>
            /// 查找节点状态 是否被选中
            /// </summary>
            /// <param name="tn">查看的节点</param>
            /// <returns>节点是否被选中</returns>
            public bool NodeIsChecked(TreeNode tn)
            {
                if (tn.ImageIndex == 1 || tn.ImageIndex == 2)
                    return true;
                return false;
            }
    
            public CheckState NodeCheckState(TreeNode tn)
            {
                switch (tn.ImageIndex)
                {
                    case 1:
                        return CheckState.Indeterminate;
                    case 2:
                        return CheckState.Checked;
                    case 0:
                    default:
                        return CheckState.Unchecked;
                }
            }
    
            /// <summary>
            /// 将所有子节点全不选
            /// </summary>
            public void NodeUnSelected()
            {
                foreach (TreeNode tn in this.Nodes)
                {
                    NodeUnSelected(tn);
                }
            }
    
            /// <summary>
            /// 将所有子节点全选
            /// </summary>
            public void NodeSelected()
            {
                foreach (TreeNode tn in this.Nodes)
                {
                    NodeSelected(tn);
                }
            }
    
            //设置节点选定状态:
            //规则.1:检查是否有子节点,需清除所有子节点的选定状态;
            void SetNodeImg11(TreeNode tn)
            {
                foreach (TreeNode t in tn.Nodes)
                {
                    t.SelectedImageIndex = 0;
                    t.ImageIndex = 0;
                    if (t.Nodes.Count != 0)
                        SetNodeImg11(t);
                }
            }
    
            //设置节点选定状态:
            //规则.2:检查是否有父节点,如有,则根据兄弟节点的选定状态修改父节点的选定状态
            void SetNodeImg12(TreeNode tn)
            {
                if (tn.Parent == null)
                    return;
                int Img0Num = 0, Img1Num = 0, Img2Num = 0;
                //统计同级节点选中情况
                foreach (TreeNode t in tn.Parent.Nodes)
                {
                    switch (t.ImageIndex)
                    {
                        case 1:
                            Img1Num++;
                            break;
                        case 2:
                            Img2Num++;
                            break;
                        case 0:
                        default:
                            Img0Num++;
                            break;
                    }
                }
                //如果同级节点选中和未选中的都有
                if (Img1Num != 0 || (Img0Num != 0 && Img2Num != 0))
                {
                    tn.Parent.SelectedImageIndex = 1;
                    tn.Parent.ImageIndex = 1;
                }
                else
                {
                    tn.Parent.StateImageIndex = 0;
                    tn.Parent.ImageIndex = 0;
                }
                SetNodeImg12(tn.Parent);
            }
    
            //设置节点选定状态:
            //规则.1:检查是否有子节点,设置所有子节点为选定状态
            void SetNodeImg21(TreeNode tn)
            {
                foreach (TreeNode t in tn.Nodes)
                {
                    t.SelectedImageIndex = 2;
                    t.ImageIndex = 2;
                    if (t.Nodes.Count != 0)
                    {
                        SetNodeImg21(t);
                    }
                }
            }
    
            //设置节点选定状态:
            //规则.2:检查是否有父节点,如有,则根据兄弟节点的选定状态修改父节点的选定状态
            void SetNodeImg22(TreeNode tn)
            {
                if (tn.Parent == null)
                    return;
                int Img0Num = 0, Img1Num = 0, Img2Num = 0;
                foreach (TreeNode t in tn.Parent.Nodes)
                {
                    //if (t.ImageIndex == 0)
                    //    Img0Num++;
                    //if (t.ImageIndex == 1)
                    //    Img1Num++;
                    //if (t.ImageIndex == 2)
                    //    Img2Num++;
                    switch (t.ImageIndex)
                    {
                        case 1:
                            Img1Num++;
                            break;
                        case 2:
                            Img2Num++;
                            break;
                        case 0:
                        default:
                            Img0Num++;
                            break;
                    }
                }
                if (Img1Num != 0 || (Img0Num != 0 && Img2Num != 0))
                {
                    tn.Parent.SelectedImageIndex = 1;
                    tn.Parent.ImageIndex = 1;
                }
                //else if (Img1Num == 0 && Img2Num == 0)
                //{
                //    tn.Parent.SelectedImageIndex = 0;
                //    tn.Parent.ImageIndex = 0;
                //}
                else
                {
                    tn.Parent.StateImageIndex = 2;
                    tn.Parent.ImageIndex = 2;
                }
                SetNodeImg22(tn.Parent);
            }
    
        }
    }
  • 相关阅读:
    super与this的区别?
    springboot(4)-thymeleaf
    springboot(3)-自定义josn
    springboot(2)-Http协议接口开发
    springboot(1)-HelloWorld
    SpringSecurityOauth2.0
    Docker 应用部署
    RabbitMQ02
    RabbitMQ01
    011通用寄存器
  • 原文地址:https://www.cnblogs.com/z5337/p/3303014.html
Copyright © 2011-2022 走看看