开发者

Catching Ctrl + C in a textbox

Despite me working with C# (Windows Forms) for years, I'm having a brain fail moment, and can't for the life of me figure out how to catch a user typing Ctrl + C into a textbox.

My application is basically a terminal application, and I want Ctrl + C to send a (byte)3 to a serial port, rather than be the shortcut for Copy to Clipboard.

I've set the shortcuts enabled property to false on the textbox. Yet when the user hits Ctrl + C, the keypress event doesn't fire.

If I catch keydown, the event fires when the user presses Ctrl (that is, before they hit the C key).

It's probably somethin开发者_如何学编程g stupidly simple that I'm missing.


Go ahead and use the KeyDown event, but in that event check for both Ctrl and C, like so:

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

Also, to prevent processing the keystroke by the underlying TextBox, set the SuppressKeyPress property to true as shown.


Key events occur in the following order:

  1. KeyDown
  2. KeyPress
  3. KeyUp

The KeyPress event is not raised by noncharacter keys; however, the noncharacter keys do raise the KeyDown and KeyUp events. Control is a noncharacter key.

You can check with this line of code: if (e.KeyData == (Keys.Control | Keys.C))


I had a problem catching Ctrl + C on a TextBox by KeyDown. I only got Control key when both Control and C were pressed. The solution was using 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();
    }
}


D'oh! Just figured it out. Out of the three possible events, the one I haven't tried is the one I needed! The KeyUp event is the important one:

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;
    }
}


If you want to catch such combinations of keys in KeyPress Event look at this table here:

http://www.physics.udel.edu/~watson/scen103/ascii.html

in Non-Printing Characters section you can see the Dec numbers for each combination. For example, Dec number for Ctrl + C is 3. So you can catch it in KeyPress Event like this:

private void btnTarget_KeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar != 3) // if it is not Ctrl + C
    {
       // do something
    }
}


Try the following: capture the up arrow and down arrow events. When you detect down arrow for CTRL, set a flag; when you detect up arrow, reset the flag. If you detect the C key while the flag is set, you have Ctrl+C.

Edit. Ouch... Jay's answer is definitely better. :-)


I don't know if it's because some change in newer version or because I am trying to use this on ListBox, but there is no e.Control in KeyEventArgs e that I get from KeyDown.

I had to work around solution, I came up with this (it's not the prettiest one, but it works fine):

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();
}


For me, it's not working with KeyDown event so I tried with PreviewKeyDown and it's worked.

private void txt_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
  if (e.Control == true && e.KeyCode == Keys.C)
  {
    Clipboard.SetText(txt.SelectedText);
  }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