今天在做一个Winform的程序时,需要用到TreeView的CheckBox的联动,网上找了几个代码,发现总是出问题,最后发现是因为鼠标点击过快的问题,下面是解决方案

这是需要联动的TreeView

 

public static class TreeViewCheck
    {
        /// <summary>
        /// 系列节点 Checked 属性控制
        /// </summary>
        /// <param name="e"></param>
        public static void CheckControl(TreeViewEventArgs e)
        {
            if (e.Action != TreeViewAction.Unknown)
            {
                if (e.Node != null && !Convert.IsDBNull(e.Node))
                {
                    CheckParentNode(e.Node);
                    if (e.Node.Nodes.Count > 0)
                    {
                        CheckAllChildNodes(e.Node, e.Node.Checked);
                    }
                }
            }
        }
        #region 私有方法
        //改变所有子节点的状态
        private static void CheckAllChildNodes(TreeNode pn, bool IsChecked)
        {
            foreach (TreeNode tn in pn.Nodes)
            {
                tn.Checked = IsChecked;

                if (tn.Nodes.Count > 0)
                {
                    CheckAllChildNodes(tn, IsChecked);
                }
            }
        }
        //改变父节点的选中状态,此处为所有子节点不选中时才取消父节点选中,可以根据需要修改
        private static void CheckParentNode(TreeNode curNode)
        {
            bool bChecked = false;

            if (curNode.Parent != null)
            {
                foreach (TreeNode node in curNode.Parent.Nodes)
                {
                    if (node.Checked)
                    {
                        bChecked = true;
                        break;
                    }
                }
                if (bChecked)
                {
                    curNode.Parent.Checked = true;
                    CheckParentNode(curNode.Parent);
                }
                else
                {
                    curNode.Parent.Checked = false;
                    CheckParentNode(curNode.Parent);
                }
            }
        }
        #endregion
    }

以上为联动的代码

原则上这段代码满足以下功能:

 

1.勾选一个节点时,该节点的所有子节点都被勾选

 

 

2.取消勾选一个节点时,该节点的所有子节点都被取消勾选

 

 

3.勾选一个节点时,如果该节点的所有兄弟都被勾选,则该节点的父节点也应被勾选

 

4.取消勾选一个节点时,如果该节点的所有兄弟节点都未被勾选,则该节点的父节点也应被取消勾选

但是,如果点击间隔时间过短(达到类似双击的速度),则TreeView的复选框会显示出现无法正确联动的问题。

 

https://social.msdn.microsoft.com/Forums/windows/en-US/9d717ce0-ec6b-4758-a357-6bb55591f956/possible-bug-in-net-treeview-treenode-checked-state-inconsistent?forum=winforms  这是解决方案

 

class TreeViewEnhanced:TreeView
    {
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x203) { m.Result = IntPtr.Zero; }
            else base.WndProc(ref m);
        }
    }

然后引用此TreeViewEnhanced即可

posted on 2017-05-03 22:15  微澜  阅读(1613)  评论(0)    收藏  举报