Поделиться через


Keyboard Support

Microsoft Silverlight will reach end of support after October 2021. Learn more.

Silverlight provides a set of keyboard events that enable you to respond to keystroke actions. Keyboard events have a number of similarities with mouse events. Mouse, focus, touch device and keyboard events are sometimes referred to collectively as Silverlight input events.

This topic contains the following sections.

  • Keyboard Events
  • Keyboard Event Handlers
  • Attaching a Keyboard Event Handler
  • Defining a Keyboard Event Handler
  • Using KeyEventArgs
  • Keyboard Routed Events
  • Text Input and Controls
  • Keyboard Event Handling and Reentrancy
  • Input Method Editors
  • Related Topics

Keyboard Events

Silverlight provides the keyboard events described in the following table.

Event

Description

KeyDown

Occurs when a key is pressed while the plug-in (and some element within it) has focus.

KeyUp

Occurs when a key is released while the plug-in (and some element within it) has focus.

Keyboard Events and Focus

In order for a keyboard event to be received, the object must have focus; otherwise, keyboard events are not generated. There are two levels of focus: focus at the plug-in level, and focus at the level of an individual UI element within the Silverlight content area.

A Silverlight plug-in gains focus when the user clicks the plug-in area, tabs to it from the browser-level tab sequence, or provides the appropriate activation action for the plug-in model. You can also call the HTML DOM Focus method in most cases if you want to force focus at the HTML level. The exact focus behavior when Silverlight content is first loaded varies. This depends on whether content is browser hosted, and also can vary for specific browser hosts.

An individual element gains focus when the user clicks directly on that element in the layout, or uses the TAB key to step into a Silverlight tab sequence within the Silverlight content area. You can also call a control's Focus method to force focus, but only if the particular UIElement is also a Control. Generally, if you are forcing focus, you are doing so in order to enable keyboard input for that UI element, and only visible controls have a typical need to process any keyboard input.

If the user clicks an element in the Silverlight plug-in content area, both of these focus conditions occur simultaneously (and sometimes GotFocus fires twice in this case).

For more information about focus and its behavior in the API and through user interaction, see Focus Overview.

Keyboard Events and Browser Hosts

When a Silverlight-based application is hosted in a browser, different browsers might handle keyboard events differently, because of issues such as host keyboard handling that signify commands, and nonportable key codes. When you create an application that uses keyboard input, make sure to test the application in each of your target deployment browsers.

If an application is browser-hosted, the browser host determines which keystrokes it interprets as commands and which keystrokes it passes on to hosted content. This means that certain keystroke combinations cannot be retrieved from KeyDown and KeyUp event handler functions in some set of browser hosts. Most keystrokes that a browser hosts interprets as commands are shortcut or accelerator keystrokes, and when this happens the keystrokes are not passed as key events to Silverlight. For example, CTRL+D is a shortcut keystroke combination for adding a favorite URL to the Firefox and Internet Explorer browser hosts, and neither CTRL nor D is reported as a key event to the intermediate hosting layer that Silverlight must use as its input source when Silverlight-based applications are hosted by a browser.

Browser host behavior also influences auto-repeat behavior for the KeyDown event. Internet Explorer browser hosts can issue repeated key-down events at the browser level for cases where a key remains held down. This auto-repeat behavior is also surfaced by the Silverlight KeyDown event. But some browser hosts do not provide auto-repeat key-down information to their plug-in integration layer, and therefore Silverlight cannot auto-repeat KeyDown for these cases.

Keyboard Events and Full-Screen Mode

When a Silverlight plug-in is displayed in full-screen mode, and the application is either browser-hosted or out-of-browser without elevated trust, keyboard events for the full range of possible keys are prevented from being passed to keyboard event handlers in the application. The following considerations apply when an application is running in full-screen mode:

  • The specific keys UP ARROW, DOWN ARROW, LEFT ARROW, RIGHT ARROW, SPACEBAR, TAB, PAGE UP, PAGE DOWN, HOME, END, ENTER still generate KeyDown and KeyUp. These keys can then be used to initiate actions in your application even if running in full-screen mode.

  • All other keys do not raise KeyDown and KeyUp, and thus you cannot act on these key inputs.

  • ESC is handled by Silverlight and returns theapplication to embedded mode.

