2019独角兽企业重金招聘Python工程师标准>>>

今天我在试着做一个C#树形视图(TreeView)控件,要求在每个节点前面添加一个可用于打勾的复选框,并要求复选框有上下级联动的效果。现在在网上能查到挺多满足这类功能的代码,原本我也以为这是一件挺简单的事情,不过实际情况并非如此。

我们建立一个C#窗体应用程序,主窗体取名FormMain,在里面放置一个Dock为Fill的TreeView控件treeTest。注意该控件的CheckBoxes属性要设置为True才能显示复选框。

在FormMain中写入代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace TreeViewCheckTest
{public partial class FormMain : Form{public FormMain(){InitializeComponent();}private void FormMain_Load(object sender, EventArgs e){//生成测试数据TreeNode treeNode11 = new TreeNode("蜉蝣目");treeNode11.Nodes.Add("等蜉科");treeNode11.Nodes.Add("四节蜉科");treeNode11.Nodes.Add("扁蜉科");treeNode11.Nodes.Add("蜉蝣科");treeNode11.Nodes.Add("河花蜉科");TreeNode treeNode12 = new TreeNode("蜚蠊目");treeNode12.Nodes.Add("姬蠊科");treeNode12.Nodes.Add("硕蠊科");treeNode12.Nodes.Add("地鳖科");treeNode12.Nodes.Add("隐尾蠊科");TreeNode treeNode13 = new TreeNode("螳螂目");treeNode13.Nodes.Add("螳科");treeNode13.Nodes.Add("花螳科");treeNode13.Nodes.Add("锥头螳科");treeNode13.Nodes.Add("细足螳科");TreeNode treeNode14 = new TreeNode("其他类型昆虫");TreeNode treeNode1 = new TreeNode("昆虫纲");treeNode1.Nodes.AddRange(new TreeNode[] { treeNode11, treeNode12, treeNode13, treeNode14 });treeTest.Nodes.Add(treeNode1);treeTest.ExpandAll();}/// <summary>/// 关联锁/// </summary>bool needSetRelateCheck = true;/// <summary>/// 树节点前复选框发生变化时触发/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void treeViewEnhanced1_AfterCheck(object sender, TreeViewEventArgs e){if (!needSetRelateCheck){return;}//1、判断当前操作节点勾还是不勾//如果勾,当前节点下所有子节点都要勾上//如果不勾,下面子节点全部不勾TreeNode node = e.Node;if (node.Checked){node.Nodes.OfType<TreeNode>().ToList().ForEach(x => x.Checked = true);}else{node.Nodes.OfType<TreeNode>().ToList().ForEach(x => x.Checked = false);}//2、如果当前节点被勾选,如果当前节点被勾选,则其上溯所有祖先节点都要勾//否则判断当前节点所有兄弟节点是否有勾,有则父节点要勾,没有则父节点不勾needSetRelateCheck = false; //为本方法上锁,确保连带影响不会运行本事件中代码if (node.Checked){while (node.Parent != null){node = node.Parent;node.Checked = true;}}else{while (node.Parent != null){node = node.Parent;bool hasCheckedChild = false;foreach (TreeNode child in node.Nodes){if (child.GetHashCode() == e.Node.GetHashCode()){continue;}if (child.Checked){hasCheckedChild = true;break;}}if (!hasCheckedChild){node.Checked = false;}else{break;}}}needSetRelateCheck = true; //为本方法解锁}}
}

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

  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

大牛的答案中说这是一个WindowsVista版本的BUG,不过我现在的32位Win7也会出现此问题。

解决这个问题的方法是将TreeView封装一层,并重写一下WndProc函数:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace TreeViewCheckTest
{class TreeViewEnhanced : TreeView{protected override void WndProc(ref Message m){if (m.Msg == 0x203) { m.Result = IntPtr.Zero; }else base.WndProc(ref m);}}
}

实现了TreeViewEnhanced类后,将FormMain中的TreeView控件替换为我们刚刚实现的TreeViewEnhanced就好啦!

END

转载于:https://my.oschina.net/Tsybius2014/blog/551358

C# - 解决TreeView控件复选框联动时鼠标点击过快导致的显示不正确的问题相关推荐

  1. winform中TreeView控件复选框联动时鼠标点击过快导致的显示不正确的问题

    今天我在试着做一个C#树形视图(TreeView)控件,要求在每个节点前面添加一个可用于打勾的复选框,并要求复选框有上下级联动的效果.现在在网上能查到挺多满足这类功能的代码,原本我也以为这是一件挺简单 ...

  2. 关于怎么获取Repeater控件复选框选中的那一行的数据

    关于怎么获取Repeater控件复选框选中的那一行的数据 1.首先你要有一个repeater控件,并且里面有复选框控件 2.废话不多话,直接上代码 Dim i As Integer'Car是repea ...

  3. 5、Web 窗体的基本控件——复选框控件和复选组控件(CheckBox 和 CheckBoxList)

    5.Web 窗体的基本控件--复选框控件和复选组控件(CheckBox 和 CheckBoxList) 复选框控件和复选组控件(CheckBox 和 CheckBoxList) 前端 <%@ P ...

  4. html5 多选框控件,复选框和单选框都属于控件吗

    单选框和复选框的区别是什么? 单选框和复选框的区别是什么? 详细一点-. (1)复选框可以允许你选择多个设置,而单选框则允许你选择一个设置: 这两个选框的区别是一个通过用圆圈表示,一个通过用方框表示. ...

  5. 扩展GridView控件(7) - 行的指定复选框选中时改变行的样式

    GridView既强大又好用.为了让它更强大.更好用,我们来写一个继承自GridView的控件. [索引页] [×××] 扩展GridView控件(7) - 行的指定复选框选中时改变行的样式 作者:w ...

  6. html下拉复选框联动,HTML : CheckBox 复选框成组联动(JavaScript)

    在页面中,经常需要控制一组 CheckBox 的选中状态,常用的操作有: 1.通过一个或者多个复选框来控制一组 CheckBox 的选中状态. 2.根据一组 CheckBox 的选中状态来决定某些控件 ...

  7. 在WPF TreeView中使用复选框

    目录 介绍 背景 细节决定成败 功能要求 将Smarts放入ViewModel 树视图配置 将TreeViewItem变成ToggleButton Aero主题中的复选框错误 介绍 本文回顾了一个WP ...

  8. html怎样创建复选框,如何使用可点击标签创建HTML复选框

    方法1:包装标签 将复选框包装在 label 标记内: Text 方法2:使用for属性 使用 for 属性(匹配复选框 id ): Text NOTE :页面上的ID必须是唯一的! 解释 由于其他答 ...

  9. 在reader中勾选pdf复选框_如何让文件夹内PDF图片显示图标

    原标题:如何让文件夹内PDF图片显示图标 电脑小知识,值得收藏 有些网友Win 7系统的64位版本安装了Adobe Reader软件之后,发现PDF文件在系统中无法显示缩略图,这样看起来不是很方便,每 ...

最新文章

  1. mongodb更新数据,查找相同的id,有重复的,就更新。
  2. 在河北当中学老师用不用考计算机,河北省教育厅出台新方案 师范生当教师也需考证...
  3. Ansible系列--Copy模块
  4. mysql 修改root 密码
  5. mycat分布式mysql中间件(自增主键)
  6. fanuc 机床,加工中心通信总结,机床联网监控系统
  7. 安全方面的文章+VC知识库
  8. TP框架的目录结构总结
  9. 微信小程序订阅服务器,微信小程序之模板订阅消息
  10. 一篇文章为何能引起公众对联想那么多的争议?
  11. Android防止连点非常简单的操作
  12. Android开发网上的一些重要知识点[经验分享]
  13. 本地生成RDL报表文件的创建工具
  14. 闪电对计算机或网络设备的威胁,计算机网络的雷电防护_计算机网络
  15. java puppeteer生成pdf_PuppeteerSharp导出PDF(带页码)
  16. 上线长辈模式,饿了么能拿下银发市场吗?
  17. 结对项目——最长英语单词链
  18. (亲自整理)如何让你的C盘立马多出来20G空间
  19. ewebeditor文件上传漏洞2.8.0版本(漏洞复现)
  20. 海龟 (turtle) 画图终极实战:小海龟挑战大迷宫游戏

热门文章

  1. 某个网站(比如CSDN、GitHub)突然打开、加载很慢,有些途径访问正常、其他网站访问正常,可尝试指定域名服务器的IP地址,不走DNS查询。
  2. java怎么设置按钮居中对齐_button按钮居中
  3. 基本初等函数的求导公式
  4. Mothur6进阶_Mothur扩增子基因序列分析_基于系统型phylogeny的多样性指数分析
  5. pg_tables,pg_indexes,pg_views,pg_user,pg_roles,pg_rules,pg_settings详解
  6. 面试题CSS03【21-10-16】
  7. html网页图片滚动代码用css和div,DIV+CSS网页图片滚动源代码
  8. 光电旋转编码器使用方法及稳定的单片机程序
  9. 变形的生产者消费者问题PV解法
  10. 虚幻引擎5 C++编程学习4