以下代码直接来自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);
}
}
}
您将其放在包含树视图的表单中并调用node_AfterCheck(惊讶,惊讶),树视图AfterCheck事件。然后它以递归方式检查或取消选中树视图上的子节点。
但是,如果您实际尝试它,并且在同一树视图复选框上多次单击几次,则子节点最终会与父节点的校验不同步。您可能需要几个级别的孩子,其中可能有100个孩子,因为UI更新速度足够慢,可能会发现这种情况。
我尝试了一些事情(例如在node_AfterCheck开始时禁用treeview控件并在结束时重新启用),但仍然会发生不同步问题。
有什么想法吗?
答案 0 :(得分: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);
}
}
答案 1 :(得分:1)
使用上面的解决方案,我认为需要绘制更详细的步骤,如何将其应用于已经创建的TreeView的人。例如,对于我这个初学者来说,这造成了困难,但这里是解决方案:
在您的项目中创建一个“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;
在 private NoClickTree treeView;
在函数 private void InitializeComponent()
中找到原始初始化,类似 this.treeView = new System.Windows.Forms.TreeView();
在 this.treeView = new NoClickTree();
完成!
这些步骤帮助我解决了这个问题。