3
votes

I've come across a rather interesting occurrence in a WinForms app I'm developing. It seems that when I add a DropDownItem to a ToolStripMenuItem, the shortcut key on the parent menu item disappears. And it's not just that the shortcut key isn't shown, it no longer registers the keypress at all. If I remove the submenu items, the shortcut key comes back. Surprisingly, everything looks just fine in the designer, this doesn't appear to happen until runtime.

Menu In The Designer:

Designer View

Same menu at runtime:

Runtime View

Does anyone know why this is happening and how I can prevent it? And to clarify, clicking on the parent menu carries out different functionality than clicking on the submenu, so moving the shortcut is not sufficient. If I click on the menus manually, all functionality is carried out as expected. It is only the shortcut key that no longer works.

3
My guess is... It would be a good design that your node that contains other nodes would not trigger actions on their own. I'm pretty sure I know no software where a menu container actually have actions. - LightStriker
In most cases I would agree. In this case it is an Undo menu. Clicking the parent menu will back up one step, while clicking on the submenus will back up to the step you clicked on. Basically, I am trying to implement a ToolStripSplitButton in Menu form. - Shaun Hamman
It is a flaw in the designer, it should have hidden the shortcut key name at design time as well. Only menu items that don't display a sub-menu can have shortcut keys. So that typing the key directly executes the Click event without showing UI. - Hans Passant
@ShaunHamman: It's still a very bad design. If it was the case of an undo menu with an undo stack, you should have a empty menu node called "Undo Stack" or "Actions" or whatever which at the top is the Undo CTRL+Z / Redo CTRL+Y, a separator and under it the dynamic stack of actions to undos. The "container" wouldn't have any action associated to it. - LightStriker
@LightStriker Perhaps. But bad design or not, I would still like to know if the functionality I'm trying to implement can be done without completely subclassing the ToolStripMenuItem control. - Shaun Hamman

3 Answers

0
votes

Not really sure why this happens but you can always define a new PreviewKeyDown event within the current Form and see if the keys pressed matches the menu item shortcut keys. Thus, you'll be able to execute the commands you'd like to when ONE or more keys are pressed.

Example

public Form1()
{
    InitializeComponent();
    PreviewKeyDown += new PreviewKeyDownEventHandler(Form1_PreviewKeyDown); //Link the PreviewKeyDown event of the current Form to Form1_PreviewKeyDown
}

private void Form1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
    if (e.Control && e.KeyCode == Keys.D7) //Indicates whether Ctrl and 7 are pressed (These are our hotkeys)
    {
        //DoSomething
    }
}

Thanks,
I hope you find this helpful :)

0
votes

I think shortcut keys only work with menu items with no sub-items. So at run-time its not visible because compiler predicted that its a menu with a sub-menu.

0
votes

From what I've been able to gather, the only way to make this work is to subclass the ToolStripMenuItem and handle the drawing manually.