右键单击打开自定义 ContextMenuStrip

Open custom ContextMenuStrip on right-click

我正在创建一个包含不同类型 TreeNode 的 TreeView,每个 TreeNode 都有自己的 ContextMenuStrip 菜单。 我有一个继承自 TreeNode 的 class ElementTreeNode。我想添加一个继承自 ContextMenuStrip 菜单的 ElementContextMenu,右键单击节点时应打开该菜单。

我的第一个方法是简单地将 ElementContextMenu 的实例添加到我的 ElementTreeNodeContextMenuStrip 属性 中。但是我向 ElementTreeNode 添加了一个 EventHandler,我无法通过这种方式访问​​它。可能是因为 属性 向下转换为 ContextMenuStrip 从而丢失了仅存在于 ElementContextMenu:

中的 EventHandler
class ElementTreeNode : TreeNode
{
    public ElementTreeNode()
    {
        ContextMenuStrip = new ElementContextMenu();
    }
}

我的第二个想法是在 class 中添加一个 属性 ElementContextMenu 然后让右键单击事件打开此菜单而不是 ContextMenuStrip 属性:

class ElementTreeNode : TreeNode
{
    public ElementContextMenu ElementContextMenu;

    public ElementTreeNode()
    {
        ElementContextMenu = new ElementContextMenu();
    }
}

所以我的问题是:
如何在右键单击节点时打开 ElementContextMenu 属性 而不是 ContextMenuStrip
有没有办法改变这种行为?

只需手动显示 ContextMenu,不要分配 TreeView 的上下文菜单。例如

        TreeView tv = new TreeView() { Dock = DockStyle.Fill };
        tv.Nodes.Add(new ElementTreeNode { Text = "Node 1" });
        tv.Nodes.Add(new ElementTreeNode { Text = "Node 2" });
        tv.MouseDown += (o, e) => {
            TreeNode n = tv.GetNodeAt(e.Location);
            tv.SelectedNode = n; // known bug, force selected node
            if (e.Button == MouseButtons.Right) {
                if (n is ElementTreeNode) {
                    var n2 = (ElementTreeNode) n;
                    n2.ElementContextMenu.Show(tv, e.Location);
                }
            }
        };

试着让你的 ElementTreeNode class 像这样:

class ElementTreeNode : TreeNode
{    

  public ElementTreeNode()
  {
    ElementContextMenu = new ElementContextMenu();
  }

  public ElementContextMenu ElementContextMenu
  {
    get { 
      return ContextMenuStrip as ElementContextMenu; 
    }
    private set { 
      ContextMenuStrip = value; 
    }
  }
}

现在,只要您需要添加事件处理程序或访问仅存在于 ElementContextMenu class 中的属性,请使用 ElementContextMenu 属性。

old ContextMenuStrip 属性 的行为仍然相同(右键单击节点时打开上下文菜单),但它会打开您的 ElementContextMenu 实例。