Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does PreviewTextInput not handle spaces?

I am handling the PreviewTextInput event on my window to handle swipes from a magnetic card reader. I handle the event on the window, so that it does not matter which individual control is focused.

Once the handler determines a swipe has started (a '%' or ';' character is input), it handles all events until the swipe is finished. This system generally works quite nicely, with a few important exceptions:

When a space character (and possibly a \n character) are input from the reader, they are not handled by PreviewTextInput, but are sent directly into whatever control is focused. Oddly enough, the handler does receive \r characters. This causes undesired behavior.

What I want is a way to capture all key events at the window level, and have an opportunity to handle them if I want to. I have tried PreviewKeyDown and found it a bit cumbersome to use, and to get char values from. PreviewTextInput is much nicer because I can simply read the Text property.

Is there a reason PreviewTextInput does not handle certain characters? Is there any comparable method to get all events, including spaces?

like image 481
captncraig Avatar asked Nov 01 '11 19:11

captncraig


3 Answers

I found some sort of explanation in this WPF forum question:

Because some IMEs will treat whitespace keystroke as part of the text composition process, that's why it eats up by Avalon to report correct composited text through TextInput event.

And some more info from the MSDN documentation of the TextInput event:

... 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.

BTW, Here are two related questions:

  • How can I prevent input controls from stealing the space character from the TextCompositionManager?
  • Help with the WPF TextCompositionManager events
like image 138
sinelaw Avatar answered Oct 19 '22 17:10

sinelaw


One workaround I have found is to hook PreviewKeyDown instead of PreviewTextInput. Unfortunately, that approach requires a lot more runaround to get a concrete char for what button they pressed. The most reliable way I found was in this question. It feels quite cumbersome for what I feel should be rather simple. Anyone have a better way of doing this?

like image 12
captncraig Avatar answered Oct 19 '22 18:10

captncraig


Specifically to reject spaces, not necessarilty other chars for the reasons given in other answers, attach to the textbox the following event handler:

private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
    // Prohibit space
    if (e.Key == Key.Space)
        e.Handled = true;
}

You might still need code to handle PreviewTextInput. I'm just coming across this issue toward writing a numeric-only textbox, the answer is trickier than I expected - I'm handling not only these two events but also the paste event.

I know this does not answer your exact question but I'm hoping it might help other readers.

like image 4
PeteH Avatar answered Oct 19 '22 17:10

PeteH