Reputation: 4380
I need to allow the Alt
key to be used as a modifier when selecting certain menu entries in a ContextMenuStrip
. This works fine with all other modifiers like Ctrl
or Shift
. However, for some reason Alt
automatically closes the context menu.
I tried using the Closing
event in the context menu, and the menu item AutoClose
property, but this is proving to be more clunky than anticipated. Specifically, even though the context menu is kept open, the application MenuStrip
is activated (which may explain why the context menu closes in the first place).
I've tried searching around but I found surprisingly few questions about this, and none on stack overflow, so I wonder whether there might be a better way to work around this that I have missed?
Example code showing that suppressing MenuStrip
activation does not prevent context menu from closing:
class MainForm : Form
{
MenuStrip menuStrip;
ContextMenuStrip contextMenuStrip;
public MainForm()
{
KeyPreview = true;
menuStrip = new MenuStrip();
menuStrip.Items.Add("&File");
Controls.Add(menuStrip);
contextMenuStrip = new ContextMenuStrip();
contextMenuStrip.Items.Add("&OptionA");
contextMenuStrip.Items.Add("&OptionB");
ContextMenuStrip = contextMenuStrip;
}
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.Alt)
{
e.Handled = true;
e.SuppressKeyPress = true;
}
else base.OnKeyDown(e);
}
}
Upvotes: 1
Views: 597
Reputation: 7354
This is by design, so you'll have to do the state tracking yourself. But this will definitely stop Alt
from reaching the MenuStrip
.
This is low level keyboard filtering, so you'll have to decide what to do when Alt
is pressed entirely on your own, however.
You could also change the conditional to check for Alt
plus some state.
In short, returning true
from PreFilterMesssage
will stop it from reaching your app.
static void Main()
{
//...SNIP...
Application.AddMessageFilter(new AltFilter());
//...SNIP...
}
public class AltFilter : IMessageFilter
{
private static ushort WM_SYSKEYDOWN = 0x0104;
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == WM_SYSKEYDOWN && Control.ModifierKeys == Keys.Alt)
{
//Do your own special thing instead
return true;
}
return false;
}
}
Upvotes: 1