В 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)