Как создать составные сочетания клавиш в приложении Windows Forms? - PullRequest
13 голосов
/ 10 октября 2008

Я хочу создать компонент, который позволит нам создавать сложные сочетания клавиш, связанные с произвольной командой, как в Visual Studio IDE и Microsoft Office.

То есть сочетания клавиш, состоящие из последовательности нескольких нажатий клавиш, например Ctrl + W + C . В Visual Studio это открывает представление класса. При нажатии первого набора клавиш ( Ctrl + W ) было нажато сообщение "(Ctrl + W). Ожидание второй клавиши аккорда ..." в строке состояния.

Ответы [ 5 ]

12 голосов
/ 11 октября 2008

Отвечая на вопрос аккордов клавиатуры , в частности, я не верю, что на данный момент вам доступна готовая опция.

Однако это должно быть достаточно просто для моделирования. Я бы создал один класс, возможно KeyboardChordProvider. Он должен знать о событиях клавиатуры на уровне формы. Как указано в другом месте, свойство Form.KeyPreview должно быть true. Этого поставщика может быть достаточно, чтобы подписаться на событие Form.KeyPress. Вы можете сделать все это в конструкторе провайдера, если передадите форму.

Вам необходимо зарегистрировать возможные нажатия клавиш у провайдера.

Внутренне этот экземпляр будет отслеживать текущее состояние. Всякий раз, когда наблюдается нажатие клавиши, представляющее первую клавишу аккорда, вы обновляете состояние провайдера и инициируете событие, чтобы подписчик мог задать текст: (CTRL + W) была нажата. В ожидании второго ключа аккорда ...

Если следующее нажатие клавиши соответствует потенциальной вторичной опции, тогда у вас есть совпадение и вы можете вызвать событие ChordPressed, содержащее детали введенных штрихов. В качестве альтернативы вы можете просто вызвать конкретный обратный вызов, который был предоставлен провайдеру во время регистрации аккорда (чтобы не было оператора switch или какой-либо другой диспетчеризации в обработчике события ChordPressed).

Если в любое время нажатие клавиши не соответствует потенциальной опции next , вы сбросите состояние провайдера.

Внутри поставщика вы можете смоделировать возможные нажатия клавиш, используя древовидную структуру. Текущее состояние провайдера - это просто определенный узел дерева. Сначала корневой узел будет активным. Если дочерний элемент соответствует нажатию клавиши, он становится текущим узлом в ожидании следующего удара. Если дочерний узел был листовым узлом, то соответствовал весь аккорд, и вы вызывали бы событие ChordPressed (передавая цепочку штрихов, которые привели вас к этой точке) или вызывали обратный вызов, сохраненный в листе. Всякий раз, когда ни одно нажатие клавиши не соответствует дочернему, вернитесь к активному корневому узлу.

Я думаю, этот дизайн достиг бы того, что вы хотите.

2 голосов
/ 10 октября 2008

Элементы управления меню имеют свойство с именем ShortCut , в котором можно назначить значение. При нажатии этой клавиши быстрого вызова, этот пункт меню будет вызываться. Используйте это свойство для команд, имеющих соответствующее меню.

Если вам нужны ярлыки, которые не будут доступны в меню, вам придется справиться с этим самостоятельно с помощью событий KeyUp или KeyDown , либо в форме или контроль. Объект KeyEventArgs будет передан вашему обработчику, и вы сможете проверить, какая клавиша нажата, и были ли нажаты клавиши Ctrl, Alt или Shift.

Пример кода из MSDN:

// Handle the KeyDown event to determine the type of character entered into the control.
private void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
    // Initialize the flag to false.
    nonNumberEntered = false;

    // Determine whether the keystroke is a number from the top of the keyboard.
    if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9)
    {
        // Determine whether the keystroke is a number from the keypad.
        if (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9)
        {
            // Determine whether the keystroke is a backspace.
            if(e.KeyCode != Keys.Back)
            {
                // A non-numerical keystroke was pressed.
                // Set the flag to true and evaluate in KeyPress event.
                nonNumberEntered = true;
            }
        }
    }
    //If shift key was pressed, it's not a number.
    if (Control.ModifierKeys == Keys.Shift) {
        nonNumberEntered = true;
    }
}
0 голосов
/ 10 октября 2008

Зависит от объема сочетания клавиш. Если вы хотите, чтобы сочетание клавиш использовалось из любого элемента управления в форме без использования панели инструментов, установите

Form.KeyPreview = true;

в форме. Это позволит фильтровать все события нажатия клавиш по событиям KeyPress , KeyDown и KeyUp на уровне формы, что позволит обрабатывать одно сочетание клавиш одно местоположение вместо дублирования функциональности во всех пользовательских элементах управления.

MSDN: свойство Form.KeyPreview

0 голосов
/ 10 октября 2008

В дополнение к некоторым ответам использование амперсанда в заголовке кнопки или пункта меню приведет к его подчеркиванию и получению доступа с помощью Alt + буквы, которой предшествует амперсанд &.

Другими словами, если у вас есть пункт меню с заголовком & File , он будет отображаться с подчеркиванием под буквой F, и пользователь может вызвать меню, нажав Alt + F .

0 голосов
/ 10 октября 2008

Используйте событие формы OnKeyPressed и проверьте, была ли нажата нужная комбинация клавиш в аргументе eventArgs

...