tags:

views:

51

answers:

2

I have a TextBox which I'm using to handle numbers. I therefore only accept [0-9.,]. However, "." is the only valid decimal separator. I therefore only want this in my text, but I want to accept "," too, and swap it with a "." such that the displayed character is a valid one.

So - how do I swap an input character? I'm assuming I can fetch this and swap it in some input event? Or do I have to replace it after it has been inserted into the TextBox?

I tried swapping it in the OnPreviewKeyDown and OnPreviewTextInput events, but the properties holding the input characters are read only. I'd like to do something like this:

protected override void OnPreviewKeyDown(System.Windows.Input.KeyEventArgs e)
{
    if (e.Key == Key.OemComma)
    {
        e.Key = Key.OemPeriod; 
    }
    base.OnPreviewKeyDown(e);
}
+2  A: 

You can use TextChanged event and replace Text property each time.

private void textBox_TextChanged(object sender, TextChangedEventArgs e)
{
    TextBox box = (TextBox)sender;
    box.Text = box.Text.Replace(",", ".");
}

If you using Binding you can make a converter that replace the text when it converts back.

<TextBox Name="textBox" Text="{Binding Path=number, Converter=DecimalConverter}"  />

and

public class DecimalConverter : IValueConverter
{
    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        return value;
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        string strValue = (string)value;
        return strValue.Replace(",",".");
    }
}
Zied
Thx. Sounds like a reasonable solution if I need to do it after the text is inserted. Awaiting before I accept the answer to see if someone has any info on whether I can control the actual input characters.
stiank81
+1  A: 

You just need to handle the PreviewKeyDown to stop it from being applied to the text and then just insert your own character. You can also use this for filtering the non-numeric input:

protected override void OnPreviewKeyDown(KeyEventArgs e)
{
    switch (e.Key)
    {
        case Key.D0:
        case Key.D1:
        case Key.D2:
        case Key.D3:
        case Key.D4:
        case Key.D5:
        case Key.D6:
        case Key.D7:
        case Key.D8:
        case Key.D9:
        case Key.OemPeriod:
            base.OnPreviewKeyDown(e);
            break;
        case Key.OemComma:
            e.Handled = true;
            int caretIndex = CaretIndex;
            Text = Text.Insert(caretIndex, ".");
            CaretIndex = caretIndex + 1;
            break;
        default:
            e.Handled = true;
            break;
    }
}
John Bowen
This should help me handle all in one place, so I believe this will be helpful. Thx!
stiank81