В WPF как мне обрабатывать клавиши-модификаторы, которые нажимаются после того, как клавиша удерживается в событии KeyDown?

У меня есть окно WPF, которое я позволяю пользователю перемещать, нажимая клавиши со стрелками. Я сделал это, подключившись к событию KeyDown:

<Window ... KeyDown="Window_OnKeyDown">

Одно нажатие клавиши со стрелкой переместит окно на 1 пиксель. Очевидно, что это довольно медленно, поэтому я также позволяю пользователю удерживать клавишу Shift, чтобы перемещать окно быстрее, по 5 пикселей за раз:

private void Window_OnKeyDown(object sender, KeyEventArgs e)
{
    var key = e.Key;
    var pixelAmount = e.KeyboardDevice.Modifiers == ModifierKeys.Shift ? 5 : 1;

    switch (key)
    {
        case Key.Up:
            Top = Top - pixelAmount;
            break;
        case Key.Down:
            Top = Top + pixelAmount;
            break;
        case Key.Left:
            Left = Left - pixelAmount;
            break;
        case Key.Right:
            Left = Left + pixelAmount;
            break;
    }
}

Этот код прекрасно работает, если пользователь нажимает Shift, а затем клавишу со стрелкой. Проблема в том, что это не работает, если пользователь сначала удерживает клавишу со стрелкой, а затем нажимает Shift, чтобы ускорить движение. Это потому что Window_OnKeyDown() теперь думает, что Shift является активной клавишей, а оператор switch запускается для клавиши Shift, а не для уже нажатой клавиши со стрелкой. Кто-нибудь знает, как я могу исправить это поведение?

1 ответ

Если пользователь нажимает клавишу Shift после клавиши со стрелкой, e.Key изменится на shift и, следовательно, этот код не будет работать. Единственное решение, которое я могу придумать, - это использовать

 bool Shift = (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))

и чтобы получить клавишу со стрелкой, вы также можете использовать Keyboard.IsKeyDown(), например Keyboard.IsKeyDown(Key.Up)

Другие вопросы по тегам