I have developed a WPF textbox which formats numbers as we keep typing numbers in textbox. This is using interactivity behavior. Now, It works fine with normal regular keyboard. But as we support globalization, textbox should support to Japanese characters(numbers) as well which are full width characters. So to test, when I select Japanese keyboard - Microsoft IME in (windows-controlpanel-region & langauage - keyboard and languages - change keyboards), and enter japanese numbers my interactivity behavior code (hookup) AssociatedObject_PreviewTextInput does not get called until I press 'Enter' Key which creates other issues for me. For regular keyboard, this function gets called as soon I type number.

Code looks as below

private void AssociatedObject_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
     TextBox tb = sender as TextBox;
     // other stuff
}

protected override void OnAttached()
{
     base.OnAttached();
     AssociatedObject.PreviewTextInput += AssociatedObject_PreviewTextInput;
     /// other stuff
}

Any help is appreciated. Thank you.

1

There are 1 answers

3
kennyzx On

You can listen to PreviewKeyDown/PreviewKeyUp to get notified for each stroke.

Any you may want to take over input by manipulate TextBox's Text property directly, instead of waiting for the final input after pressing Enter.

AssociatedObject.PreviewKeyDown += AssociatedObject_PreviewKeyDown;

Here I just handle the case where user is using IME to input digits (0~9). I insert the digit at the caret. And by setting e.Handled = true;, IME will not input anything to the TextBox.

private void AssociatedObject_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.ImeProcessedKey == Key.D0 ||
        e.ImeProcessedKey == Key.D1 ||
        e.ImeProcessedKey == Key.D2 ||
        e.ImeProcessedKey == Key.D3 ||
        e.ImeProcessedKey == Key.D4 ||
        e.ImeProcessedKey == Key.D5 ||
        e.ImeProcessedKey == Key.D6 ||
        e.ImeProcessedKey == Key.D7 ||
        e.ImeProcessedKey == Key.D8 ||
        e.ImeProcessedKey == Key.D9  )
    {
        TextBox tb = sender as TextBox;
        int index = tb.CaretIndex;

        //stripe the leading 'D'
        string d = e.ImeProcessedKey.ToString().Substring(1);
        tb.Text = tb.Text.Insert(index, d);

        tb.CaretIndex = index + 1; //I need to manually move the caret forward, since caret position was reset to 0.

        e.Handled = true; //important, so IME does not input to the TextBox
    }
}