Проблемы с отображением ContextMenu во время события KeyDown - PullRequest
0 голосов
/ 07 октября 2009

Я использую следующий код для отображения контекстного меню в моей форме, когда кто-то нажимает «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!")
}

Проблема, с которой я столкнулся, заключается в том, что второй элемент меню («Some & Android») «нажимается» сразу же после отображения меню - очевидно, потому что нажатие клавиши (Alt-A) немедленно передается меню.

Если я изменю этот пункт меню на другую мнемонику (например, «& Some Android»), то этого не произойдет, и меню будет отображаться как обычно.

Я знаю, что класс ContextMenu устарел, но есть ли способ предотвратить такое поведение? Я уже пытался установить для свойства Handled EventArgs значение true, но это ничего не сделало (предположительно потому, что ничего не будет делать до тех пор, пока не завершится обработчик события, а метод Show () останавливает выполнение, пока ContextMenu больше не отображается.

ОБНОВЛЕНИЕ: Я обновил код для использования более нового класса ContextMenuStrip и обнаружил, что происходит то же самое, однако класс ContextMenuStrip предоставляет мне гораздо больше методов для переопределения, что позволяет лучше управление пунктом меню.

Я заметил, что с классом ContextMenuStrip метод Show () возвращается мгновенно (пока меню все еще отображается), однако даже установка свойства Handled для аргументов события в значение true не препятствует обработке нажатия клавиши по контекстному меню.

Я пытаюсь использовать более сложную логику, чтобы решить, следует ли запускать событие щелчка на основе того, прошел ли определенный интервал времени с момента отображения меню и обработано ли событие KeyUp с тех пор, но все это кажется очень грязным - наверняка кто-то еще сталкивался с этой проблемой раньше?

Ответы [ 2 ]

4 голосов
/ 08 сентября 2010

У меня была такая же проблема с нажатой клавишей 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);
    }
}
2 голосов
/ 07 октября 2009

Я думаю, что это может быть больше связано с тем, что в KeyDown вы открываете свое меню, а KeyUp затем передается в меню.

Так что, возможно, вам следует переместить открытие меню в KeyUp или KeyPress. Это должно полностью избежать проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...