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 nodes 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.