C# – WPF, PreviewKeyDown event and underscore char

c++wpf

I'm catching key hits with PreviewKeyDown event in my WPF component. I need to distinguish characters being typed: letters vs. numbers vs. underscore vs. anything else.

Letters and numbers work fine (just convert the Key property of the KeyEventArgs object to string and work with character 0 of that string), but this won't work for underscore.

It's ToString value depends on localized keyboard settings (it shows up as "OemMinus" on EN/US keyboard and "OemQuestion" on CZ/QWERTY keyboard).

So how can I RELIABLY find out, if the typed char is underscore in the PreviewKeyDown event?

Thanks for any help

Best Solution

UPDATE:

This is a bit messy, but it might help you after some refactoring. I capture text using the preview event and force sending the Key I want; I ignore all other keys in my preview handler. I did switch from KeyDown to KeyUp to get the preview event to fire first. I use the _clearNext flag to skip/clear the key event.

In XAML

<Window x:Class="EmployeeNavigator.Views.MainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    PreviewTextInput="Window_PreviewTextInput"
    Keyup="Window_KeyUp"
    Height="400" 
    Width="600"
    MinWidth="600">
</Window>

Code-behind detects and processes _

  private bool _clearNext = false;
  private void Window_KeyUp(object sender, KeyEventArgs e)
  {
     if ( _clearNext )
     {
        _clearNext = false;
        e.Handled = true;
     }
     else if (e.Key == Key.OemMinus)
     {
        e.Handled = true;
     }
     else if (e.Key == Key.OemQuestion)
     {
        e.Handled = true;
     }
  }

  private void Window_PreviewTextInput(object sender, TextCompositionEventArgs e)
  {
     if (e.Text.Equals("_"))
     {
        KeyEventArgs args = new KeyEventArgs(Keyboard.PrimaryDevice,
           Keyboard.PrimaryDevice.ActiveSource, 0, Key.OemMinus);
        args.RoutedEvent = Keyboard.KeyUpEvent;
        InputManager.Current.ProcessInput(args);
        e.Handled = true;
        _clearNext = true;
     }
     else if (e.Text.Equals("?"))
     {
        KeyEventArgs args = new KeyEventArgs(Keyboard.PrimaryDevice,
           Keyboard.PrimaryDevice.ActiveSource, 0, Key.OemQuestion);
        args.RoutedEvent = Keyboard.KeyUpEvent;
        InputManager.Current.ProcessInput(args);
        e.Handled = true;
        _clearNext = true;
     }
  }

I'll add there must be a better way.