#1,076 – Two Ways to Check for Use of Modifier Keys in Keypress Handlers

You can check for the presence of modifier keys (e.g. Alt, Ctrl, Shift, or Windows key) in keypress handlers using the KeyboardDevice.Modifier property.  For example:

        private void Window_KeyDown(object sender, KeyEventArgs e)
            if ((e.Key == Key.G) &&
                (e.KeyboardDevice.Modifiers == ModifierKeys.Control))
                MessageBox.Show("Ctrl+G detected");

Note that this method doesn’t distinguish between whether you pressed the left vs. right Ctrl keys.  This is normally what you want.  If you do want to distinguish between the two, you can explicitly check for left vs. right.

        private void Window_KeyDown(object sender, KeyEventArgs e)
            if ((e.Key == Key.G) &&
                MessageBox.Show("Left Ctrl+G detected");
            else if ((e.Key == Key.G) &&
                MessageBox.Show("Right Ctrl+G detected");

#625 – Converting a Keypress Timestamp to a DateTime

The various keypress (up/down) event handlers will all have access to a KeyEventArgs object, which includes a Timestamp property.  This property indicates the exact time that the key was pressed or released.

The value of the Timestamp property is an int, rather than a DateTime object.  The integer represents the number of milliseconds since the last reboot.  When the value grows too large to store in the integer object, it resets to 0.  This happens every 24.9 days.

You can convert this timestamp value to an actual date/time by starting with the current time and subtracting the number of milliseconds that have elapsed since the timestamp.  You can read the current number of milliseconds since reboot from the Environment.TickCount property.

        private void TextBox_KeyDown(object sender, KeyEventArgs e)
            DateTime dt = DateTime.Now;
            dt.AddMilliseconds(e.Timestamp - Environment.TickCount);

            Trace.WriteLine(string.Format("Key DOWN at: {0}", dt.ToString("h:mm:ss.FFF tt")));

#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)

#620 – Why Are There So Many KeyPress Events?

When you press a single key within a WPF application, there are potentially a number of different keypress events that can fire.  But why are there so many different events that can possibly fire?

There are several reasons why there isn’t just a single keypress event.

  • Your application will only see the events for which you define a handler.  There is a large set of possible events so that you can choose which ones make sense for your application to handle.
  • Preview events exist so that a parent control can intercept keypress events for its children or descendants.  The tunneling allows you to decide at what level you want to preview the event.
  • The actual keypress event bubbles up the logical tree so that you can decide at what level to actually respond to the event.  In this way, you can handle multiple events in a single place.