TreeView 三种状态 没多大变化 只是增加了很多函数以方便调用

using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;

namespace SimpleCustomControl
{
    [ToolboxBitmap(typeof(TreeView))]
    public partial class MyTreeView : TreeView
    {
        private int imageWidth = 0x12;

        private bool isFirstNodeDifferent = true;
        [Category("行为"), DefaultValue(true), Description("确定根节点第一个节点是否作为取消所择使用。")]
        public bool IsFirstNodeDifferent
        {
            get { return isFirstNodeDifferent; }
            set { isFirstNodeDifferent = value; }
        }

        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 (isFirstNodeDifferent && 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;
        }

        private bool nodeIsAllChecked;
        /// <summary>
        /// 返回整个TreeView 选中状态
        /// </summary>
        /// <returns>返回选中状态信息</returns>
        [Browsable(false)]
        public bool NodeIsAllChecked
        {
            get
            {
                if (isFirstNodeDifferent)
                {
                    // 两种方式 两种效率  未测试哪个更效率
                    //foreach (TreeNode tn in Nodes)
                    //{
                    //    if (tn.Index != 0 && NodeCheckState(tn) != CheckState.Checked)
                    //        return false;
                    //}
                    int count = Nodes.Count;
                    for (int i = 1; i < count; i++)
                    {
                        if (NodeCheckState(Nodes[i]) != CheckState.Checked)
                            return false;
                    }
                }
                else
                {
                    foreach (TreeNode tn in Nodes)
                    {
                        if (NodeCheckState(tn) != CheckState.Checked)
                            return false;
                    }
                }
                return true;
            }
        }

        /// <summary>
        /// 返回指定节点选中状态
        /// 有三种状态 Checked 选中 Indeterminate 部分选中 Unchecked 未选中
        /// </summary>
        /// <param name="tn">节点是否被选中</param>
        /// <returns>返回选中状态信息</returns>
        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);
            }
            if (isFirstNodeDifferent && Nodes.Count > 0)
            {
                Nodes[0].SelectedImageIndex = 0;
                Nodes[0].ImageIndex = 0;
            }
        }

        //设置节点选定状态:
        //规则.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);
        }


    }
}

 

posted on 2013-09-06 12:59  z5337  阅读(401)  评论(0编辑  收藏  举报