4

I have a textbox bound to a decimal value (property) and when I type the "3." it does not allow me to enter as it parses it back to 3 and hence I lose the ".". I tried the solutions like Delay/LostFocus etc but that did not work for me, from WPF validation rule preventing decimal entry in textbox?.

I have now written a IValueConverter class and I am obviously not doing it correctly. Here is the code:

[ValueConversion(typeof(decimal), typeof(string))]
public class DecimalToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        //return Decimal.Parse(value.ToString());
        if (value == null) return Decimal.Zero;
        if (!(value is string)) return value;
        string s = (string)value;
        int dotCount = s.Count(f => f == '.');
        Decimal d;
        bool parseValid = Decimal.TryParse(s, out d);
        System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex("^[-+]?([0-9]*?[.])?[0-9]*$");
        bool b = regex.IsMatch(s);
        if (dotCount == 1 && b)
        {
            return s;
        }
        return d;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value != null ? value.ToString() : "";
    }
}

XAML

<TextBox x:Name="ValueTextBox" Grid.Column="0" Grid.RowSpan="2" VerticalContentAlignment="Center" Text ="{Binding Value, Converter={StaticResource DecimalToStringConverter}}" PreviewTextInput="ValueTextBox_OnPreviewTextInput"  TextWrapping="Wrap" MouseWheel="ValueTextBox_MouseWheel" PreviewKeyDown="ValueTextBox_PreviewKeyDown" PreviewKeyUp="ValueTextBox_PreviewKeyUp" TextChanged="ValueTextBox_TextChanged" BorderThickness="1,1,0,1"/>

Please advise how I can correct this... Thanks

Community
  • 1
  • 1
ababeel
  • 435
  • 1
  • 8
  • 25
  • Similar issue has an answer [here](https://stackoverflow.com/questions/16914224/wpf-textbox-to-enter-decimal-values/51087700#51087700) – Jnr Dec 05 '18 at 16:34

3 Answers3

2

It's so annoying. You can't press "." but if you move back a character it lets you. It's because "21." is not a valid decimal.

For me I eventually gave up and made the field a string. There must be a better way but it got me past the issue for my use-case. You then also need to check to ensure it's a number etc, but at least the user experience is what they expect.

Kelly
  • 6,992
  • 12
  • 59
  • 76
0

Try to handle the PreviewTextInput event (only) like this:

<TextBox x:Name="ValueTextBox" Grid.Column="0" Grid.RowSpan="2" VerticalContentAlignment="Center"
    Text ="{Binding Value}" PreviewTextInput="ValueTextBox_PreviewTextInput" />

private void ValueTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    decimal value;
    e.Handled = string.IsNullOrEmpty(e.Text) || !decimal.TryParse($"{ValueTextBox.Text}{e.Text}",
        System.Globalization.NumberStyles.Any,
        System.Globalization.CultureInfo.InvariantCulture, out value);
}
mm8
  • 163,881
  • 10
  • 57
  • 88
0

Try this

This will allow only decimals to be entered into the textbox and nothing else.

The viewmodel looks like this:

private string _decimalVal = "0";
public string decimalVal
{
    get { return _decimalVal.ToString(); }
    set
        {
            if (string.IsNullOrEmpty(value) || value == "-")
                SetProperty(ref _decimalVal, value);
            else if (Decimal.TryParse(value, out decimal newVal))
            {
                if (newVal == 0)
                    value = "0";

                SetProperty(ref _decimalVal, value = (value.Contains(".")) ? Convert.ToDecimal(value).ToString("0.00") : value);
            }
        }
}

The XAML usage looks like this:

<TextBox Text="{Binding decimalVal,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
ian korkie
  • 53
  • 1
  • 8