Як виявити ключові стани модифікатора у WPF?


151

Чи є якісь глобальні конструкції, якими я можу користуватися, коли мені потрібно отримати доступ, чи кнопки Control, Shift, Alt вниз? Наприклад, всередині MouseDownподії TreeView.

Якщо так, як?

Відповіді:


257

Використовуйте клас Keyboard. Використовуючи Keyboard.IsKeyDownви можете перевірити, чи тепер кнопка Control, Shift, Alt знижена.

Для зміни:

if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{ /* Your code */ }

Для контролю:

if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
{ /* Your code */ }

Для Alt:

if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
{ /* Your code */ }

125

Також є:

// Have to get this value before opening a dialog, or user will have released the control key
if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{

}

13
Набагато краще рішення. Це також дозволяє перевірити всі модифікатори відразу. Якщо ви хочете обробити Ctrl + F, ви не хочете обробляти Ctrl + Shift + F, тому ви можете просто перевірити (e.Key == Key.F && e.KeyboardDevice.Modifiers == ModifierKeys.Control)замість усіх інших речей ...
ygoe

35
Зауважте, що порівняння у наведених вище прикладах дає різні результати! Оскільки перелік ModifierKeys має атрибут Flags, ви можете мати будь-які комбінації значень у enum. Якщо ви хочете зафіксувати ТІЛЬКИ натискання клавіші shift, скористайтеся Keyboard.Modifiers == ModifierKeys.Shiftоператором. Якщо ви хочете (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shiftзафіксувати клавішу shift, але не хвилюйтесь, якщо інші модифікатори натиснуті одночасно, скористайтесь синтаксисом HasFlag або набагато кращимKeyboard.Modifiers.HasFlag(ModifierKeys.Shift)
Patrik B

4
Я не міг зловити модифікатор ключа Windows за допомогою цього методу. (CTRL працював чудово.) Я намагався зловити WIN+RightArrow.
ANeves

1
@ANeves Цікаво, Keyboard.Modifiersпоказує якNone
Чак Савідж

8
    private bool IsShiftKey { get; set; }

    private void OnPreviewKeyDown(object sender, KeyEventArgs e)
    {
        IsShiftKey = Keyboard.Modifiers == ModifierKeys.Shift ? true : false;

        if ((Key.Oem3 == e.Key || ((IsShiftKey && Key.Oem4 == e.Key) || (IsShiftKey && Key.Oem6 == e.Key) || (IsShiftKey && Key.Oem5 == e.Key)) && (validatorDefn as FormatValidatorDefinition).format == "packedascii"))
        {
           e.Handled = true;
        }
    }

2
Відповіді краще з коментарями, а також кодом. Укажіть, будь ласка, якийсь контекст.
Кріс

1
відмінна ідея додати його як властивість
RollRoll

1
Коли я використовував PreviewKeyDown, шукаючи Alt + інший ключ, мені довелося використовувати e.SystemKey замість e.Key (значення "e.Key" було "Система" у випадку використання alt + іншого символу, в моєму випадку
Джош

3

Це, як я впораюся з цим (використовуючи PreviewKeyDown), скажімо, ми шукаємо Alt + R ...

private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
    if ((Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt)
       && e.SystemKey == Key.R)
    {
       //do whatever
    }
}

Можливо, хтось може зрозуміти, чому мені довелося використовувати e.SystemKey, а не лише e.Key, можливо через модифікатор? але це працювало для мене бездоганно під час пошуку модифікатора + ключ.


0

а також:

якщо My.Computer.Keyboard.ShiftKeyDown, то ...

My.Computer.Keyboard.CtrlKeyDown

My.Computer.Keyboard.AltKeyDown


0

Частково запозичує у @Josh, і дещо схоже на @Krushik, а також посилається на питання про різницю між KeyEventArgs.systemKey та KeyEventArgs.Key (відповідаючи, чому Джош повинен використовувати SystemKey); де, з ключами-модифікаторами (такими як Alt), e.Key повертає Key.System, і, таким чином, "справжній" ключ знаходиться в межах e.SystemKey.

Шляхом цього є спочатку отримати «справжній» ключ, а потім виконати ваше умовне:

private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
    // Fetch the real key.
    var key = e.Key == Key.System ? e.SystemKey : e.Key;

    if ((Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
        && key == Key.Return)
    {
        // Execute your code.
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.