在KeyDown事件期间显示ContextMenu时出现问题

时间:2009-10-07 10:01:56

标签: c# contextmenu

当有人按“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!")
}

我遇到的问题是,只要显示菜单,第二个meny项目(“Some& Android”)就会立即“点击” - 显然是因为按键(Alt-A)正在立即通过到菜单。

如果我将该菜单项更改为具有不同的助记符(例如“& Some Android”),则不会发生这种情况,并且菜单会正常显示。

我知道ContextMenu类已被弃用,但是有什么方法可以阻止这种行为吗?我已经尝试将EventArgs的Handled属性设置为true,但是没有做任何事情(可能是因为在事件处理程序完成之前它不会执行任何操作,并且Show()方法会暂停执行,直到不再显示ContextMenu。

更新:我已更新代码以使用较新的ContextMenuStrip类,并发现同样的事情发生,但ContextMenuStrip类提供了更多方法我要覆盖允许更好地控制菜单项。

我注意到使用ContextMenuStrip类,Show()方法立即返回(当菜单仍然显示时),但是即使将事件args上的Handled属性设置为true也不会阻止按键由上下文菜单处理。

我正在考虑使用一些更复杂的逻辑来决定是否根据自显示菜单以来是否已经过了某个时间间隔来触发click事件,以及从那时起是否处理过KeyUp事件,这一切似乎都非常混乱 - 当然其他人之前遇到过这个问题?

2 个答案:

答案 0 :(得分:4)

打开上下文菜单时,按下Alt键我遇到了同样的问题。我发现它是上下文菜单中的关键事件,它在创建后不久就发布了它。我通过继承contextmenustrip并覆盖ProcessCmdKey方法解决了这个问题,如下所示:

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

答案 1 :(得分:2)

我认为这可能与KeyDown中打开菜单并将KeyUp传递给菜单的事实更相关。

所以你应该把菜单打开到KeyUp或KeyPress。这应该完全避免这个问题。