【问题标题】:Is there anyway to get TreeNode that opened ContextMenuStrip in ToolStripMenuItem click handler?无论如何要获取在 ToolStripMenuItem 点击处理程序中打开 ContextMenuStrip 的 TreeNode 吗?
【发布时间】:2013-06-23 20:41:45
【问题描述】:

我有不同级别 TreeNode 的 TreeView
我向所有父 TreeNodes 添加了相同的 ContextMenuStrip,我希望通过打开该 ContextMenuStrip 并按“全部删除”来删除所有子 TreeNodes

private void btn_delete_all_objects_Click(object sender, EventArgs e)
{
    ToolStripMenuItem tsmi = (ToolStripMenuItem)sender; //that way i receive button "Delete all"
    ContextMenuStrip cms = (ContextMenuStrip)tsmi.Owner; //this is ContextMenuStrip where this button...
    TreeView tw = (TreeView)cms.SourceControl; //i can get TreeView :( BUT I NEED TreeNode!
    TreeNode tn = tw.SelectedNode; //bah... if i select some of child nodes, then right click to open menu on parent, selected node is still that child
}

而且我不知道如何获取用户单击打开菜单的 TreeNode
有什么想法吗?

【问题讨论】:

  • 当上下文菜单显示时,您将获得节点。只需将此节点保存在变量中并在事件处理程序中读取它。
  • 哪种方式?在 contextMenuStrip1_Opening 和 contextMenuStrip1_Opened sender 仍然是 ContextMenuStrip,但不是 TreeNode
  • 此时您在树节点上单击鼠标,您就有了树节点。这个你可以保存在一个变量中。单击上下文菜单中的条目后,您可以读取保存的变量,其中包含您的节点。

标签: c# treeview treenode contextmenustrip


【解决方案1】:

你可以在树形视图中使用HitTest()方法来查找节点,像这样,

var hitTest = treeView1.HitTest(treeView1.PointToClient(new Point(contextMenuStrip1.Left, contextMenuStrip1.Top)));
if (hitTest.Node != null)
{
    // Place your code to delete nodes
}

或者您可以关注鼠标单击的节点并使用treeView1.SelectedNode 属性在您的菜单项中进行操作。通过这种方式,您可以避免在每个上下文菜单项上使用 HitTest()...

private void treeView1_MouseDown(object sender, MouseEventArgs e)
{
    var hitTest = treeView1.HitTest(treeView1.PointToClient(e.Location));
    if (hitTest.Node != null)
    {
         treeView1.SelectedNode = hitTest.Node;
    }
}

【讨论】:

  • 这行得通!谢谢 :) 不能说这真的是最好的方法,但如果没有其他方法......
【解决方案2】:

不清楚你想用上面的代码做什么。但是要执行您需要的操作(即右键单击TreeNode 并启动特定的ContextMenuStrip),请使用与

类似的代码
private void customTreeViewSql_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    // Ensure selected node is selected.
    treeView.BeginUpdate();
    this.treeView.SelectedNode = e.Node;
    try
    {
        if (e.Node.Level == 0)
        {
            if (e.Button == MouseButtons.Right)
                contextMenuStripA.Show(MousePosition);
        }
        else if (e.Node.Level == 1)
        {
            if (e.Button == MouseButtons.Right)
                contextMenuStripB.Show(MousePosition);
        }
    }
    finally
    {
        this.treeView.EndUpdate();
    }
}

然后您可以在 ContexMenu 中设置 click 事件,以根据所选内容删除所有子节点

private void toolStripMenuDeleteAll_Click(object sender, EventArgs e)
{
    TreeNode treeNode = this.treeView.SelectedNode;
    foreach (TreeNode n in treeNode.Nodes)
        n.Remove();
}

我希望这会有所帮助。

【讨论】:

  • 感谢您提供帮助,这不是我想要的,但仍然... ContextMenuStrip 在单击 TreeNode 时自动显示,我只需要获取 TreeNode 在执行 ToolStripmenuItem 按钮时打开该 ContextMenuStrip 的方法新闻处理程序
  • 上面的上下文按钮点击事件会立即触发,并适用于当前选定的节点。这应该可以满足您的要求。
【解决方案3】:

我认为这比 Krishnakumar 的代码清晰易懂。 您可以将您的“toolStripMenuDeleteAll”设置为仅一些树节点,而不是所有树节点。 此代码根本不会更改 Selected TreeNode。

欢迎 查达什

TreeNode LastClickedTreeNode;
private void customTreeViewSql_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    // update last treenode clicked.
    LastClickedTreeNode = e.Node;
}

private void toolStripMenuDeleteAll_Click(object sender, EventArgs e)
{
    foreach (TreeNode n in LastClickedTreeNode.Nodes)
        n.Remove();
}

【讨论】:

  • 我明白了,但是...它依赖于鼠标点击。可以使用键盘箭头键选择节点
猜你喜欢
  • 2011-09-13
  • 1970-01-01
  • 1970-01-01
  • 2014-03-22
  • 2013-05-31
  • 1970-01-01
  • 1970-01-01
  • 2013-11-28
  • 1970-01-01
相关资源
最近更新 更多