Захват Ctrl + C в текстовом поле

Несмотря на то, что я работаю с С# (Windows Forms) в течение многих лет, у меня есть момент выхода из строя, и я не могу для жизни из меня выяснить, как поймать пользователя, набрав Ctrl + C в текстовое поле.

Мое приложение в основном является терминальным приложением, и я хочу, чтобы Ctrl + C отправлял (byte)3 на последовательный порт, а не был ярлыком для копирования в буфер обмена.

Я установил для ярлыков enabled свойство false в текстовое поле. Однако, когда пользователь нажимает Ctrl + C, событие нажатия клавиши не срабатывает.

Если я поймаю keydown, событие срабатывает, когда пользователь нажимает Ctrl (то есть, прежде чем нажать клавишу C).

Возможно, что-то глупое простое, что мне не хватает.

Ответ 1

Перейдите и используйте событие KeyDown, но в этом случае проверьте как Ctrl, так и C, например:

if (e.Control && e.KeyCode == Keys.C) {
    //...
    e.SuppressKeyPress = true;
}

Кроме того, чтобы предотвратить обработку нажатия клавиш базовым TextBox, установите для свойства SuppressKeyPress значение true, как показано.

Ответ 2

Ключевые события происходят в следующем порядке:

  • KeyDown
  • KeyPress
  • KeyUp

Событие KeyPress не создается нехарактерными ключами; однако нехарактерные ключи действительно увеличивают события KeyDown и KeyUp. Управление - это нехарактерный ключ.

Вы можете проверить эту строку кода: if (e.KeyData == (Keys.Control | Keys.C))

Ответ 3

У меня была проблема ловли Ctrl + C на TextBox на KeyDown. Я получил ключ Control, когда были нажаты кнопки Control и C. В решении использовалось PreviewKeyDown:

private void OnLoad()
{
    textBox.PreviewKeyDown += OnPreviewKeyDown;
    textBox.KeyDown += OnKeyDown;
}

private void OnPreviewKeyDown( object sender, PreviewKeyDownEventArgs e)
{
    if (e.Control)
    {
        e.IsInputKey = true;
    }
}

private void OnKeyDown( object sender, KeyEventArgs e)
{
    if (e.Control && e.KeyCode == Keys.C) {
        textBox.Copy();
    }
}

Ответ 4

D'ах! Просто понял это. Из трех возможных событий тот, который я не пробовал, тот, который мне нужен! Событие KeyUp является важным:

private void txtConsole_KeyUp(object sender, KeyEventArgs e)
{
    if (e.KeyData == (Keys.C | Keys.Control))
    {
        _consolePort.Write(new byte[] { 3 }, 0, 1);
        e.Handled = true;
    }
}

Ответ 5

Попробуйте следующее: захватите события up arrow и down arrow. Когда вы обнаруживаете down arrow для CTRL, установите флаг; когда вы обнаружите флаг up arrow, reset. Если вы обнаруживаете клавишу C, пока установлен флаг, у вас есть Ctrl + C.

Edit. Ой... Джей ответ, безусловно, лучше.: -)

Ответ 6

Я не знаю, связано ли это с изменением в более новой версии или из-за того, что я пытаюсь использовать это в ListBox, но нет e.Control в KeyEventArgs e, который я получаю из KeyDown.

Мне пришлось работать над решением, я придумал это (это не самый красивый, но он отлично работает):

private List<Key> KeyBuff = new List<Key>();

private void ListBox_KeyDown(object sender, KeyEventArgs e)
{
    if (!KeyBuff.Exists(k => k == e.Key))
        KeyBuff.Add(e.Key);

    if (KeyBuff.Exists(k => k == Key.LeftCtrl || k == Key.RightCtrl) &&
        KeyBuff.Exists(k => k == Key.C))
    {
        // Desired detection
        Clipboard.SetText(SelectedText);
    }
}

private void ListBox_KeyUp(object sender, KeyEventArgs e)
{
    KeyBuff.Clear();
}