开发者

Check or uncheck all TreeViewItem children

开发者 https://www.devze.com 2023-01-08 14:30 出处:网络
My project is WinForms, C#. I have a form with TreeView with CheckBoxes set to true. There are a few root nodes each having multiple children nodes.

My project is WinForms, C#.

I have a form with TreeView with CheckBoxes set to true. There are a few root nodes each having multiple children nodes.

I'd like to have all children n开发者_JS百科odes to have the same checked/unchecked state as their parent. I wrote the following event handler:

private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
  // return in case the event is induced by the code below
  if (e.Action == TreeViewAction.Unknown)
  {
    return;
  }
  System.Diagnostics.Debug.WriteLine(string.Format("Checked - {0}", e.Node.Checked));
  foreach (TreeNode subNode in e.Node.Nodes)
  {
    subNode.Checked = e.Node.Checked;
  }
}

However, this works quite strange when clicking on the parent quickly. I can easily reproduce this by quickly checking and unchecking parent so that subnodes are all checked while parent is already unchecked.

How to do this more correctly?


This is a bug introduced by the Vista version of the native TreeView control. It responds to a double-click by automatically toggling a check box. But without raising the BeforeCheck and AfterCheck events. The Windows Forms TreeView class wrapper wasn't updated to deal with this problem.

The fix is simple enough, you need to prevent the native control from seeing the double-click. Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form, replacing the existing tree view.

using System;
using System.Windows.Forms;

public class MyTreeView : TreeView {
  protected override void WndProc(ref Message m) {
    // Suppress WM_LBUTTONDBLCLK
    if (m.Msg == 0x203) { m.Result = IntPtr.Zero; }
    else base.WndProc(ref m);
  }
}


We add a timer that starts/resets when you click. If the timer fire after 500ms the actual update code is executed.

This will fix the fast clicking after each other.


When you click quickly, the double click event is firing instead of the single click. The single click behavior is what changes the checked status. If you have done something to override the normal double click behavior, make sure to account for that on the child nodes.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号