This limitation of keyboard input during full-screen mode is a security feature. For more information, see Full-Screen Support.

However, an out-of-browser application that uses elevated trust does not have this restriction, and can handle all key events while operating in full-screen mode. For more information, see Trusted Applications.

Keyboard Event Handlers

An input event handler implements a delegate that provides the following information:

  • You can determine the sender of the event. The sender reports the object where the event handler is attached.

  • You also receive event data. For keyboard events, that data will be an instance of KeyEventArgs. The delegate for handlers is KeyEventHandler. The most relevant properties of KeyEventArgs for most handler scenarios are Key and possibly PlatformKeyCode.

  • Because the keyboard events are routed events, the event data provides OriginalSource. If you are deliberately allowing events to bubble up through an object tree, OriginalSource is sometimes the object of concern rather than sender, although that depends on your design. For more information on how you might use OriginalSource rather than sender, see the"Keyboard Routed Events" section of this topic, or Events Overview for Silverlight.

Attaching a Keyboard Event Handler

You can attach keyboard event-handler functions for any Silverlight object that includes the event as a member (any UIElement derived class). The following XAML example shows how to attach handlers for the KeyUp event for a Canvas.

<Canvas KeyUp="Canvas_KeyUp">
  ...
</Canvas>

Attaching a keyboard event handler using code is not covered here. See Events Overview for Silverlight.

Defining a Keyboard Event Handler

The following example shows the incomplete event handler definition for the OnKeyUp method attached above.

void Canvas_KeyUp(object sender, KeyEventArgs e)
{
    //handling code here
}
Private Sub Canvas_KeyUp(ByVal sender As Object, ByVal e As KeyEventArgs)
    'handling code here
End Sub

Using KeyEventArgs

All keyboard events use KeyEventArgs for event data, and KeyEventArgs contains the following properties:

Key

The KeyDown event is raised if a key is pressed (likewise, KeyUp is raised if a key is released). Usually you are listening to the events in order to process a specific key value. To determine which key is pressed or released, check the Key value in the event data. Key returns either a value that is a portable key value (a member of the Key enumeration), or it returns Key.Unknown.

If Key is not Unknown, then the event represents a single specific portable key value, and you can check it against expected values in your handler to see whether your handler should respond further.

The portable key codes are a common subset of all the possible key codes of the supported platforms for Silverlight. For example, the keystroke 'v' is represented as a Key value of Key.V.

PlatformKeyCode

Certain keystrokes are not portable. An example is the SCROLL LOCK key in Microsoft Windows.

If Key equals Unknown, then a key has been pressed or released, but that key is specific to a particular platform. In this case, you can check the PlatformKeyCode property value. This property returns an integer. The integer must be evaluated in the context of what that integer value means for a particular platform and how it maps its key codes. For information about Microsoft Windows-specific key codes, see Virtual-Key Codes in the MSDN Library. For information on Macintosh-specific key codes, see Keyboard Layout Services Reference on the Apple Developer Connection Web site.

NoteNote:

Determining the platform (which may be necessary to interpret a PlatformKeyCode property value) is not documented in this topic. Depending on your overall application design, you can do this at the HTML or browser host level, by analyzing the HTTP request headers of the hosting HTML page, or by setting a variable on installation of an out-of-browser application. Within the managed API, Silverlight provides the BrowserInformation class, as well as other types in the System.Windows.Browser namespace that might be useful for capturing information that is also available in the HTML DOM or to the browser host.

Modifier Keys

Certain keystrokes are considered to be modifier keys. These are keys that are usually pressed in conjunction with other keys. Modifier keys that are used on all platforms include the SHIFT and CTRL keys. Certain modifier keys are platform specific.

NoteNote:

The key for CTRL may have different labeling on some keyboards. The string CTRL is used in this documentation to identify the key, because this matches the Key.Ctrl value in the API.

