问题描述
在我的 WPF 应用程序中,我有一个文本框,用户可以在其中输入百分比(作为整数,介于 1 和 100 之间).Text 属性数据绑定到 ViewModel 中的一个属性,在那里我将值强制在 setter 中的给定范围内.
In my WPF application I have a TextBox where the user can enter a percentage (as int, between 1 and 100). The Text property is databound to a property in a ViewModel, where I coerce the value to be in the given range in the setter.
但是,在 .NET 3.5 中,数据在被强制后无法在 UI 中正确显示.在 MSDN 上的这篇文章中,WPF 博士指出您必须手动更新绑定,以便显示正确的绑定.因此,我有一个调用 UpdateTarget()
的 TextChanged
处理程序(在视图中).在代码中:
However, in .NET 3.5, the data is not shown properly in the UI after being coerced. In this post on MSDN, Dr. WPF states that you have to manually update the binding so the correct will be shown. Therefore, I have a TextChanged
handler (in the View) which calls UpdateTarget()
. In code:
查看 XAML:
<TextBox Text="{Binding Percentage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static sys:String.Empty}}"
TextChanged="TextBox_TextChanged"/>
查看代码隐藏:
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
// Removed safe casts and null checks
((TextBox)sender).GetBindingExpression(TextBox.TextProperty).UpdateTarget();
}
视图模型:
private int? percentage;
public int? Percentage
{
get
{
return this.percentage;
}
set
{
if (this.Percentage == value)
{
return;
}
// Unset = 1
this.percentage = value ?? 1;
// Coerce to be between 1 and 100.
// Using the TextBox, a user may attempt setting a larger or smaller value.
if (this.Percentage < 1)
{
this.percentage = 1;
}
else if (this.Percentage > 100)
{
this.percentage = 100;
}
this.NotifyPropertyChanged("Percentage");
}
}
不幸的是,此代码在 .NET 4.0 中中断(相同的代码,只是将 TargetFramework 更改为 4.0).具体来说,在我第一次强制该值后,只要我继续输入整数值(因为我绑定到一个 int),TextBox 就会忽略任何进一步的强制值.
Unfortunately, this code breaks in .NET 4.0 (same code, simply changed TargetFramework to 4.0). Specifically, after I coerced the value for the first time, the TextBox ignores any further coerced values as long as I continue to enter integer values (since I am binding to an int).
因此,如果我输入123",在 3 之后我会看到值100".现在,如果我输入4",则 ViewModel 中的 setter 将获得值1004",它将其强制为 100.然后触发 TextChanged 事件(并且发件人的 TextBox.Text 为100"!),但 TextBox 显示"1004".如果我然后输入5",setter 会得到值10045",等等.
So if I enter "123", after the 3 I see the value "100". Now if I enter "4", the setter in the ViewModel gets the value "1004", which it coerces to 100. The TextChanged event then fires (and the sender's TextBox.Text is "100"!), but the TextBox shows "1004". If I then enter "5", the setter gets the value "10045", etc.
如果我然后输入a",TextBox 会突然显示正确的值,即100".如果我继续输入数字直到 int 溢出,也会发生同样的情况.
If I then enter an "a", suddenly the TextBox shows the correct value, i.e. "100". The same occurs if I continue to enter numbers until the int overflows.
我该如何解决这个问题?
How can I fix this?
推荐答案
尝试在 xaml 中使用 Explicit 而不是 PropertyChanged:
Try using in xaml Explicit instead of PropertyChanged:
<TextBox Text="{Binding Percentage, Mode=TwoWay, UpdateSourceTrigger=Explicit, TargetNullValue={x:Static System:String.Empty}}"
TextChanged="TextBox_TextChanged" />
并在 UpdateSource 而不是 UpdateTarget 后面的代码中
and in code behind UpdateSource instead of UpdateTarget
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
// Removed safe casts and null checks
((TextBox)sender).GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
测试了它,它的工作原理.顺便说一句,这个问题可能会在 .NET 的更高版本中得到解决.
Tested it and it works.Btw this problem will probably be resolved in a later version of .NET.
这篇关于强制 WPF 文本框不再在 .NET 4.0 中工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!