#1,077 – Checking for Single Modifer vs. Multiple Modifier Keys

In keypress events, you can check to see if the user is also holding down one of the modifier keys (Ctrl, Alt, Shift, or Windows key).  You do this by checking the KeyEventArgs.KeyboardDevice.Modifiers property.

You sometimes want to check to see if one and only one modifier key is being held down (e.g. Ctrl key without Alt, Shift, or Windows).  You do this by checking to see if the Modifiers property is equal to one of the ModifierKeys enumerated values.

            if ((e.Key == Key.G) &&
                (e.KeyboardDevice.Modifiers == ModifierKeys.Control))
                MessageBox.Show("Ctrl+G detected, NO Alt/Shift/Windows");

You may also want to check to see if the control key is being pressed, either alone or in conjunction with one of the other modifier keys.  You do this by using a mask.

            if ((e.Key == Key.G) &&
                ((e.KeyboardDevice.Modifiers & ModifierKeys.Control) == ModifierKeys.Control))
                MessageBox.Show("Ctrl+G or Ctrl+Alt+G, Ctrl+Alt+Windows+G, etc.");

#1,075 – Triggering on IsKeyboardFocusWithin Property

You can set up a trigger that fires whenever a control’s IsKeyboardFocused property becomes truechanging the value of some other property when the control gains keyboard focus.

You can also trigger on the IsKeyboardFocusWithin property.  This property will get set to true for an element when any child of that element has keyboard focus.

In the example below, we set the background color of either StackPanel when any element within the StackPanel has focus.  This technique may be useful when you want to keep track of what section of a window the user is working in and do something based on that knowledge.

    <Window.Resources>
        <Style x:Key="HoneydewFocus" TargetType="StackPanel">
            <Style.Triggers>
                <Trigger Property="IsKeyboardFocusWithin" Value="true">
                    <Setter Property="Background" Value="Honeydew"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    
    <StackPanel>
        <StackPanel Orientation="Horizontal" Margin="10"
                    Style="{StaticResource HoneydewFocus}">
            <Button Content="Click Me" VerticalAlignment="Center"/>
            <TextBox Width="200" Height="25" Margin="10"/>
        </StackPanel>

        <StackPanel Orientation="Horizontal" Margin="10"
                    Style="{StaticResource HoneydewFocus}">
            <Button Content="Or Me" VerticalAlignment="Center"/>
            <TextBox Width="200" Height="25" Margin="10"/>
        </StackPanel>
    </StackPanel>

1075-001

1075-002

#921 – Keyboard Shortcuts Available in a TextBox Control

There are a number of keys that you can use as shortcuts for editing text within a TextBox control.  The most common are:

  • Left/Right Arrow keys:  Move cursor left or right within text
  • Up/Down Arrow keys:  Move cursor to previous/next line, maintaining position within line
  • Ctrl+Left/Right Arrow:  Move to beginning of previous/next word
  • Ctrl+Up Arrow:  Move to start of text
  • Ctrl+Down Arrow:  Move to end of text
  • Shift+Left/Right/Up/Down Arrow:  Move cursor while selecting text
  • Home key:  Move to beginning of current line
  • End key:  Move to end of current line
  • Shift+Home/End:  Select text to beginning/end of current line
  • Page Up/Down:  Move up/down full page
  • Insert key:  Toggle Insert/Overwrite mode
  • Delete key:  Delete character to right of cursor
  • Backspace key:  Delete character to right of cursor
  • Ctrl+A:  Select all text
  • Ctrl+X:  Cut selected text
  • Ctrl+C:  Copy selected text
  • Ctrl+V:  Paste text at current position

#651 – Using Static Members of the Keyboard Class

The KeyboardDevice class represents the current state of the keyboard and is accessible from within keypress event handlers using the KeyEventArgs.KeyboardDevice property.

        private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            Console.WriteLine(string.Format("A key pressed? {0}", e.KeyboardDevice.IsKeyDown(Key.A)));
        }

You can also use the Keyboard.PrimaryDevice property to access the current KeyboardDevice object.

        public void CheckForA()
        {
            Console.WriteLine(string.Format("A key pressed? {0}", Keyboard.PrimaryDevice.IsKeyDown(Key.A)));
        }

In addition to providing access to the KeyboardDevice object, the Keyboard class also provides several static methods that give you the same information.  This is easier than referencing the PrimaryDevice property.

        public void CheckForA()
        {
            Console.WriteLine(string.Format("A key pressed? {0}", Keyboard.IsKeyDown(Key.A)));
        }

#650 – Getting Information About Keyboard Keys from Any Method

You can use the KeyEventArgs.KeyboardDevice property within a keypress handler to get information about any keyboard key.  For example:

private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
    Console.WriteLine(string.Format("Toggle info: Caps Lock:{0}, Scroll Lock: {1}, Num Lock: {2}",
        e.KeyboardDevice.IsKeyToggled(Key.CapsLock),
        e.KeyboardDevice.IsKeyToggled(Key.Scroll),
        e.KeyboardDevice.IsKeyToggled(Key.NumLock)));
}

You can also access the same KeyboardDevice object from any method, using the Keyboard.PrimaryDevice property (found in System.Windows.Input). This property will refer to an instance of a KeyboardDevice object.

        public void MyFunctionToGetKeyInfo()
        {
            Console.WriteLine(string.Format("Toggle info: Caps Lock:{0}, Scroll Lock: {1}, Num Lock: {2}",
                Keyboard.PrimaryDevice.IsKeyToggled(Key.CapsLock),
                Keyboard.PrimaryDevice.IsKeyToggled(Key.Scroll),
                Keyboard.PrimaryDevice.IsKeyToggled(Key.NumLock)));
        }

#649 – KeyStates Property Combines IsDown and IsToggled

In a keypress handler, you can check several states for the key that triggered the event.  The IsDown and IsToggled properties indicate whether the key in question is currently down and whether it’s in the toggled state, respectively.

You can also get information on the current state of the key using the KeyStates property.  The property is an enumerated value containing a bitwise combination of the Down and Toggled values.

        private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            Console.WriteLine(string.Format("--- PreviewKeyDown for key {0}", e.Key));
            Console.WriteLine(string.Format("  IsDown={0}, IsToggled={1}", e.IsDown, e.IsToggled));
            Console.WriteLine(string.Format("  KeyStates={0}", e.KeyStates));
        }

#646 – Detecting a Key’s Toggle State in a Keypress Handler

There are several keys on the keyboard that typically act as toggles–when you first press the key, it is considered toggled, or on–and when you press it again, it is considered untoggled, or off.

The keys that are typically used as toggle keys are: Caps Lock, Scroll Lock and Num Lock.  (Note–the normal Shift key is not typically used as a toggle key).

When a key is pressed, you can determine whether it is entering the toggled state or the untoggled state by checking the KeyEventArgs.IsToggled property in one of the keypress event handlers.

        private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            Trace.WriteLine(string.Format("----- PreviewKeyDown for key {0}, toggled = {1}", e.Key, e.IsToggled));
        }

For example, if I press the Caps Lock four times, I’ll see the following output:

The Caps Lock key is toggling on and off.