Difference between the KeyDown Event, KeyPress Event and KeyUp Event in Visual Studio
KeyDown: happens when the person presses a key (when the keyboard first detects a finger on a key, this happens when the key is pressed down).
KeyPress: happens when a key is pressed and then released.
KeyUp: happens when the key is released
You are right that all of these events occur when a key is pressed and then released, in the order I described above.
What's the difference between KeyDown and KeyPress in .NET?
There is apparently a lot of misunderstanding about this!
The only practical difference between KeyDown
and KeyPress
is that KeyPress
relays the character resulting from a keypress, and is only called if there is one.
In other words, if you press A on your keyboard, you'll get this sequence of events:
- KeyDown: KeyCode=Keys.A, KeyData=Keys.A, Modifiers=Keys.None
- KeyPress: KeyChar='a'
- KeyUp: KeyCode=Keys.A
But if you press Shift+A, you'll get:
- KeyDown: KeyCode=Keys.ShiftKey, KeyData=Keys.ShiftKey, Shift, Modifiers=Keys.Shift
- KeyDown: KeyCode=Keys.A, KeyData=Keys.A | Keys.Shift, Modifiers=Keys.Shift
- KeyPress: KeyChar='A'
- KeyUp: KeyCode=Keys.A
- KeyUp: KeyCode=Keys.ShiftKey
If you hold down the keys for a while, you'll get something like:
- KeyDown: KeyCode=Keys.ShiftKey, KeyData=Keys.ShiftKey, Shift, Modifiers=Keys.Shift
- KeyDown: KeyCode=Keys.ShiftKey, KeyData=Keys.ShiftKey, Shift, Modifiers=Keys.Shift
- KeyDown: KeyCode=Keys.ShiftKey, KeyData=Keys.ShiftKey, Shift, Modifiers=Keys.Shift
- KeyDown: KeyCode=Keys.ShiftKey, KeyData=Keys.ShiftKey, Shift, Modifiers=Keys.Shift
- KeyDown: KeyCode=Keys.ShiftKey, KeyData=Keys.ShiftKey, Shift, Modifiers=Keys.Shift
- KeyDown: KeyCode=Keys.A, KeyData=Keys.A | Keys.Shift, Modifiers=Keys.Shift
- KeyPress: KeyChar='A'
- KeyDown: KeyCode=Keys.A, KeyData=Keys.A | Keys.Shift, Modifiers=Keys.Shift
- KeyPress: KeyChar='A'
- KeyDown: KeyCode=Keys.A, KeyData=Keys.A | Keys.Shift, Modifiers=Keys.Shift
- KeyPress: KeyChar='A'
- KeyDown: KeyCode=Keys.A, KeyData=Keys.A | Keys.Shift, Modifiers=Keys.Shift
- KeyPress: KeyChar='A'
- KeyDown: KeyCode=Keys.A, KeyData=Keys.A | Keys.Shift, Modifiers=Keys.Shift
- KeyPress: KeyChar='A'
- KeyUp: KeyCode=Keys.A
- KeyUp: KeyCode=Keys.ShiftKey
Notice that KeyPress
occurs in between KeyDown
and KeyUp
, not after KeyUp
, as many of the other answers have stated, that KeyPress
is not called when a character isn't generated, and that KeyDown
is repeated while the key is held down, also contrary to many of the other answers.
Examples of keys that do not directly result in calls to KeyPress
:
- Shift, Ctrl, Alt
- F1 through F12
- Arrow keys
Examples of keys that do result in calls to KeyPress
:
- A through Z, 0 through 9, etc.
- Spacebar
- Tab (KeyChar='\t', ASCII 9)
- Enter (KeyChar='\r', ASCII 13)
- Esc (KeyChar='\x1b', ASCII 27)
- Backspace (KeyChar='\b', ASCII 8)
For the curious, KeyDown
roughly correlates to WM_KEYDOWN
, KeyPress
to WM_CHAR
, and KeyUp
to WM_KEYUP
. WM_KEYDOWN
can be called fewer than the the number of key repeats, but it sends a repeat count, which, IIRC, WinForms uses to generate exactly one KeyDown per repeat.
KeyDown event in a Form
You can override ProcessCmdKey
to handle key presses on the form level.
See this question for more details and examples:
Hotkey (not global) in Windows Forms .NET
Why DateTimePicker won't trigger keyDown and KeyPress events with the tab key?
The Tab key is used for navigation. Moving the focus from one control to another. So your KeyDown event handler can never see it, the keystroke is intercepted and used before that. You could subscribe the PreviewKeyDown event and set the e.IsInputKey = true as a workaround, check the MSDN sample code in the linked article for code.
But it is the wrong event to use anyway, you'd still want this to work when the user changes focus with the mouse instead of the keyboard. So use the Enter
event instead.
Do beware that both approaches have the same problem, the focus might already be on the month part from previous usage of the control so now your code will incorrectly move it to the year part. And you can't find out what part has the focus, that is up a creek without a good paddle. A very ugly workaround for that is to change the Format property, and back, that forces the control to re-create the control window and that always resets the focus. Use BeginInvoke() to run that code. Perhaps more constructively, consider to just not display the day if you are only interested in month+year, CustomFormat property.
Sample code that implements the focus hack:
Private Sub DateTimePicker1_Enter(sender As Object, e As EventArgs) Handles DateTimePicker1.Enter
Me.BeginInvoke(
New Action(Sub()
'' Hack to reset focus
DateTimePicker1.Format = DateTimePickerFormat.Long
DateTimePicker1.Format = DateTimePickerFormat.Short
DateTimePicker1.Focus()
SendKeys.Send("{Right}")
End Sub))
End Sub
Difference between the KeyDown Event, KeyPress Event and KeyUp Event in Visual Studio
KeyDown: happens when the person presses a key (when the keyboard first detects a finger on a key, this happens when the key is pressed down).
KeyPress: happens when a key is pressed and then released.
KeyUp: happens when the key is released
You are right that all of these events occur when a key is pressed and then released, in the order I described above.
Double result when using keypress
You don't need to append keychar in your result.Text
(Assuming result
is your TextBox
item) as you have written in line result.Text += e.KeyChar.ToString();
. That's the line which is doubling your input.
Remove it and it'll work as expected.
Related Topics
Get Application's Window Handles
Linq to Find Series of Consecutive Numbers
Simulating Keyboard with Sendinput API in Directinput Applications
Http Error 500.19 When Publish .Net Core Project into Iis with 0X80070005
Outofmemoryexception When I Read 500Mb Filestream
Check If an Executable Exists in the Windows Path
Quartz.Net Setup in an ASP.NET Website
MVC 4 How Pass Data Correctly from Controller to View
How to Create a Sequence of Integers in C#
C# Image.Clone Out of Memory Exception
Visual Studio 2010: How to Enforce Build Order of Projects in a Solution
Ef 6 - How to Correctly Perform Parallel Queries
How to Dynamically Switch Web Service Addresses in .Net Without a Recompile
Create Out-Of-Process Com in C#/.Net
Resharper Complains When Method Can Be Static, But Isn'T
How to Pass a Table-Value Parameter