Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keypad decimal separator on a Wpf TextBox, how to?

I have a Wpf application with some textbox for decimal input.

I would that when I press "dot" key (.) on numeric keypad of pc keyboard it send the correct decimal separator.

For example, on Italian language the decimal separator is "comma" (,)...Is possible set the "dot" key to send the "comma" character when pressed?

like image 228
Luca Petrini Avatar asked Sep 28 '10 08:09

Luca Petrini


2 Answers

Quick and dirty:

   private void NumericTextBox_KeyDown(object sender, KeyEventArgs e) {
        if (e.Key == Key.Decimal) {
            var txb = sender as TextBox;
            int caretPos=txb.CaretIndex;
            txb.Text = txb.Text.Insert(txb.CaretIndex, System.Globalization.CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator);
            txb.CaretIndex = caretPos + 1;
            e.Handled = true;
        }
    }
like image 195
Jacques Sineriz Avatar answered Nov 10 '22 01:11

Jacques Sineriz


Although you may set the default converter locale in WPF as suggested by Mamta Dalal it is not enough to convert the "decimal" key press to the correct string. This code will display the correct currency symbol and date/time format on data-bound controls

//Will set up correct string formats for data-bound controls,
// but will not replace numpad decimal key press
private void Application_Startup(object sender, StartupEventArgs e)
{
    //Among other settings, this code may be used
    CultureInfo ci = CultureInfo.CurrentUICulture;

    try
    {
        //Override the default culture with something from app settings
        ci = new CultureInfo([insert your preferred settings retrieval method here]);
    }
    catch { }
    Thread.CurrentThread.CurrentCulture = ci;
    Thread.CurrentThread.CurrentUICulture = ci;

    //Here is the important part for databinding default converters
    FrameworkElement.LanguageProperty.OverrideMetadata(
            typeof(FrameworkElement),
            new FrameworkPropertyMetadata(
                XmlLanguage.GetLanguage(ci.IetfLanguageTag)));
    //Other initialization things
}

I found that handling the previewKeyDown event window-wide is a little cleaner than textbox-specific (it would be better if it could be applied application-wide).

public partial class MainWindow : Window
{
    public MainWindow()
    {
        //Among other code
        if (CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator != ".")
        {
            //Handler attach - will not be done if not needed
            PreviewKeyDown += new KeyEventHandler(MainWindow_PreviewKeyDown);
        }
    }

    void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Decimal)
        {
            e.Handled = true;

            if (CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator.Length > 0)
            {
                Keyboard.FocusedElement.RaiseEvent(
                    new TextCompositionEventArgs(
                        InputManager.Current.PrimaryKeyboardDevice,
                        new TextComposition(InputManager.Current,
                            Keyboard.FocusedElement,
                            CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator)
                        ) { RoutedEvent = TextCompositionManager.TextInputEvent});
            }
        }
    }
}

If anybody could come up with a way to set it application-wide...

like image 6
Alex Mazzariol Avatar answered Nov 10 '22 01:11

Alex Mazzariol