Usually you interpret modifier keys in order to check whether a modifier key is pressed and held down at the time that another key event is also received. This is because the other key plus a modifier represents a key combination that is of interest to your application. The modifier key information is not transmitted as part of the same event data in this case. Instead, you use the Keyboard utility class from within your event handlers to check for the modifiers, as part of handling the event for the key value that is potentially modified.

To determine which modifiers are applied, check the Modifiers value of the Keyboard static class. This property returns a ModifierKeys flag enumeration value. The value is a flag because multiple modifiers might be pressed.

However, independent of how you process modifiers for other non-modifier key events, a modifier key still generates its own key events. You can choose to handle these, and you can also choose to track your own modifier key state, but using the Modifiers value is generally more convenient.

NoteNote:

The CTRL key in combination with a mouse click might be involved in producing a right-click mouse input equivalent on Macintosh platforms.

Example Keyboard Event Handler

The following example is an event handler that handles KeyUp. This handler is specifically checking for the CTRL+V key combination. Any other key value (including an unmodified Key.V value) is ignored.

void Canvas_KeyUp(object sender, KeyEventArgs e)
{
    //check for the specific 'v' key, then check modifiers
    if (e.Key==Key.V) { 
        if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control) {
        //specific Ctrl+V action here
        }
    } // else ignore the keystroke
}
Private Sub Canvas_KeyUp(ByVal sender As Object, ByVal e As KeyEventArgs)
    'check for the specific v key, then check modifiers
    If (e.Key = Key.V) Then
        If ((Keyboard.Modifiers And ModifierKeys.Control) = ModifierKeys.Control) Then
            'specific Ctrl+V action here
        Else 'ignore the keystroke
        End If
    End If
End Sub

Keyboard Routed Events

Silverlight supports the concept of a routed event for certain events, which include KeyDown and KeyUp. Routed events in Silverlight use the bubbling routing strategy. The bubbling routing strategy means that an event originates from a child object and is then routed up to successive parent objects in the object tree, presenting another opportunity to handle the same event and interact with the same event data.

Consider the following XAML example, in which KeyUp events are defined for a Canvas and two Button objects. In this case, if you release a key while focus is held by either Button object, it raises the KeyUp event, and any handler added to the Button has first opportunity to handle that event. The event is then bubbled up to the parent Canvas.

<StackPanel KeyUp="TopLevelKB">
  <Button Name="ButtonA" Content="Button A"/>
  <Button Name="ButtonB" Content="Button B"/>
  <TextBlock Name="statusTextBlock"/>
</StackPanel>

The following example shows how to implement the KeyUp event handler for the corresponding XAML content in the preceding example.

void TopLevelKB(object sender, KeyEventArgs e)
{
    if (e.Key!=Key.Unknown) {
        String msg = "The key " + e.Key.ToString();
        msg += " was pressed while focus was on " 
            + (e.OriginalSource as FrameworkElement).Name;
        statusTextBlock.Text = msg;
    }
}
Private Sub TopLevelKB(ByVal sender As Object, ByVal e As KeyEventArgs)
    If Not (e.Key = Key.Unknown) Then
        Dim fe As FrameworkElement = e.OriginalSource
        Dim msg As String = "The key " & e.Key.ToString()
        msg = msg & " was pressed while focus was on "
        msg = msg & fe.Name
        statusTextBlock.Text = msg
    End If
End Sub

Notice the use of the OriginalSource property in the preceding handler. Here, OriginalSource reports the object that raised the event. The object could not be the StackPanel, because the StackPanel is not a control and cannot have focus; only one of the two buttons within the StackPanel could possibly have raised the event, but which one? OriginalSource is how you can distinguish the actual event source object if you are handling the event on a parent object.

The Handled Property in Event Data

Depending on your event handling strategy, you might want only one event handler to react to a bubbling event. For instance, if you have a specific KeyUp handler for one of the Button objects, you might not want the parent panel to also handle the event. For this scenario, use the Handled property in the event data.

The purpose of Handled in a Silverlight routed event data class is to influence the behavior of the Silverlight routed event system, to report that some other handler you had registered earlier on the event route has already acted. When you set Handled to true in an event handler, that event stops routing and is not sent to successive parent elements.

