每次在上下文菜单(winforms)上按下一个键时如何检测?

How to detect everytime a key has been pressed on a context menu (winforms)?

在 Winforms 应用程序中,我使用 ContextMenuStrip(右键单击通知图标时显示)。

我想检测打开上下文菜单项时是否按下了某个键(例如:通过注册事件)。

与大多数控件不同,ContextMenuStrip 上没有 KeyDown 事件。 但是,有一个 PreviewKeyDown 事件。 我已经注册了那个活动,但是它没有按预期工作。

这是我的上下文菜单:

Item1
Item2
SubMenu > SubItem1
          SubItem2

如果我在 Item1 高亮显示(鼠标在其上)时按下某个键,则会触发事件。但是,如果我在突出显示 SubItem1 时按下某个键,则什么也不会发生。

如果没有项目被突出显示,同样的行为会发生: 如果仅打开上下文菜单(没有突出显示的项目),则会触发事件。 如果打开子上下文菜单(没有突出显示的项目),则不会触发事件。


这里是一些请求的代码示例:

//MainForm.cs
void ContextMenuStrip1PreviewKeyDown(object sender, EventArgs e)
{
    MessageBox.Show("OK"); //not always called, as explained above
}

//MainForm.Designer.cs (generated automatically by form designer)
this.contextMenuStrip1.PreviewKeyDown +=
  new System.Windows.Forms.PreviewKeyDownEventHandler(this.ContextMenuStrip1PreviewKeyDown);

要在上下文菜单条打开时检测 Shift 键状态,作为一个选项,您可以处理 Application.Idle event and will check the key state using GetKeyState 函数:

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern short GetKeyState(int keyCode);
public const int KEY_PRESSED = 0x8000;
public static bool IsKeyDown(Keys key)
{
    return Convert.ToBoolean(GetKeyState((int)key) & KEY_PRESSED);
}

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    Application.Idle += Application_Idle;
}

void Application_Idle(object sender, EventArgs e)
{
    if (!contextMenuStrip1.Visible)
        return;
    if (IsKeyDown(Keys.ShiftKey))
        someMenuItem.Text = "Shift is Down";
    else
        someMenuItem.Text = "Shift is Up";
}

protected override void OnFormClosed(FormClosedEventArgs e)
{
    Application.Idle -= Application_Idle;
    base.OnFormClosed(e);
}