代码之家  ›  专栏  ›  技术社区  ›  Sam

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

  •  64
  • Sam  · 技术社区  · 16 年前

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

    我不能用树视图 SelectedNode 属性,因为该节点仅被右键单击而未被选中。

    9 回复  |  直到 7 年前
        1
  •  85
  •   Jeremy Thompson    12 年前

    您可以将鼠标单击事件添加到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);
            }
        }
    }
    
        2
  •  20
  •   deej    14 年前

    这是我的解决方案。将此行放入树视图的nodemouseclick事件:

     ((TreeView)sender).SelectedNode = e.Node;
    
        3
  •  12
  •   solarc    14 年前

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

    因此,在许多GUI中,我们在右键单击时更改选定的树节点,这样就不会出现混淆。这可能与标准的iwndos应用程序(如explorer)不同(出于实用的原因,我倾向于在标准窗口应用程序之后强烈地建模我们的GUI行为),我相信这一例外情况会导致更多的可用树。

    以下是在右键单击期间更改选择的代码:

      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 );
               }
            }
         }
      }
    
        4
  •  6
  •   Beta Carotin    12 年前

    重新提出这个问题,因为我发现这是一个更好的解决方案。 我用 NodeMouseClick 事件代替。

    void treeview_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
    {
        if( e.Button == MouseButtons.Right )
        {
            tree.SelectedNode = e.Node;
        }
    }
    
        5
  •  2
  •   Trevor Elliott    12 年前

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

    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属性将反映正确的节点。

        6
  •  2
  •   George    8 年前

    这是一个很古老的问题,但我仍然觉得它很有用。我使用上面的一些答案的组合,因为我不希望右键单击的节点成为选定的节点。如果我选择了根节点,并且想删除它的一个子节点,我不希望在删除它时选择子节点(我也在对选定的节点做一些我不希望在右键单击时发生的工作)。这是我的贡献:

    // 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);
    }
    
        7
  •  0
  •   ICR    16 年前

    如果您希望上下文菜单依赖于所选项目,我认为最好的方法是使用jonesinator的代码来选择单击的项目。然后,上下文菜单内容可以依赖于所选项目。

    首先选择项目,而不只是将其用于上下文菜单,这会带来一些优势。第一个问题是,用户有一个可视指示,指示他单击了哪个项目,因此菜单与哪个项目相关联。第二个问题是这样,与调用上下文菜单的其他方法(如键盘快捷键)保持兼容要容易得多。

        8
  •  0
  •   Ricky Manwell    10 年前

    我就是这样做的。

    private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Right)
            e.Node.TreeView.SelectedNode = e.Node;
    }
    
        9
  •  0
  •   sparkyShorts    8 年前

    您可以使用的另一个选项是具有选定节点的全局变量。你只需要使用 TreeNodeMouseClickEventArgs .

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

    现在您可以访问该节点及其属性。