1

Есть форма, в которой содержится несколько кнопок. И я добавил обработку нажатия клавиш стрелок на клавиатуре, но вместо моих действий в окне просто выбираются другие кнопки (При нажатии на любые другие мой код работает корректно, но мне необходимы именно стрелки. Можно ли как то отключить эти стандартные функции, чтобы они не мешали выполнению моей части кода?

Пример моей части кода:

private void Preview_KeyDown(object sender, KeyEventArgs e)
        {
            else if (e.KeyCode == Keys.Left)
                SerialPort.Write("LEFT1\n");
            else if (e.KeyCode == Keys.Right)
                SerialPort.Write("RIGHT1\n");
            else if (e.KeyCode == Keys.Up)
                SerialPort.Write("UP1\n");
            else if (e.KeyCode == Keys.Down)
                SerialPort.Write("DOWN1\n");
        }
VladD
  • 206,799
  • SerialPort.Write("LEFT1\n"); e.SuppressKeyPress = true; и так далее – Виктор Nov 12 '22 at 11:34
  • Не до конца понял, что делает e.SuppressKeyPress, по сути, мне нужно, чтобы при нажатии клавиш не исполнялись стандартные действия (То-бишь выбор элементов управления в форме) – Walter Dornez Nov 12 '22 at 12:14
  • Читайте тут всё https://learn.microsoft.com/ru-ru/dotnet/api/system.windows.forms.keyeventargs.suppresskeypress?view=windowsdesktop-7.0 Я ошибся надо false – Виктор Nov 12 '22 at 12:19
  • @Виктор true if the key event should not be sent to the control; otherwise, false. не читайте документацию на русском – aepot Nov 12 '22 at 12:41

1 Answers1

1

Надо научиться находить и читать документацию.

Включить перехват клавиш формой в конструкторе

public Preview()
{
    InitializeComponent();
    KeyPreview = true; // это значение так же можно выставить в дизайнере формы
}

Далее для формы в дизайнере задать обработчик события KeyDown и написать такой код

private void Preview_KeyDown(object sender, KeyEventArgs e)
{
    switch (e.KeyCode)
    {
        case Keys.Left:
        case Keys.Right:
        case Keys.Up:
        case Keys.Down:
            SerialPort.Write(e.KeyCode.ToString().ToUpper() + "1\n");
            e.SuppressKeyPress = true;
            break;
    }
}

Выяснилось, что стрелки по умолчанию не вызывают KeyDown, это можно исправить в дополнительном обработчике PreviewKeyDown

private void Preview_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
    switch (e.KeyCode)
    {
        case Keys.Left:
        case Keys.Right:
        case Keys.Up:
        case Keys.Down:
            e.IsInputKey = true;
            break;
    }
}
aepot
  • 49,560
  • Preview_KeyPress сработает только при отпускании клавиши – Виктор Nov 12 '22 at 12:07
  • Спасибо за ответ, но: 1) KeyPressEventArgs не содержит KeyCode. 2) Поместил свитч в KeyDown, но он всё равно не решает проблему, в приложении по прежнему просто выбираются другие кнопки, а не исполняется мой код – Walter Dornez Nov 12 '22 at 12:08
  • @WalterDornez исправил ответ. Вы KeyPreview задали? – aepot Nov 12 '22 at 12:16
  • @aepot Конечно, для этого и прописал, что если использовать другие кнопки, то всё работает и, в моём случае, светодиод на плате зажигается – Walter Dornez Nov 12 '22 at 12:17
  • @aepot Ещё раз детальней опишу происходящее: Если использовать стрелки, то вместо ожидаемой отправки в сериал порт программа просто переключается между кнопками. То-есть по сути мне нужно просто отключить навигацию в программе по стрелкам, но я не знаю, как это сделать – Walter Dornez Nov 12 '22 at 12:18
  • @WalterDornez исправил ответ – aepot Nov 12 '22 at 12:24
  • 1
    @aepot Огромное спасибо! Заработало после последнего уточнения) (P.S. Сам только начинаю, по сути первый серьёзный проект) – Walter Dornez Nov 12 '22 at 12:28
  • @WalterDornez в документации всё это тоже есть https://learn.microsoft.com/ru-ru/dotnet/api/system.windows.forms.control.previewkeydown – aepot Nov 12 '22 at 12:32
  • @aepot Всё же не до конца решилась проблема, теперь оно работает ровно до первого нажатия на любую кнопку, а после нажатия любой кнопки мышью он всё равно обрабатывает стрелки как навигацию по программе... – Walter Dornez Nov 12 '22 at 12:37
  • потому, что у Вас уже другой элемент выбран, а на нём нет обработчика – Виктор Nov 12 '22 at 12:38
  • @WalterDornez попробуйте заменить Handled на SuppressKeyPress – aepot Nov 12 '22 at 12:38
  • @aepot Не помогло, к сожалению – Walter Dornez Nov 12 '22 at 12:42
  • @WalterDornez выглядит как KeyPreview = true; не задан – aepot Nov 12 '22 at 12:44
  • @aepot Смотрите, что происходит сейчас: Программа запускается, я нажимаю стрелки и всё работает, после, я решаю нажать на какую то кнопку (Button) в программе мышкой и после этого пытаюсь нажимать стрелки, но вместо того, что мне надо, он просто переключает фокус в приложении между кнопками, а не делает то, что делал сразу после запуска программы – Walter Dornez Nov 12 '22 at 12:47
  • @aepot Было бы гораздо проще, если можно было бы отключить навигацию в программе по стрелкам... – Walter Dornez Nov 12 '22 at 12:49
  • @WalterDornez я понимаю, но код пишу с телефона, и честно говоря прямо сейчас нет возможности поковырать настоящий проект. В целом, я бы посоветовал использовать WPF, там таких глюков нет. https://ru.stackoverflow.com/a/1222168/373567 – aepot Nov 12 '22 at 12:52
  • @aepot К сожалению, переход на WPF будет слишком сложным, ибо большинство функций уже реализовано здесь – Walter Dornez Nov 12 '22 at 12:54
  • @WalterDornez большинство функций, не связанных с интерфейсом, можно просто скопировать. – aepot Nov 12 '22 at 12:55