按住 Alt 键时如何防止上下文菜单关闭?

How to prevent context menu from closing when holding the Alt key?

我需要允许 Alt 键在选择 ContextMenuStrip 中的某些菜单条目时用作修饰符。这适用于所有其他修饰符,如 CtrlShift。但是,出于某种原因 Alt 自动关闭上下文菜单。

我尝试使用上下文菜单中的 Closing 事件和菜单项 AutoClose 属性,但事实证明这比预期的更笨拙。具体来说,即使上下文菜单保持打开状态,应用程序 MenuStrip 也会被激活(这可以解释为什么上下文菜单首先关闭)。

我尝试四处搜索,但出乎意料的是,我发现的问题很少,而且 none 堆栈溢出,所以我想知道是否有更好的方法来解决我错过的这个问题?

显示抑制 MenuStrip 激活不会阻止上下文菜单关闭的示例代码:

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);
    }
}

这是设计使然,因此您必须自己进行状态跟踪。但这肯定会阻止 Alt 到达 MenuStrip

这是低级键盘过滤,因此当 Alt 完全由您自己按下时,您必须决定要做什么。

您还可以更改条件以检查 Alt 加上一些状态

简而言之,从 PreFilterMesssage 返回 true 将阻止它到达您的应用程序。

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;
    }
}