R – Display the menu for a ToolStripDropDownButton as a context menu

winforms

I have a tool strip which contains a ToolStripDropDownButton. As an alternative access method, I would also like to be able to display this button's dropdown menu as a context menu, when the user right-clicks in the area below the tool strip.

I tried the following code, but it didn't work (it displayed the button's dropdown in the normal location, directly under the button):

Point contextMenuLocation = [get from WM_CONTEXTMENU]
myButton.DropDown.Show( contextMenuLocation );

The best idea I can think of would be to copy the toolstrip items from the button's dropdown into a ContextMenuStrip, but I don't see any simple way to do that (ToolStripItem does not implement ICloneable or a Clone method). Tool strip items store a reference to their Parent, so I can't just add the existing items to the context menu, as that would break the button.

Does anybody have a good idea on how to accomplish this?

Best Answer

A good way of populating two different dropdown with the same items is to extract the items creation into a function that builds the necessary drop down just before you open any instance of that dropdown. This also lets you enable a disable stuff if the application state changes.

class A
{
    public A()
    {
        button = new ToolStripDropDownButton();
        button.DropDown = new ToolStripDropDown();

        ToolStripDropDown dropDown = new ToolStripDropDown();
        dropDown.Opening += DropDownOpening;
        menu.Items.DropDown = dropDown;

    }

    void DropDownOpening(object sender, EventArgs e)
    {
        ToolStripDropDown dropDown = sender as ToolStripDropDown;
        if(dropDown != null) 
        {
            dropDown.Items.Clear();
            BuildMenu(dropDown);
        }
        else
        {
            // throw if you like
        }
    }

    void BuildMenu(ToolStripDropDown dropDown)
    {
        // TODO : Add items to dropdown
        // TODO : Take decisions depending on current application state
    }

    ToolStripDropDownButton button;
    MenuStrip menu;
}