Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF: Textbox and Binding to Double not able to type . on it

Tags:

mvvm

wpf

I have a text box like

<TextBox Text="{Binding TransactionDetails.TransactionAmount, Mode=TwoWay, 
UpdateSourceTrigger=PropertyChanged}" Grid.Column="3" Grid.ColumnSpan="2" Grid.Row="5" 
x:Name="TextBoxAmount"/>

And I have taken "TransactionAmount" as Double. Its working well on integer value but when I am typing some Floating point value like 100.456 I am not able to type '.'

like image 228
Sabyasachi Mishra Avatar asked May 19 '15 06:05

Sabyasachi Mishra


4 Answers

The behavior is as expected when your app targets .NET 4.0 or earlier but was changed later on (MSDN). The old behavior can be restored by setting:

System.Windows.FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty = false;

Set this as early as possible (e.g. in the constructor of App.cs), otherwise the framework raises an exception.

Source and detailed explanation: https://www.mobilemotion.eu/?p=1855

like image 88
Jonas Marty Avatar answered Nov 10 '22 12:11

Jonas Marty


You are updating your property every time the value changes. When you type in a ., it is written into your viewmodel and the view is updated.

e.g. if you type in 100. it is rounded to 100, thus you won't see any dot ever.

You have some options to change this behavior:

use a deferred binding:

<TextBox Text="{Binding Path=TransactionDetails.TransactionAmount, 
                        Mode=TwoWay, 
                        UpdateSourceTrigger=PropertyChanged, 
                        Delay=250}" 
         Grid.Column="3" 
         Grid.ColumnSpan="2" 
         Grid.Row="5" 
         x:Name="TextBoxAmount" />

only change the value if it is different from the saved one (I'd recommend this for every binding):

private double _transactionAmount; 
public double TransactionAmount  
{
  get { return _transactionAmount; }    
  set
  { 
    if (_transactionAmount != value)
    {
      _transactionAmount = value; 
      Notify("TransactionAmount"); 
    }
  }

or use some kind of validation, e.g. ValidatesOnExceptions.

like image 44
Herm Avatar answered Nov 10 '22 11:11

Herm


The best solution I got by using StringFormat like

<TextBox Text="{Binding TransactionDetails.TransactionAmount, Mode=TwoWay, 
UpdateSourceTrigger=PropertyChanged,StringFormat=N2}" Grid.Column="3" 
Grid.ColumnSpan="2" Grid.Row="5" x:Name="TextBoxAmount" />

Also we can go for custom string format as per requirements

like image 43
Sabyasachi Mishra Avatar answered Nov 10 '22 10:11

Sabyasachi Mishra


Your Problem is with UpdateSourceTrigger. Instead of using there You can use something like this,

private double amount;
public double Amount
    {
        get
        {
            return amount;
        }
        set
        {
            amount= value;
            PropertyChanged();
            Calculation();
        }
    }

PropertyChanged() You will get this from INotifyPropertyChanged. For more Information click here https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx

like image 1
Dinesh balan Avatar answered Nov 10 '22 10:11

Dinesh balan