当ContextMenuStrip具有焦点时,获取用户键入的char

时间:2013-01-13 16:14:28

标签: c# .net winforms

当打开ContextMenuStrip时,如果用户键入可能选择的第一个字母 - 就好像他点击了它一样。我想拦截它并获得他点击的角色。

以下代码执行此操作,但使用硬编码可能的字符。我想要一种通用的方法来做到这一点,或者通过按键击中禁用自动选择(只留下鼠标点击)或者某种方式拦截角色。

以下简化代码假设我希望winform的Text为键入的字符,ContextMenuStrip有一个选项为“A”。

public Form1()
{
    InitializeComponent();
    contextMenuStrip1.KeyDown += contextMenuStrip1_KeyDown;
}

private void button1_Click(object sender, EventArgs e)
{
    contextMenuStrip1.Show();
}

void contextMenuStrip1_KeyDown(object sender, KeyEventArgs e)
{
    e.SuppressKeyPress = true;
    if (e.KeyCode == Keys.A)
    {
        if (e.Shift) Text = "A";
        else Text = "a";
    }
}

使用KeyPress事件并检查e.KeyChar不起作用,因为它不会被触发。 (“A”点击事件会被触发。)

使用其中之一:e.KeyCodee.KeyDatae.KeyValue不起作用(没有进一步的硬编码),因为他们接受Shift作为密钥。

1 个答案:

答案 0 :(得分:3)

如注释中所述,您必须从ContextMenuStrip派生自己的类,以便可以覆盖ProcessMnemonic()方法。

稍微注释一下,Winforms中的键盘处理非常复杂。在将焦点分配到具有焦点的控件之前,很快就会处理快捷键击。必然如此,您不希望为每个控件实现KeyDown事件,以便您可以使快捷键击工作。

这适用于外部并涉及多个受保护的方法,ProcessCmdKey,ProcessDialogChar和ProcessMnemonic。如果设置了表单的KeyPreview属性,则与OnKeyDown一样,还有VB6 compat功能。因此,表单首先获取它,然后从那里迭代控件,从容器到子控件。

ToolStrip类(ContextMenuStrip的基类)会覆盖ProcessMnemonic()方法以识别按键,将它们映射到菜单项。因此,为了拦截这个默认处理,你必须自己覆盖ProcessMnemonic(),以便先按下按键。