arne.z
arne.z

Reputation: 3540

Open custom ContextMenuStrip on right-click

I am creating a TreeView with different types of TreeNodes, each with their own ContextMenuStrip menus. I have a class ElementTreeNode which inherits from TreeNode. I want to add a ElementContextMenu which inherits from ContextMenuStrip menu to it which should open when right-clicking on the node.

My first approach was to simply add an instance of ElementContextMenu to the ContextMenuStrip property of my ElementTreeNode. But I added an EventHandler to ElementTreeNode which I can not access in this way. Probably because the property downcasts to ContextMenuStrip and thus loses the EventHandler which just exists in ElementContextMenu:

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

My second idea was to add a property ElementContextMenu to the class and then let the right-click event open this menu instead of the ContextMenuStrip property:

class ElementTreeNode : TreeNode
{
    public ElementContextMenu ElementContextMenu;

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

So my question is:
How can I open the ElementContextMenu property instead of the ContextMenuStrip when I right-click the node?
Is there a way to change this behavoir?

Upvotes: 0

Views: 271

Answers (2)

IronGeek
IronGeek

Reputation: 4883

Try making your ElementTreeNode class like this:

class ElementTreeNode : TreeNode
{    

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

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

Now whenever you need to add an EventHandler or access properties which only exist in ElementContextMenu class use the ElementContextMenu property.

The old ContextMenuStrip property will still behave the same way (open a context menu when you right-click the node), but it will open your instance of ElementContextMenu instead.

Upvotes: 0

Loathing
Loathing

Reputation: 5266

Just show the ContextMenu manually and don't assign the TreeView's context menu. E.g.

        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);
                }
            }
        };

Upvotes: 1

Related Questions