0

In Winforms, I want to display a ContextMenuStrip when the user right-clicks on a ToolStripMenuItem. For example (see the image below), in Firefox there is Bookmarks menu and when we right-click on one of the bookmarks, a context menu item will be displayed.

How could we do it in Windows Form application?

I know we could associate a ContextMenuStrip to a Control (e.g. a Form), but the problem is that ToolStripMenuItem is not a Control.

bookmarks-menu-in-firefox

Setyo N
  • 1,953
  • 2
  • 26
  • 28

1 Answers1

4

Create a custom ContextMenuStrip and show it while handling the MouseUp event on a ToolStripItem, so basically something like that:

    toolStripLabel1.MouseUp += new System.Windows.Forms.MouseEventHandler(toolStripLabel1_MouseUp);

    private void toolStripLabel1_MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            contextMenuStrip1.Show(Cursor.Position);
        }
    }

You can then display different context menus based on the menu item user clicked.

UPDATE

Regarding your comment, if you don't like the menu items to disapear when you show context menu, you can iterate through all the tool strip menu items and set AutoClose property to false (and then back to true after showing the context menu):

    private void toolStripLabel1_MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            AutoCloseDropDowns(menuStrip1.Items, false);
            contextMenuStrip1.Show(Cursor.Position);
            AutoCloseDropDowns(menuStrip1.Items, true);
        }
    }

    private void AutoCloseDropDowns(ToolStripItemCollection items, bool autoClose)
    {
        if (items != null)
        {
            foreach (var item in items)
            {
                var ts = item as ToolStripDropDownItem;
                if (ts != null)
                {
                    ts.DropDown.AutoClose = autoClose;
                    AutoCloseDropDowns(ts.DropDownItems, autoClose);
                }
            }
        }
    }
bpiec
  • 1,561
  • 3
  • 23
  • 38
  • Thanks @bpiec. It works, but when I click the ContextMenuStrip, the ToolStripMenuItem disappeared before the ContextMenuStrip is shown. Could we keep the ToolStripMenuItem displayed as in Firefox's Bookmarks menu? – Setyo N Feb 21 '14 at 09:12
  • You can handle `OnClosing` of `ToolStripMenu` (not item!) and do there `e.Cancel = true` while your `ContextMenusStrip` is visible (make a *flag*). Info is inaccurate, but should helps. – Sinatr Feb 21 '14 at 09:32
  • 1
    You can also set `DropDown.AutoClose = false` on all parent items of ToolStripItem before displaying context menu and then set it to true. I will write you an example of that later today. – bpiec Feb 21 '14 at 09:35
  • @user154321: If that answer helped you please set it as accepted. Thank you. – bpiec Feb 22 '14 at 14:43
  • Thanks, bpiec. Using DropDown.AutoClose property of ToolStripMenuItem works very well for me. – Setyo N Feb 24 '14 at 02:54
  • @bpiec this works great to show the contextmenustrip but how can you get the "SourceControl"? meaning, how can you know which toolStripMenuItem was clicked? (since a toolstripmenuitem is not a 'control') – Jill Jun 12 '15 at 02:47
  • @Jill: If you assign the same event handler to all menu items than you will have this menu item passed as a `sender` parameter. – bpiec Jun 12 '15 at 06:53