• c# TreeView实现三种选中状态


    c# 项目中需要实现树状选项的勾选,有全选,半勾选,不选的状态。

    因原控件中只有勾选和不勾选两种状态,所以半勾选状态需要使用代码绘制和自行定义。

    勾选:Node.Checked=true

    不勾选: Node.Checked=false

    半勾选: Node.Checked=false && Node.ToolTipText="部分勾选"

    注意:半勾选状态需要重新绘制控件需要设置控件属性DrawMode为OwnerDrawText或者OwnerDrawAll

    核心逻辑一:设置父亲节点的选中状态(选中一个节点时,判断兄弟节点是否全选;取消一个节点时,需要判断兄弟节点是否有选中状态和半选中状态。由此来判断父节点的选中状态)

     //取消节点选中状态之后,取消所有父节点的选中状态
            private void setParentNodeCheckedState(TreeNode currNode, bool state)
            {
                TreeNode parentNode = currNode.Parent; //获得当前节点的父节点
                parentNode.Checked = state; //设置父节点的选中状态
                if (state == false) //当状态设置为false 
                {
                    int flag = 0;
                    foreach (TreeNode broNode in parentNode.Nodes) //判断该父节点的子节点中,是否有半勾选状态的选项
                    {
                        if (broNode.Checked||broNode.ToolTipText.Equals("部分勾选"))
                        {
                            flag = 1;
                        }
                    }
                    if (flag == 1) // 有设置父节点为半勾选状态
                    {
                        parentNode.ToolTipText = "部分勾选";
                        parentNode.Checked = false;
                    }
                    else  
                    {   //设置父节点状态为 未勾选
                        parentNode.ToolTipText = "";
                        parentNode.Checked = true;
                        parentNode.Checked = false;  //需要改变节点的Checked状态,才能重新绘制控件;
                    }
                }
                else {   //当父节点设置为选中状态时
                    int flag = 0;
                    foreach (TreeNode broNode in parentNode.Nodes)//判断该父节点的子节点下是否有未选中的节点。
                    {
                        if (!broNode.Checked)
                        {
                            flag = 1;
                        }
                    }
                    if (flag == 1)
                    {
                        parentNode.ToolTipText = "部分勾选";
                        parentNode.Checked = false;
                    }
                    else
                    {
                        parentNode.ToolTipText = "";
                        parentNode.Checked = true;
                    }
                }
                if (currNode.Parent.Parent != null) //如果父节点之上还有父节点
                {  
                    setParentNodeCheckedState(currNode.Parent, state); //递归调用
                }
            }

    核心逻辑二:设置子节点的选中状态

     //选中节点之后,选中节点的所有子节点
            private void setChildNodeCheckedState(TreeNode currNode, bool state)
            {
                TreeNodeCollection nodes = currNode.Nodes; //获取所有子节点
                if (nodes.Count > 0) //存在子节点
                    foreach (TreeNode tn in nodes) 
                    {
                        tn.Checked = state;
                        tn.ToolTipText = "";
                        setChildNodeCheckedState(tn, state);//递归调用子节点的子节点
                    }
            }

    设置控件监听属性AfterCheck

      private void skinTreeView1_AfterCheck(object sender, TreeViewEventArgs e)
            {
                if (e.Action == TreeViewAction.ByMouse) //鼠标点击
                {
                    //textBox1.Text = e.Node.Text;
                    if (e.Node.Checked) //选中
                    {                    e.Node.ToolTipText = "";
                        //选中节点之后,选中节点的所有子节点
                        setChildNodeCheckedState(e.Node, true);
                        if (e.Node.Parent != null)
                        {
                            setParentNodeCheckedState(e.Node, true);
                        }
                    }  
                    else  //取消选中
                    {
                        e.Node.ToolTipText = "";
                        //取消节点选中状态之后,取消所有子节点的选中状态
                        setChildNodeCheckedState(e.Node, false);
                        //如果节点存在父节点,取消父节点的选中状态
                        if (e.Node.Parent != null)
                        {
                            setParentNodeCheckedState(e.Node, false);
                        }
                    }
                }
            }

    设置重新绘制监听DrawNode,为半勾选状态绘制新图案

      private void ClassTreeList_DrawNode(object sender, DrawTreeNodeEventArgs e)
            {
                if (e.Bounds.Location.X <= 0)
                {
                    return;
                }
                var treeview = sender as TreeView;
                var brush = Brushes.Black; //黑色
                if (e.Node.ToolTipText.EndsWith("部分勾选")&&e.Node.Checked==false)
                {  //判断为半勾选状态
                    var location = e.Node.Bounds.Location;
                    location.Offset(-10, 7);
                    var size = new Size(7, 7);
                    e.Graphics.FillRectangle(brush, new Rectangle(location, size)); //这里绘制的是正方形
                }
                //绘制文本
                e.Graphics.DrawString(e.Node.Text, treeview.Font, brush, e.Bounds.Left, e.Bounds.Top);
            }
  • 相关阅读:
    [js对象]JS入门之Date对象
    从Microsoft SqlServer 2005中返回有一定顺序的记录集
    [js对象]JS入门之Global对象
    [JS.IntelliSense]VS2008(Orcas) So Cool
    即插即用插件式框架的程序集处理遐想(TypeFinder)
    [C#3.0体验]Orcas中内置的LinQ,XLinQ[DLinQ]扩展方法
    [ASP.NET入门]页面生命周期
    [IE]IE6&IE7运行于同一个系统中
    [js对象]JS入门之Boolean&Object对象
    RSS(Really Simple Syndication)常用标签
  • 原文地址:https://www.cnblogs.com/yhood/p/11532787.html
Copyright © 2020-2023  润新知