TreeView 快速单击时不执行AfterCheck时间

解决方法1:

在AfterCheck事件中,通过System.Threading.Thread.Sleep()来控制函数的执行的最短时间,保证函数执行时间必须大于某个值

解决方法2:

编写列TreeView2

class
TreeView2: TreeView

{

protected override void WndProc(ref Message m)

{

if(m.Msg!=0x203)

{

base.WndProc(ref m);

}

}

}

To reproduce this, start a C#.NET Windows Forms application, drop a TreeView control onto the form and set the CheckBoxes property to true.  Then add an AfterCheck event and paste in this over the Form1 code:

using System;

using System.Windows.Forms;

namespace WindowsFormsApplication1

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

private void Form1_Load(object sender, EventArgs e)

{

TreeNode parent = treeView1.Nodes.Add("Parent");

parent.Nodes.Add("Child1");

parent.Nodes.Add("Child2");

parent.ExpandAll();

}

private void TreeView1AfterCheck(object sender, TreeViewEventArgs e)

{

if (e.Action == TreeViewAction.Unknown)

return;

//If the parent is clicked then set the checkstate of the children to match

if (e.Node.Level == 0)

foreach (TreeNode childNode in e.Node.Nodes)

childNode.Checked = e.Node.Checked;

//If a child is clicked then set the parent to be checked if any children are checked otherwise unchecked

else if (e.Node.Level == 1)

{

TreeNode parent = e.Node.Parent;

bool noneChecked = true;

foreach (TreeNode siblingNode in parent.Nodes)

if (siblingNode.Checked)

noneChecked = false;

parent.Checked = !noneChecked;

}

}

}

}

When you run the application you will see a form with a tree view with a Parent and two Children.  When you check/ uncheck the Parent the Children will check/ uncheck.  Unchecking all the children will uncheck the Parent and checking either Child will check
the Parent if it isn‘t already checked.

This works fine if you click slowly or use the keyboard.

However, if you click the Parent twice quickly (but not quickly enough to be a double-click) then the Tree View doesn‘t fire the AfterCheck event the second time and goes into some weird state where the form freezes up until you click on it (that click is then
ignored).

For example, if I have everything checked and click the Parent twice quickly I will see all the checkboxes clear and then JUST the Parent will end up checked (even though this should be impossible).  At this point hovering the Form will not show where the mouse
has focus and the next click will be ignored!  For example, you can click the close button and the form will remain open but will start to work properly again.

I tried to debug this, it looks as if the NodeMouseClick event does fire both times but the AfterCheck event only fires the first time.

NOTE: this only happens when using the mouse, using the keyboard is fine, you can tap away on the space bar as fast as you like and it always works.

Answer:

The .NET TreeView class heavily customizes mouse handling for the native Windows control in order to synthesize the Before/After events. Unfortunately, they didn‘t get it quite right. When you start clicking fast, you‘ll generate double-click messages. The
native control responds to a double-click by toggling the checked state for the item, without telling the .NET wrapper about it. You won‘t get a Before/AfterCheck event.

It‘s a bug but they won‘t fix it. The workaround is not difficult, you‘ll need to prevent the native control from seeing the double-click event. Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the
toolbox, replacing the existing one.

using System;
using System.Windows.Forms;

class MyTreeView : TreeView {
    protected override void WndProc(ref Message m) {
        // Filter WM_LBUTTONDBLCLK
        if (m.Msg != 0x203) base.WndProc(ref m);
    }
}
时间: 2024-12-09 19:39:13

TreeView 快速单击时不执行AfterCheck时间的相关文章

Java类静态属性、静态块、非静态属性、非静态块、构造函数在初始化时的执行顺序

