The TextInput event enables you to listen for text input in a device-independent manner. The keyboard is the primary means of text input, but speech, handwriting, and other input devices can generate text input also.
For keyboard input, WPF first sends the appropriate KeyDown/KeyUp events. If those events are not handled and the key is textual (rather than a control key such as directional arrows or function keys), then a TextInput event is raised. There is not always a simple one-to-one mapping between KeyDown/KeyUp and TextInput events because multiple keystrokes can generate a single character of text input and single keystrokes can generate multi-character strings. This is especially true for languages such as Chinese, Japanese, and Korean which use Input Method Editors (IMEs) to generate the thousands of possible characters in their corresponding alphabets.
When WPF sends a KeyUp/KeyDown event, Key is set to Key..::.System if the keystrokes could become part of a TextInput event (if ALT+S is pressed, for example). This allows code in a KeyDown event handler to check for Key..::.System and, if found, leave processing for the handler of the subsequently raised TextInput event. In these cases, the various properties of the TextCompositionEventArgs argument can be used to determine the original keystrokes. Similarly, if an IME is active, Key has the value of Key..::.ImeProcessed, and ImeProcessedKey gives the original keystroke or keystrokes.
The following example defines a handler for the Click event and a handler for the KeyDown event,
The first segment of code or markup creates the user interface.
<StackPanel KeyDown="OnTextInputKeyDown">
<Button Click="OnTextInputButtonClick"
Content="Open" />
<TextBox> . . . </TextBox>
</StackPanel>
// Create the UI elements.
StackPanel textInputStackPanel = new StackPanel();
Button textInputeButton = new Button();
TextBox textInputTextBox = new TextBox();
textInputeButton.Content = "Open";
// Attach elements to StackPanel.
textInputStackPanel.Children.Add(textInputeButton);
textInputStackPanel.Children.Add(textInputTextBox);
// Attach event handlers.
textInputStackPanel.KeyDown += new KeyEventHandler(OnTextInputKeyDown);
textInputeButton.Click += new RoutedEventHandler(OnTextInputButtonClick);
The second segment of code contains the event handlers
private void OnTextInputKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.O && Keyboard.Modifiers == ModifierKeys.Control)
{
handle();
e.Handled = true;
}
}
private void OnTextInputButtonClick(object sender, RoutedEventArgs e)
{
handle();
e.Handled = true;
}
public void handle()
{
MessageBox.Show("Pretend this opens a file");
}
Because input events bubble up the event route, the StackPanel receives the input regardless of which element has keyboard focus. The TextBox control is notified first and the OnTextInputKeyDown handler is called only if the TextBox did not handle the input. If the PreviewKeyDown event is used instead of the KeyDown event, the OnTextInputKeyDown handler is called first.
In this example, the handling logic is written two times—one time for CTRL+O, and again for button's click event. This can be simplified by using commands, instead of handling the input events directly. Commands are discussed in this overview and in Commanding Overview.