离开对 Kevin Wienhold 答案的评论,您只想允许用户单击树视图的空白区域并取消选择任何选定的节点。
您可以通过处理来做到这一点MouseDown event http://msdn.microsoft.com/en-us/library/system.windows.forms.control.mousedown.aspx of the TreeView
控制,并设置SelectedNode财产 http://msdn.microsoft.com/en-us/library/system.windows.forms.treeview.selectednode.aspx to null
如果鼠标单击不包含节点的位置。例如,您可以使用以下代码:
private void myTreeView_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (myTreeView.HitTest(e.Location).Node == null)
{
myTreeView.SelectedNode = null;
}
}
这利用了HitTest method http://msdn.microsoft.com/en-us/library/z6sb88bz.aspx确定哪个节点位于特定点,将鼠标事件的位置指定为要测试的点。当用户使用时,您不需要任何其他代码来像往常一样选择节点does点击它们;这是由自动处理的TreeView
.
EDIT:正如我对这个问题的评论所表明的那样,我仍然非常不清楚你想在这里完成什么。如果您确实想在节点侧面的空白处按住鼠标右键时防止节点暂时突出显示,那么事情会变得更复杂一些。
我之前研究过这个问题,棘手的部分是按住鼠标按钮时不会收到窗口消息,至少在移动鼠标之前不会收到窗口消息(在这种情况下,无论如何都不再选择该节点) 。此行为显然是由操作系统决定的,并且使用标准 .NET 提供的事件不容易覆盖。您可以尝试取消点击右键MouseDown
整天都有事件发生,但在您的控件中引发此事件之前,Windows 已选择该节点(请记住,.NET 提供的控件,例如TreeView
and ListView
只是 Windows API 提供的相同控件的包装器,它本身显然实现了这种“按住右键时选择节点”行为)。
What does然而,工作是压倒一切的WndProc http://msdn.microsoft.com/en-us/library/system.windows.forms.control.wndproc.aspx在派生的TreeView
控制和处理WM_RBUTTONDOWN message http://msdn.microsoft.com/en-us/library/ms646242%28VS.85%29.aspx。但请注意,即使设置SelectedNode
财产给null
在这里不起作用,因为直到afterWindows 会自动选择节点作为对单击鼠标右键的响应 - 无论您做什么,都必须防止基节点TreeView
控制从接收WM_RBUTTONDOWN
信息。因此,您有几种处理此问题的选择:
-
您可以通过提前退出来简单地取消右键单击消息return
陈述。当然,这意味着您将无法在您的系统中处理此事件MouseDown
处理程序,因为它从未真正传递给控件!因此,如果您想显示弹出式上下文菜单,这可能不适合您。
public class NewTreeView : System.Windows.Forms.TreeView
{
protected override void WndProc(ref System.Windows.Forms.Message m)
{
const int WM_RBUTTONDOWN = 0x204;
if (m.Msg == WM_RBUTTONDOWN)
{
return;
}
base.WndProc(ref m);
}
}
-
您可以在覆盖的内容中显示上下文菜单WndProc
方法作为对WM_RBUTTONDOWN
消息,然后return
从方法中不允许基类处理消息。这与第一个解决方案执行完全相同的操作(防止右键单击事件导致节点显示为选中状态),但它确实允许您在右键单击时显示上下文菜单(或执行任何其他您想要的操作)发生。当然,这确实意味着所有相关代码都必须包含在您的子类中TreeView
控件,不在表单的 UI 代码中处理,这对您来说可能方便也可能不方便。
public class NewTreeView : System.Windows.Forms.TreeView
{
protected override void WndProc(ref System.Windows.Forms.Message m)
{
const int WM_RBUTTONDOWN = 0x204;
if (m.Msg == WM_RBUTTONDOWN)
{
//Create and show a context menu
var myContextMenu = new ContextMenuStrip();
myContextMenu.Items.Add("First Item");
myContextMenu.Items.Add("Second Item");
return;
}
base.WndProc(ref m);
}
}
-
你可以提高你的own http://msdn.microsoft.com/en-us/library/wkzf914z.aspx RightMouseClick
您自定义的事件TreeView
类作为对WM_RBUTTONDOWN
消息,然后您可以根据需要从表单的 UI 代码中处理该消息。通过不通过WM_RBUTTONDOWN
给基地留言TreeView
控件类,这实现了与前两个建议相同的目标,但允许您在表单的 UI 代码中处理右键单击事件,而不必将所有逻辑放入子类控件的WndProc
.
public class NewTreeView : System.Windows.Forms.TreeView
{
protected override void WndProc(ref System.Windows.Forms.Message m)
{
const int WM_RBUTTONDOWN = 0x204;
if (m.Msg == WM_RBUTTONDOWN)
{
//Raise your custom event
OnRightMouseClick(new EventArgs());
return;
}
base.WndProc(ref m);
}
}