原文地址: http://www.wangyanwei.com/articles/wpf-textbox-cannot-enter-a-float-in-the-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>
这两种方法都不能完美解决该问题,有兴趣的不妨尝试一下。