The following example is a modification of the previous event-handler example, this time using Handled. If the event is already handled, the handler will not be able to respond. If the event is not already handled, the handler is invoked. In this case, the event handler also sets Handled to true so that any handlers attached further in the event route and the object tree will not be invoked.

void ButtonKB(object sender, KeyEventArgs e)
{
    if (e.Key!=Key.Unknown) {
        e.Handled=true;
        String msg = "The key " + e.Key.ToString();
        msg += " was handled while focus was on " 
            + (sender as FrameworkElement).Name;
        statusTextBlock.Text = msg;
    }
}
Private Sub ButtonKB(ByVal sender As Object, ByVal e As KeyEventArgs)
    If Not (e.Key = Key.Unknown) Then
        e.Handled=True
        Dim fe As FrameworkElement = sender
        Dim msg As String = "The key " & e.Key.ToString()
        msg = msg & " was handled while focus was on "
        msg = msg & fe.Name
        statusTextBlock.Text = msg
    End If
End Sub

AddHandler and Already-Handled Keyboard Events

You can use a special technique for attaching handlers that can act on events that already are marked handled. This technique uses the AddHandler method to register a handler, rather than using XAML attributes or language specific handler adding syntax such as += in C#. A limitation of this technique in general is that the AddHandler API takes a parameter of type RoutedEvent that identifies the routed event in question. Not all Silverlight routed events provide a RoutedEvent identifier, and this consideration thus affects which routed events can still be handled in the Handled case. The keyboard events KeyDown and KeyUp have routed event identifiers as fields on UIElement. So do TextInput , TextInputStart and TextInputUpdate. However, other related text entry events such as TextBox.TextChanged do not have routed event identifiers and thus cannot be used for the AddHandler technique.

Commanding

In Silverlight 5, a small number of UI elements support commanding. Commanding is a concept that can apply either to mouse or keyboard input, because the input action is abstracted into the command itself. For more information, see the "Commanding" section of Mouse Support.

Text Input and Controls

Certain controls react to keyboard events with their own handling. For instance, a TextBox is a control that is designed to capture and then visually represent text that was entered by using the keyboard, and it uses KeyUp and KeyDown in its own logic to capture keystrokes, then also raises its own TextChanged event if the text actually changed. You can still generally add handlers for KeyUp and KeyDown to a TextBox, or any related control that is intended to process text input. However, as part of its intended design, a control might not respond to all key values that are directed to it through key events. Behavior is specific to each control. As an example, ButtonBase (base class for Button) processes KeyUp so that it can check for the SPACEBAR or ENTER key, which it considers equivalent to a mouse left button down for purposes of raising a Click event. This processing of the event is accomplished by ButtonBase overriding the virtual method OnKeyUp, and in its implementation it sets Handled = true. The result is that any parent of a button listening for a key event in the case of a SPACEBAR would not receive the already-handled event for its own handlers. Another example is TextBox. Some keys such as the ARROW keys are not considered text by TextBox and are instead considered specific to the control UI behavior, and the TextBox marks these event cases as handled.

Custom controls can implement their own similar override behavior for key events by overriding OnKeyDown / OnKeyUp. If your custom control processes specific accelerator keys, or has control or focus behavior that is similar to the scenario described for TextBox, you should place this logic in your own OnKeyDown / OnKeyUp overrides.

Keyboard Event Handling and Reentrancy

When you write keyboard event handlers, or input event handlers in general, such handlers are invoked in a synchronous manner, and are tied to the main UI thread. For this reason you may not be able to invoke certain operations from within a key-related input handler if the actions have potential for reentrancy. Examples are calling ShowDialog for SaveFileDialog or OpenFileDialog. (Exception: opening SaveFileDialog is permitted so long as the client is running Internet Explorer in protected mode, which makes it reentrancy-safe).

Input Method Editors

For TextBox controls (and potentially for derived controls), Silverlight provides APIs that can influence the behavior and state of input method editor (IME) input to that control. The APIs are established as the InputMethod.PreferredImeConversionMode attached property that you set on a TextBox element.

For more information, see InputMethod or Creating Globally Aware Applications.