聚沙成塔

WPF中TextBox在.NET 4.5无法输入浮点数

最近发现一个很奇怪的现象,TextBox中的Text绑定double型数据,触发条件UpdateSourceTrigger=PropertyChanged时,在.net4.5框架下无法输入小数点,而在.net 4.0之前的框架不存在这个问题。为了描述地更清晰,下面做一个简单的模型来说明

现象描述


前台主要代码

<Grid>
    <TextBox Text="{Binding Score,UpdateSourceTrigger=Default}"/>
</Grid>

后台主要代码

using System.ComponentModel;

public partial class Window1 : Window
{
    Student stu = new Student();
    public Window1()
    {
        InitializeComponent();
        this.DataContext = stu;
    }
}

class Student : INotifyPropertyChanged
{
    private double score;
    public event PropertyChangedEventHandler PropertyChanged;
    protected void InvokePropertyChanged(string property)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(property));
            }
        }

    /// <summary>
    /// 姓名
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// 得分
    /// </summary>
    public double Score
    {
        get { return score; }
        set
        {
            if (score != value)
            {
                score = value;
                InvokePropertyChanged("Score");
            }
        }
    }
}

这是一个很简单的Demo,相信熟悉WPF Binding的人都能看明白。下面是不同条件下的测试结果

.NET框架 UpdateSourceTrigger 结果
.NET 4.0及以下版本 Default 能输入小数
.NET 4.0及以下版本 PropertyChanged 能输入小数
.NET 4.5及以上版本 Default 能输入小数
.NET 4.5及以上版本 PropertyChanged 不能输入小数


至此,这个现象已经描述清楚了,下面介绍原因和解决方法

产生原因


转换器的问题

解决方法


修改Xmal中的StringFormat

<Grid>
    <TextBox Text="{Binding Score,UpdateSourceTrigger=PropertyChanged,
        StringFormat={}{0}}"/>
</Grid>

如果不想在每一条TextBox后都加StringFormat={}{0}这条代码,可以在App.cs的入口函数中加入一行代码即可

class App
{
    [STAThread]
    public static void Main(params string[] args)
    {
        System.Windows.FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty = false;
        Application app = new Application();
        app.Run(new Window1());
    }
}

补充说明


有的博客介绍如下方法

<Grid>
    <TextBox Text="{Binding Score,UpdateSourceTrigger=PropertyChanged,
        StringFormat={}{##.##}}"/>
</Grid>

<Grid>
    <TextBox Text="{Binding Score,UpdateSourceTrigger=PropertyChanged,
        StringFormat={}{0:N2}}"/>
</Grid>

这两种方法都不能完美解决该问题,有兴趣的不妨尝试一下。

点赞
  1. 西姆说道:

    刚好遇到这个问题,尝试了你的方法,在双向绑定的时候仍然有问题,最终我还是把UpdateSourceTrigger改为Default了。
    谢谢分享好文,我已转载本文,如果有任何不妥可以联系我撤下。

发表评论

电子邮件地址不会被公开。 必填项已用*标注