C#:如何避免在双击事件中发生TreeNode检查

所以我在C#windows窗体应用程序中有一个TreeView。 我需要的是一些节点被“锁定”,以便根据参数无法检查(或取消选中)它们。

我现在在做的是:

private void tv_local_BeforeCheck(object sender, TreeViewCancelEventArgs e) { TNode node = (TNode)e.Node; //if a part node, cancel the action. if (node.Type == "Part") { e.Cancel = true; } //if a locked node, cancel the action if (node.Locked == true) { e.Cancel = true; } } 

只需单击该复选框,此代码就可以正常工作,但如果用户双击复选框,它仍会检查/取消选中。

我尝试过使用nodeMouseDoubleClick事件,但这并没有真正帮助,因为我无法取消事件…

是否有任何想法取消节点上的双击事件?…或其他什么? 谢谢

这是我认为TreeView中的一个错误( http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/9d717ce0-ec6b-4758-a357-6bb55591f956/ )。 您需要子类化树视图并禁用双击消息以便修复它。 像这样:

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

当然,如果你这样做,你将无法再使用树视图中的双击隐喻来做其他事情(比如双击一个节点来启动一个属性页,或者其他东西)。

如果您希望双击实际切换复选框,请尝试:

 protected override void WndProc(ref Message m) { // Filter WM_LBUTTONDBLCLK when we're showing check boxes if (m.Msg == 0x203 && CheckBoxes) { // See if we're over the checkbox. If so then we'll handle the toggling of it ourselves. int x = m.LParam.ToInt32() & 0xffff; int y = (m.LParam.ToInt32() >> 16) & 0xffff; TreeViewHitTestInfo hitTestInfo = HitTest(x, y); if (hitTestInfo.Node != null && hitTestInfo.Location == TreeViewHitTestLocations.StateImage) { OnBeforeCheck(new TreeViewCancelEventArgs(hitTestInfo.Node, false, TreeViewAction.ByMouse)); hitTestInfo.Node.Checked = !hitTestInfo.Node.Checked; OnAfterCheck(new TreeViewEventArgs(hitTestInfo.Node, TreeViewAction.ByMouse)); m.Result = IntPtr.Zero; return; } } base.WndProc(ref m); } 

我使用以下代码管理它,这会阻止检查根节点:

 private void MyTreeView_MouseUp(object sender, MouseEventArgs e) { // HACK: avoid to check root nodes (mr) var node = ((TreeView)sender).GetNodeAt(new Point(eX, eY)); if (node != null && node.Parent == null) BeginInvoke(new MouseEventHandler(TreeView_MouseUpAsync), sender, e); } private void TreeView_MouseUpAsync(object sender, MouseEventArgs e) { if (IsDisposed) return; var node = ((TreeView)sender).GetNodeAt(new Point(eX, eY)); node.Checked = false; } 

尝试扩展TreeNode类并添加一个维护正确checkedState的布尔属性。 这样,当有人双击节点时,您可以将节点的已检查状态重置为存储在属性中的值。 可能有更优雅的解决方案,但这是我能想到的最好的解决方案。