前言 今天在看Android ContentProvider实现的时候,突然想到了Java类在new的过程中,静态域.静态块.非静态域.非静态块.构造函数的执行顺序问题.其实这是一个很经典的问题,非常考察对Java基础知识的掌握程度.很多面试过程中相信也有这样的问题,趁着周末有时间复习一下. 结论 这里先把整理好的结论抛给大家,然后我在写个程序来验证我们的结论.在Java类被new的过程中,执行顺序如下: 实现自身的静态属性和静态代码块.(根据代码出现的顺序决定谁先执行) 实现自身的非静态属性和

[fw]Linux系统使用time计算命令执行的时间

Linux系统使用time计算命令执行的时间 当测试一个程序或比较不同算法时,执行时间是非常重要的,一个好的算法应该是用时最短的.所有类UNIX系统都包含time命令,使用这个命令可以统计时间消耗.例如: [[email protected] ~]# time ls anaconda-ks.cfg install.log install.log.syslog satools text real 0m0.009s user 0m0.002s sys 0m0.007s 输出的信息分别显示了该命令所花

RAC安装时需要执行4个脚本及意义

RAC安装时需要执行4个脚本 1) $ORACLE_BASE/oraInventory/orainstRoot.sh (clusterware 结束时执行) 2) $CRS_HOME/root.sh (clusterware 结束时执行) 3) $CRS_HOME/bin/vipca.sh(该脚本是在第二个节点执行$CRS_HOME/root.sh时被自动调用) 4) $ORACLE_HOME/root.sh (安装完数据库以后执行) 1. orainstRoot.sh 脚本 1.1 orain

域初始化、静态块及构造方法等在创建类实例时的执行顺序(转载)

在<Core java 2: volumn 1, Edition 5>一书的第四章“对象与类”中讲到域赋值语句.实例块.静态块及构造方法等在创建类实例时的执行顺序,中文译本有些处翻译的不贴切,而英文原书中也有一处错误.本文通过一个小程序来说明类实例构造过程中的语句执行顺序. 程序如下: public class Teststaticblock { public Teststaticblock() { this("second"); System.out.println(&q

怎样计算页面执行的时间?

第一步:建立所有页面的基类 PageBase.cs using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlContro

3.怎样计算页面执行的时间?

页面执行时间:就是从这页的开始执行一直到这页执行完毕所用的时间. 许多网站的的页尾都会显示一个页面执行时间,下面说说如何实现: 首先在一个网页的开头定义一个变量: dim startime startime=timer() 在显示页面执行时间的地方,这个地方应该是页尾的地方: dim endtime endtime=timer() 页面执行时间:<%=FormatNumber((endtime-startime)*1000,3)%>毫秒 3.怎样计算页面执行的时间?,布布扣,bubuko.co

高性能网站优化-确保异步加载脚本时保持执行顺序

<高性能网站建设进阶指南> 脚本如果按照常规方式加载,不仅会阻塞页面中其他内容的下载,还会阻塞脚本后面所有元素的渲染.异步加载脚本可以避免这种阻塞现象,从而提高页面加载速度.但是性能的提升是要付出代价的.代码的异步执行可能会出现竞争状态.简单地说就是页面内部的脚本需要的标示符如果是在外部文件中定义的,而当外部文件异步加载的时候,如果没有保证外部文件和内部脚本执行顺序,很有可能会出现未定义标示符的错误 当异步加载的外部脚本与行内脚本之间存在代码依赖时,就需要通过一种保证执行顺序的方法来整合这两个

Java误区: 静态代码块,会在类被加载时自动执行?

JAVA静态代码块会在类被加载时自动执行? 很多Java开发者的思想,被这个思想深深的轮奸了n遍,传播这个错误思想的博客,在网上一堆,越来越多的人被轮奸. 如:http://blog.csdn.net/leeyu35/article/details/7755304 那么我们程序来证明这句话是错误的: class MyClass1 { static {//静态块 System.out.println("static block "); } } public class Main { Cl

web项目启动时,执行某个方法

1.监听(Listener) web文件添加 <listener> <listener-class>cn.ro.common.InitListener</listener-class> </listener> 添加InitListener类,如下 package cn.ro.common; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener