Winforms树视图,递归检查子节点问题

Winforms树视图,递归检查子节点问题,winforms,treeview,checkbox,Winforms,Treeview,Checkbox,以下代码直接取自Microsoft的 您将它放在一个包含treeview的表单中,并调用节点_AfterCheck on(惊喜,惊喜),即treeview AfterCheck事件。然后它递归地检查或取消选中树视图上的子节点 但是,如果您确实尝试了它,并以足够快的速度多次单击同一个treeview复选框,则子节点的签出将与父节点不同步。您可能需要几个级别的子级,总共可能有100个子级,以便UI更新足够慢,能够注意到这种情况 我尝试了一些方法(例如在node_AfterCheck开始时禁用tree

以下代码直接取自Microsoft的

您将它放在一个包含treeview的表单中,并调用节点_AfterCheck on(惊喜,惊喜),即treeview AfterCheck事件。然后它递归地检查或取消选中树视图上的子节点

但是,如果您确实尝试了它,并以足够快的速度多次单击同一个treeview复选框,则子节点的签出将与父节点不同步。您可能需要几个级别的子级,总共可能有100个子级,以便UI更新足够慢,能够注意到这种情况

我尝试了一些方法(例如在node_AfterCheck开始时禁用treeview控件,并在结束时重新启用),但仍然会出现不同步的问题


有什么想法吗?

NET TreeView类为本机Windows控件大量定制鼠标处理,以便合成前后事件。不幸的是,他们没有完全正确。当您开始快速单击时,将生成双击消息。本机控件通过切换项的选中状态来响应双击,而不告诉.NET包装器。您将不会得到前/后检查事件

这是一个错误,但他们不会修复它。解决方法并不困难,您需要防止本机控件看到双击事件。向项目中添加一个新类并粘贴如下所示的代码。编译。从工具箱顶部删除新控件,替换现有控件

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);
    }
}

使用上面的解决方案,我认为需要绘制更详细的步骤,如何将其应用于那些想要将其应用于已经创建的树视图的人。例如,对于我这个初学者来说,这造成了一些困难,但解决办法如下:

  • 在项目中创建类“NoClickTree.cs”

  • 在新类中包含此代码:

    public class NoClickTree : TreeView
    {
        protected override void WndProc(ref Message m)
        {
            // Suppress WM_LBUTTONDBLCLK
            if (m.Msg == 0x203) { m.Result = IntPtr.Zero; }
            else base.WndProc(ref m);
        }
    }
    
  • 转到
    Form1.Designer.cs
    yourWindowWithTreeView.Designer.cs

  • 在文件末尾查找原始初始化,类似于
    private System.Windows.Forms.TreeView TreeView

  • 私有NoClickTree树视图中替换它们

  • 在函数
    private void InitializeComponent()
    中查找原始初始化,类似于
    this.treeView=new System.Windows.Forms.treeView()

  • this.treeView=new NoClickTree()上替换它们

  • 完成了


  • 这些步骤帮助我解决了这个问题。

    为什么他们不解决它?@Kamil因为
    winforms
    即将消亡。他们迟早都会切换到
    WPF
    。我同意这一点,但我对微软的发展方向不满意。怪异的Windows 8,怪异的Windows Phone,怪异的VS2012。事情更美好,但他们忘记了使用的功能。一个解决方案并不困难,除非复选框是internet explorer中的复选框。2017在这里签入,感谢这个解决方案,winforms还没有死。我已将我的解决方案发布到这一个的子主题中:
    public class NoClickTree : TreeView
    {
        protected override void WndProc(ref Message m)
        {
            // Suppress WM_LBUTTONDBLCLK
            if (m.Msg == 0x203) { m.Result = IntPtr.Zero; }
            else base.WndProc(ref m);
        }
    }