Reputation: 86729
I'm using the following code to display a context menu on my form when someone presses "Alt-A":
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Alt && e.KeyCode == Keys.A)
{
ContextMenuStrip menu = new ContextMenuStrip();
ToolStripMenuItem item = new ToolStripMenuItem("Hello &World");
item.Click += new EventHandler(item_Click);
menu.MenuItems.Add(item);
ToolStripMenuItem item2 = new ToolStripMenuItem("Some &Andriod");
item2.Click +=new EventHandler(item_Click);
menu.MenuItems.Add(item2);
menu.Show(this, new Point(0,0));
}
}
void item_Click(object sender, EventArgs e)
{
MessageBox.Show("Hey!")
}
The problem I'm having is that the second meny item ("Some &Android") is being "Clicked" immediately as soon as the menu is displayed - apparently because the keypress (Alt-A) is being immeditely passed to the menu.
If I change that menu item to have a different Mnemonic (e.g. "&Some Android") then this doesn't happen and the menu is displayed as normal.
I know that the ContextMenu class is deprecated, but is there any way of preventing this behaviour? I've already tried setting the Handled property of the EventArgs to true, but that did nothing (presumably because that wont do anything until the event handler completes, and the Show() method halts execution until the ContextMenu is no longer displayed.
UPDATE: I've updated the code to use the newer ContextMenuStrip
class and found that the same thing happens, however the ContextMenuStrip
class provides a lot more methods for me to override allowing better control of the menu item.
I've noticed that with the ContextMenuStrip
class the Show() method returns instantly (while the menu is still displayed), however even setting the Handled property on the event args to true does not prevent the key press being handled by the context menu.
I'm looking into using some more complex logic to decide whether or not to fire the click event based on if a certain time interval has passed since the menu was shown, and if a KeyUp event has been processed since then, but it all seems extremely messy - surely someone else has run into this problem before?
Upvotes: 0
Views: 2345
Reputation: 11858
I had the same problem with a pressed Alt key while opening a context menu. I figured out that it was the key event inside the context menu which released it shortly after creation. I solved the problem by inheriting the contextmenustrip and overriding the ProcessCmdKey
method as follows:
public partial class AdvancedContextMenuStrip : ContextMenuStrip
{
public AdvancedContextMenuStrip()
{
InitializeComponent();
}
protected override bool ProcessCmdKey(ref Message m, Keys keyData)
{
if ((keyData & Keys.Alt) == Keys.Alt)
return true;
return base.ProcessCmdKey(ref m, keyData);
}
}
Upvotes: 4
Reputation: 354416
I think this might be more related to the fact that in KeyDown you open your menu and KeyUp gets passed to the menu then instead.
So you should perhaps move the menu opening to KeyUp or KeyPress. This should avoid the problem entirely then.
Upvotes: 2