Winforms treeview, recursively check child nodes problem

Using the solution above, I think it is need to paint more detailed steps, how to apply it for those who want to apply it to an already created TreeView. For example, for me, a beginner, this caused difficulties, but here is the solution:

  1. Creating a class "NoClickTree.cs" in your project.

  2. Include this code in new class:

    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);
        }
    }
    
  3. Go to Form1.Designer.cs or "yourWindowWithTreeView".Designer.cs

  4. Find original initialization at the end of the file, something like private System.Windows.Forms.TreeView treeView;

  5. Replace them on private NoClickTree treeView;

  6. In function private void InitializeComponent() find original initialization, something like this.treeView = new System.Windows.Forms.TreeView();

  7. Replace them on this.treeView = new NoClickTree();

  8. Done!

This steps helped me for solve this problem.


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