Как предотвратить закрытие контекстного меню при удерживании клавиши Alt? - PullRequest
0 голосов
/ 21 февраля 2019

Мне нужно разрешить использование клавиши Alt в качестве модификатора при выборе определенных пунктов меню в ContextMenuStrip.Это прекрасно работает со всеми другими модификаторами, такими как Ctrl или Shift.Однако по какой-то причине Alt автоматически закрывает контекстное меню.

Я пытался использовать событие Closing в контекстном меню и свойство пункта меню AutoClose, но это оказывается более неуклюжимчем ожидалось.В частности, несмотря на то, что контекстное меню остается открытым, приложение MenuStrip активируется (что может объяснить, почему контекстное меню закрывается в первую очередь).

Я пробовал искать, но обнаружил на удивление маловопросы об этом, и ни один о переполнении стека, поэтому мне интересно, может ли быть лучший способ обойти это, что я пропустил?

Пример кода, показывающий, что подавление активации 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);
    }
}

1 Ответ

0 голосов
/ 21 февраля 2019

Это сделано специально, поэтому вам придется самостоятельно отслеживать состояние.Но это определенно остановит Alt от достижения MenuStrip.

. Это низкоуровневая фильтрация клавиатуры, поэтому вам придется решить, что делать, когда Alt нажимается полностью самостоятельно, однако,

Вы также можете изменить условное выражение для проверки на Alt плюс некоторое состояние .

Короче говоря, возврат true из PreFilterMesssage остановит его достижениеваше приложение.

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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...