WPF:Textbox和Binding to Double无法输入。在上面

时间:2015-05-19 06:22:46

标签: wpf mvvm

我有一个像

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

我把“TransactionAmount”作为Double。它在整数值上运行良好,但是当我输入一些浮点值如100.456时,我无法输入'。'

7 个答案:

答案 0 :(得分:8)

每次值更改时,您都在更新属性。当您输入.时,会将其写入您的viewmodel并更新视图。

e.g。如果您输入100.,它会四舍五入为100,因此您不会看到任何点。

您可以选择更改此行为:

使用延迟绑定:

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

仅在与保存的值不同时才更改值 (我建议每个绑定都这样):

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

或使用某种验证,例如ValidatesOnExceptions。

答案 1 :(得分:4)

使用StringFormat之类的

获得的最佳解决方案
<TextBox Text="{Binding TransactionDetails.TransactionAmount, Mode=TwoWay, 
UpdateSourceTrigger=PropertyChanged,StringFormat=N2}" Grid.Column="3" 
Grid.ColumnSpan="2" Grid.Row="5" x:Name="TextBoxAmount" />

我们也可以根据要求使用自定义字符串格式

答案 2 :(得分:1)

您的问题在于UpdateSourceTrigger。 而不是在那里使用你可以使用这样的东西,

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

PropertyChanged()您将从INotifyPropertyChanged获取此信息。欲了解更多信息,请点击此处 https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx

答案 3 :(得分:1)

在绑定到双型源数据时,可以使用此类替换默认转换器。这更方便使用。下面是代码:

public class double2txtConverter : IValueConverter
    {
        string _strCache;
        double _dCache;
        //Convert double to string of textbox.
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (_dCache == (double)value)
                return _strCache;
            else
                return value.ToString();
        }
        //convert string to double;
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            _strCache = (string)value;
            _dCache = double.Parse(_strCache);
            return _dCache;
        }
    }
//below is codebehind usage:
        Binding bd = new Binding(path);
        bd.Converter = new double2txtConverter();
        bd.Source = source;
        bd.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
        txtTarget.SetBinding(TextBox.TextProperty, bd);

答案 4 :(得分:1)

当您的应用面向 .NET 4.0 或更早版本但后来 (MSDN) 进行了更改时,该行为符合预期。可以通过设置恢复旧行为:

System.Windows.FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty = false;

尽早设置(例如在 App.cs 的构造函数中),否则框架会引发异常。

来源和详细解释:https://www.mobilemotion.eu/?p=1855

答案 5 :(得分:0)

我根据上面的Herm的答案给出答案。解释是正确的,但是在控件上使用Delay并不能完全解决问题。如果最终用户键入0.005,则所需的延迟将更大,否则它将重新写入值为0。

相反,请使用字符串属性进行绑定,然后尝试将其解析为double并根据解析输出设置所需的long值。设置值之前,请先进行所有需要的验证

private double _amount;
private string _amountString;
public string Amount
{
    get { return _amountString;}
    set {
            double d=0;
            if(Double.TryParse(value, out d))
            {
                _amountString=value;
                _amount=d;
            }
        }
   }
}

答案 6 :(得分:0)

在绑定属性使用时,UpdateSourceTrigger=LostFocus。一旦文本框失去焦点,它将更新属性。