在上下文菜单下找到点击节点

我怎样才能找出树列表中的哪个节点的上下文菜单已被激活?例如,右键单击节点并从菜单中选择一个选项。

我无法使用TreeView的 SelectedNode 属性,因为节点只是右键单击并且未选中。

0
额外 编辑
意见: 2

9 答案

如果你想要上下文菜单依赖于你最好的选择项目,我想使用Jonesinator的代码来选择点击的项目。您的上下文菜单内容可以依赖于选定的项目。

首先选择该项目,而不是仅将其用于上下文菜单具有一些优点。首先是用户具有关于他点击哪个的菜单以及菜单与哪个项目相关联的视觉指示。第二个是这样,与其他调用上下文菜单的方法(例如键盘快捷方式)保持兼容很容易。

0
额外

您可以向TreeView添加一个鼠标单击事件,然后在给出由MouseEventArgs提供的鼠标坐标的情况下使用GetNodeAt选择正确的节点。

void treeView1MouseUp(object sender, MouseEventArgs e)
{
    if(e.Button == MouseButtons.Right)
    {
        // Select the clicked node
        treeView1.SelectedNode = treeView1.GetNodeAt(e.X, e.Y);

        if(treeView1.SelectedNode != null)
        {
            myContextMenuStrip.Show(treeView1, e.Location);
        }
    }
}
0
额外
我用MouseDown事件而不是MouseUp得到了期望的结果。
额外 作者 Javier,
非常感谢你,我对解决方案有一个小小的补充:你也可以使用“_NodeMouseClick”事件给你一个“TreeNodeMouseClickEventArgs e”,在这种情况下你可以使用e.Node而不必费心检查这个节点是否为空。
额外 作者 SDM,

与马库斯的回答类似,这是我找到的解决方案:

private void treeView_MouseClick(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        treeView.SelectedNode = treeView.GetNodeAt(e.Location);
    }
}

如果您将其设置为每个单独节点,则无需亲自显示上下文菜单,如下所示:

TreeNode node = new TreeNode();
node.ContextMenuStrip = contextMenu;

然后在ContextMenu的Opening事件中,TreeView.SelectedNode属性将反映正确的节点。

0
额外

振兴这个问题,因为我觉得这是一个更好的解决方案。 我使用 NodeMouseClick 事件来代替。

void treeview_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    if( e.Button == MouseButtons.Right )
    {
        tree.SelectedNode = e.Node;
    }
}
0
额外
与我的相同=)
额外 作者 deej,
我也很喜欢这个。
额外 作者 Joey Novak,

我发现标准的Windows TreeView行为选择行为很烦人。例如,如果您正在使用资源管理器并右键单击节点并点击属性,则会突出显示该节点并显示您单击的节点的属性对话框。但是,当您从对话框返回时,突出显示的节点是您之前选中/突出显示的节点,然后再执行右键单击。我发现这会导致可用性问题,因为我一直对我是否在正确的节点上执行操作感到困惑。

因此,在我们的许多GUI中,我们通过右键单击来更改选定的树节点,以免混淆。这可能不像标准的iwndos应用程序一样Explorer(我倾向于强烈建模我们的图形用户界面行为后,出于可用性原因的标准窗口应用程序),我相信这一个例外情况导致更多的可用树。

以下是一些代码,可以在右键单击时更改选择内容:

  private void tree_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
  {
     // only need to change selected note during right-click - otherwise tree does
     // fine by itself
     if ( e.Button == MouseButtons.Right )
     {         
        Point pt = new Point( e.X, e.Y );
        tree.PointToClient( pt );

        TreeNode Node = tree.GetNodeAt( pt );
        if ( Node != null )
        {
           if ( Node.Bounds.Contains( pt ) )
           {
              tree.SelectedNode = Node;
              ResetContextMenu();
              contextMenuTree.Show( tree, pt );
           }
        }
     }
  }
0
额外
这对我来说是最好的解决方案,因为它实际上选择了您单击的节点。
额外 作者 CAD bloke,

这是我的解决方案。将此行放入TreeView的NodeMouseClick事件中:

 ((TreeView)sender).SelectedNode = e.Node;
0
额外
很好很简单
额外 作者 AndrewJE,
鼠标事件参数没有.Node
额外 作者 CAD bloke,
是的,但是TreeNodeMouseClickEventArgs(它被传递到 NodeMouseClick 事件)。所以我的解决方案正在工作,不像其他解决方案那样过于复杂
额外 作者 deej,
你我的新英雄。
额外 作者 garaber,

这是我如何做到的。

private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Right)
        e.Node.TreeView.SelectedNode = e.Node;
}
0
额外

这是一个非常古老的问题,但我仍然认为它很有用。我正在使用上述一些答案的组合,因为我不想让右键单击的节点成为selectedNode。如果我选择了根节点并且想要删除它的一个子节点,我不希望孩子在删除它时选中(我还在selectedNode上做了一些工作,我不想在右键菜单上发生这种情况)点击)。这是我的贡献:

// Global Private Variable to hold right-clicked Node
private TreeNode _currentNode = new TreeNode();

// Set Global Variable to the Node that was right-clicked
private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Right)
        _currentNode = e.Node;
}

// Do something when the Menu Item is clicked using the _currentNode
private void toolStripMenuItem_Clicked(object sender, EventArgs e)
{
    if (_currentNode != null)
        MessageBox.Show(_currentNode.Text);
}
0
额外

您可以运行的另一个选项是具有包含所选节点的全局变量。你只需要使用 TreeNodeMouseClickEventArgs

public void treeNode_Click(object sender, TreeNodeMouseClickEventArgs e)
{
    _globalVariable = e.Node;
}

现在您可以访问该节点并且它是属性。

0
额外