3

I am using WPF/MVVM. I am binding a textbox.Text to a nullable double in view model. UpdateSourceTrigger = PropertyChanged and not Lostfocus. Hence the double property will be updated when each digit is entered using Double.Parse(textbox.Text) inside the converter I am using. I am using PropertyChanged and converter here since I need to do some other validation checks.

My issue is I need to enter "1.69". When I enter "1", it is added as "1" to the property. Next I enter ".", but it is not added as "1." since double.parse saves the number as "1"

So I can't add decimal numbers. Please help. Thanks in advance.

ViVi
  • 4,339
  • 8
  • 29
  • 52
  • I think the converter in the answer on this post might be what you need http://stackoverflow.com/questions/24230085/an-issue-when-textbox-is-binding-to-double-and-enter-negative-number-that-little. It looks like it handles the "." – Tim Ashton Apr 13 '16 at 10:49

3 Answers3

5

You should be fine, if you use StringFormat=\{0:n\}. For example:

<TextBox Text="{Binding FooValue, UpdateSourceTrigger=PropertyChanged, 
                                               StringFormat=\{0:n\}}"/>

or just use a converter. For example:

<Window.Resources>        
   <helper:DoubleConverter x:Key="DoubleConverter" />
</Window.Resources>
...The code omitted for the brevity
<TextBox Text="{Binding Amount, UpdateSourceTrigger=PropertyChanged,       
                        Converter={StaticResource DoubleConverter}}"/>

and DoubleConverter:

public class DoubleConverter : 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)
    {
       // return an invalid value in case of the value ends with a point
       return value.ToString().EndsWith(".") ? "." : value;
    }
}
StepUp
  • 36,391
  • 15
  • 88
  • 148
  • 1
    I learnt that the actual cause behind this is that in TwoWay data binding, it's running a ToString() behind the curtains so no converter will be needed, _but_ that this leads to the aforementioned issue with decimals. So explicitly using a converter seems like the least hacky way and I'm going to go with that. Thanks for that code. Only change I'd do would be to replace "." with `NumberFormatInfo.NumberDecimalSeparator`. For example, here in Sweden the decimal separator is ",". – Jonas Aug 30 '23 at 09:29
1

You could append a 0 before you convert, if the entered string ends with a ..

Kim Homann
  • 3,042
  • 1
  • 17
  • 20
  • So you're saying "1." should be added as "10"? – ViVi Apr 13 '16 at 10:44
  • No. If there is "1." in the TextBox, then append a "0" in order to alter it to "1.0". Then you can convert it to double and store it in your ViewModel. But make sure to not call PropertyChanged, bc otherwise it will also be changed in the view while the user is still typing. – Kim Homann Apr 13 '16 at 13:56
  • For that I need to check every time whether the string ends with a "." and keep appending. Will check anyways. Thank you. – ViVi Apr 13 '16 at 14:04
1

I just did a test app using the converter in my comment from this post: An issue when TextBox is binding to double and enter negative number that little than -1 and it works well for me.

My ViewModel:

class MainWindowViewModel
{

    private double? myDouble;
    public double? MyDouble
    {
        get { return myDouble; }
        set
        {
            myDouble = value;
        }
    }
}

My test Main window:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        >
    <Window.Resources>
        <local:DecimalConverter x:Key="converter" />
    </Window.Resources>

    <Grid>
        <TextBox 
            x:Name="textBox" 
            HorizontalAlignment="Left" 
            Text="{Binding MyDouble, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged, Converter={StaticResource converter}}"
            Height="23" 
            Margin="10,185,0,0" 
            TextWrapping="Wrap" 
            VerticalAlignment="Top" 
            Width="120"/>

        <TextBox 
            x:Name="textBox1" 
            HorizontalAlignment="Left" 
            Text="{Binding MyDouble}"
            Height="23" 
            Margin="10,248,0,0" 
            TextWrapping="Wrap" 
            VerticalAlignment="Top" 
            Width="120"/>

    </Grid>
</Window>

textbox 1 is updated from textbox as expected. Give it a try with Avneesh's converter.

Community
  • 1
  • 1
Tim Ashton
  • 436
  • 6
  • 18