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:
- KeyDown
- KeyPress
- 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);
}
}
精彩评论