#636 – Keyboard Events that Fire When A Key Is Held Down

When you hold a key down in Windows, the key begins to repeat after a short delay, as if you you were repeatedly pressing it.

While a key is held down, the PreviewKeyDown, KeyDown and PreviewTextInput events will fire repeatedly.

You can detect whether a keypress is the original/first keypress, or one of the repeats, by checking the KeyEventArgs.IsRepeat property.

Let’s say we press the ‘a’ key while a TextBox has focus and hold it down long enough for three ‘a’ characters to be inserted.  We’ll get the following events:

  • PreviewKeyDown, Key = A, IsRepeat = False
  • KeyDown, Key = A, IsRepeat = False
  • PreviewTextInput, Text = a
  • (TextBox contains “a”)
  • PreviewKeyDown, Key = A, IsRepeat = True
  • KeyDown, Key = A, IsRepeat = True
  • PreviewTextInput, Text = a
  • (TextBox contains “aa”)
  • PreviewKeyDown, Key = A, IsRepeat = True
  • KeyDown, Key = A, IsRepeat = True
  • PreviewTextInput, Text = a
  • (TextBox  contains “aaa”)
  • PreviewKeyUp, Key = A, IsRepeat = False
  • KeyUp, Key = A, IsRepeat = False

#631 – Event Sequence for KeyPressUp, KeyPressDown and TextInput

The full event sequence for keyboard related events is shown below, as they propagate down (tunneling) or up (bubbling) the logical tree.

If we have a Window that contains a StackPanel, which in turn contains a TextBox, the sequence of events would be:

  • Window_PreviewKeyDown
  • StackPanel_PreviewKeyDown
  • TextBox_PreviewKeyDown
  • TextBox_KeyDown
  • StackPanel_KeyDown
  • Window_KeyDown
  • Window_PreviewTextInput
  • StackPanel_PreviewTextInput
  • TextBox_PreviewTextInput
  • TextBox_TextInput – suppressed/handled
  • StackPanel_TextInput – suppressed/handled
  • Window_TextInput – suppressed/handled
  • Window_PreviewKeyUp
  • StackPanel_PreviewKeyUp
  • TextBox_PreviewKeyUp
  • TextBox_KeyUp
  • StackPanel_KeyUp
  • Window_KeyUp

Note that the TextInput event is listed, since TextInput events would normally fire for the originating control and then propagate up the logical tree.  But in the case of TextBox, the TextInput event is marked as handled and therefore does not fire.

#629 – Some Controls May Swallow Keypress Events

If you are handling KeyUp and/or KeyDown events for a control, you’ll notice that certain keys may be “swallowed” by a particular control.  In other words, you might not get all of the keypress events.

A control may intercept a particular event and mark it as handled if it interprets the keypress and uses it within the control.

For example, a TextBox control will “swallow” the KeyDown event for the Backspace key, since this key is used to delete characters in the control.

In the example below, I press the ‘a’ key and see all four (PreviewKeyDown, KeyDown, PreviewKeyUp, KeyUp) keypress events.  However, when I press Backspace, I see only three events–the TextBox intercepts the KeyDown event, erases a character, and marks the event as handled.

 

#628 – Key Up/Down Sequence When Using ALT Key

When you use the Alt-key in combination with another key, the control that has focus will receive KeyUp and KeyDown events for both the Alt key and the combination key.

When using the Alt key, the Key property of the KeyEventArgs object will be Key.System and the actual key being pressed will be available in the SystemKey property.  This is true for both the Alt key and the combination key.

For example, pressing Alt-Q while a TextBox control has focus will result in the following events for the TextBox, in the sequence listed.

  • PreviewKeyDown, Key = System, SystemKey = LeftAlt
  • KeyDown, Key = System, SystemKey = LeftAlt
  • PreviewKeyDown, Key = System, SystemKey = Q
  • KeyDown, Key = System, SystemKey = Q
  • PreviewKeyUp, Key = System, SystemKey = Q
  • KeyUp, Key = System, SystemKey = Q
  • PreviewKeyUp, Key = System, SystemKey = LeftAlt
  • KeyUp, Key = System, SystemKey = LeftAlt

#627 – Detecting Whether The Ctrl Key Is Pressed In a KeyDown Event Handler

When you press a Ctrl-key combination (e.g. Ctrl+G) and you are monitoring KeyDown (or KeyUp) events, you’ll see two separate KeyDown events–one for the Ctrl key and one for the key pressed with it.

If you want to respond to a Ctrl-key combination within a KeyDown event handler, you can do the following :

  • Use the KeyEventArgs.Key property to see whether the event is being fired because the combination key (e.g. ‘G’) is being pressed
  • Use the Keyboard.IsKeyDown method to check whether the Ctrl key is also currently down
        private void TextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if ((e.Key == Key.G) &&
                (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
                MessageBox.Show("You pressed Ctrl+G !");
        }

#626 – Key Up/Down Sequence When Using CTRL Key

When you use the Ctrl-key in combination with another key, e.g. pressing Ctrl-G, the control that has focus will receive KeyUp and KeyDown events for both the Ctrl key and the main key that you are pressing.

For example, if a TextBox control has focus and I press Ctrl-G (which doesn’t normally do anything in a TextBox) and I use the Ctrl key on the left side of the keyboard, I’ll see the following events for the TextBox, in the sequence listed.

  • PreviewKeyDown, key = LeftCtrl
  • KeyDown, key = LeftCtrl
  • PreviewKeyDown, key = G
  • KeyDown, key = G
  • PreviewKeyUp, key = G
  • KeyUp, key = G
  • PreviewKeyUp, key = LeftCtrl
  • KeyUp, key = LeftCtrl

In this case, you can see that my sequence in pressing/releasing the keys was:

  • Press and hold left Ctrl key
  • Press G key
  • Release G key
  • Release Ctrl key

#624 – Information Available to Key Up/Down Events

All four of the keypress-related events (PreviewKeyDown, KeyDown, PreviewKeyUp, and KeyUp) send an instance of the KeyEventArgs object to the associated event handler.

private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
}

Here are some of the more important properties available in the KeyEventArgs object:

  • Key property – The System.Windows.Input.Key being pressed.  E.g. Key.Q
  • Timestamp – Time of key press, in # ticks (milliseconds) since last reboot
  • IsDown / IsUp – Is the key currently down or up?
  • IsRepeat – Is this keystroke a repeat due to holding a key down?
  • IsToggled – For keys that toggle, like Caps Lock, indicates current toggled state
  • Source – The control that had focus when the key was pressed
  • OriginalSource – Either the control where the key was pressed, or a lower-level child element
  • Handled – Can set to true to indicate that you’ve handled the event, short-circuiting the event routing (generally)