Winforms treeview,递归检查子节点问题

Phi*_*lch 15 checkbox treeview winforms

以下代码直接来自Microsoft,网址http://msdn.microsoft.com/en-us/library/system.windows.forms.treeview.aftercheck%28VS.80%29.aspx.

  // Updates all child tree nodes recursively.
  private void CheckAllChildNodes(TreeNode treeNode, bool nodeChecked)
  {
   foreach (TreeNode node in treeNode.Nodes)
   {
    node.Checked = nodeChecked;
    if (node.Nodes.Count > 0)
    {
     // If the current node has child nodes, call the CheckAllChildsNodes method recursively.
     this.CheckAllChildNodes(node, nodeChecked);
    }
   }
  }

  // NOTE   This code can be added to the BeforeCheck event handler instead of the AfterCheck event.
  // After a tree node's Checked property is changed, all its child nodes are updated to the same value.
  private void node_AfterCheck(object sender, TreeViewEventArgs e)
  {
   // The code only executes if the user caused the checked state to change.
   if (e.Action != TreeViewAction.Unknown)
   {
    if (e.Node.Nodes.Count > 0)
    {
     /* Calls the CheckAllChildNodes method, passing in the current 
     Checked value of the TreeNode whose checked state changed. */
     this.CheckAllChildNodes(e.Node, e.Node.Checked);
    }
   }
  }
Run Code Online (Sandbox Code Playgroud)

你把它放在一个包含树视图的表单中并调用node_AfterCheck(惊讶,惊讶),树视图AfterCheck事件.然后它以递归方式检查或取消选中树视图上的子节点.

但是,如果您实际尝试它,并且在相同的树视图复选框上多次单击几次,则子节点最终会与父节点的校验不同步.您可能需要几个级别的子级,总共可能有100个孩子,因为UI更新速度足够慢,可能会发现这种情况.

I've tried a couple of things (such as disabling the treeview control at the beginning of node_AfterCheck and re-enabling at the end), but the out-of-sync problem still happens.

Any ideas?

Han*_*ant 33

.NET TreeView类大量自定义本机Windows控件的鼠标处理,以便合成Before/After事件.不幸的是,他们没有把它弄得很对.当您开始快速点击时,您将生成双击消息.本机控件通过切换项目的已检查状态来响应双击,而不会告诉.NET包装器.您将无法获得Before/AfterCheck活动.

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,即将死亡已经预测了7年了. (3认同)
  • 他们为什么不修? (2认同)
  • 2017 年在这里签到,感谢您的解决方法,winforms 还没有死。 (2认同)