zoukankan      html  css  js  c++  java
  • 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);
        }
    }


  • 相关阅读:
    Solution -「HEOI/TJOI 2016」「洛谷 P2824」排序
    Solution -「国家集训队」「洛谷 P2839」Middle
    Solution -「CTSC 2018」「洛谷 P4602」混合果汁
    Solution -「CF 793G」Oleg and Chess
    Solution -「AGC 019F」「AT 2705」Yes or No
    Solution -「AGC 013E」「AT 2371」Placing Squares
    使用Spock 单元测试
    Sentinel 熔断等指标如何统计以及如何判断熔断点
    牛客多校第五场自闭
    (单调栈)Largest Rectangle in a Histogram
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/6734937.html
Copyright © 2011-2022 走看看