我今天在WPF中测试数据绑定的细微差别,我遇到了一个奇怪的问题。
在我看来,我有
<TextBox Text="{Binding MyInt, UpdateSourceTrigger=LostFocus, StringFormat='{}{##.##}'}"/>
<Label Content="{Binding MyStr2}"/>
在我的ViewModel中,我有
private decimal myInt;
public decimal MyInt
{
get { return myInt; }
set
{
if (value == myInt) { return; }
myInt = value;
OnPropertyChange();
OnPropertyChange("MyStr2");
}
}
public string MyStr2
{
get
{
return myInt.ToString("N2", CultureInfo.CreateSpecificCulture("en-IN"));
}
}
我想从文本框中获取数据,并将其正确格式化并将其显示在标签中。简单易行。
现在,我只能在文本框中输入十进制数据,否则边框会变为红色,表示输入错误。
红色边框显示数据输入错误。但是,该标签仍然反映了较旧的数据。如果输入错误,我希望标签回落到0.00。有没有办法做到这一点?
我试图找到一种人为的方法来做到这一点,并且它以一种极其笨拙的方式运作。
private string myInt;
private decimal myIntActual;
public string MyInt
{
get
{
return myInt;
}
set
{
if (value == myInt) { return; }
Decimal.TryParse(value.ToString(), out myIntActual);
myInt = myIntActual.ToString();
Decimal.TryParse(myInt, out myIntActual);
OnPropertyChange();
OnPropertyChange("MyStr2");
}
}
public string MyStr2
{
get
{
return myIntActual.ToString("N2", CultureInfo.CreateSpecificCulture("en-IN"));
}
}
这样做是,它将输入作为字符串,尝试将其解析为十进制,如果它不能,它将返回零。但是我已经牺牲了这段代码的输入验证,更不用说代码看起来很难看。
据我所知,绑定失败时WPF具有回退值机制。输入错误时是否有任何回退值机制?
编辑:
还有一件事。输入垃圾数据后,下次输入有效数据时,该值会以某种方式到达视图模型,但文本框变为空白。这是一个可以重现的问题。
截图A:
这是按预期工作的。
然后输入垃圾数据。请注意,由于UpdateSourceTrigger
为LostFocus
,因此在焦点丢失之前不会出现错误。
然后我输入有效数据,然后......
失去焦点后,文本框会消失。请注意,标签已正确更新。我设置断点以查看绑定属性是否更新,但是文本框变为空白。那是为什么?答案 0 :(得分:1)
这是触发器的想法。我测试了这个,它对我有用。它不会对您的viewmodel或后面的代码进行任何更改。
<TextBox
x:Name="MyIntTextBox"
Text="{Binding MyInt, UpdateSourceTrigger=LostFocus, StringFormat='{}{##.##}'}"
/>
<Label Content="{Binding MyStr2}">
<Label.Style>
<Style TargetType="Label" BasedOn="{StaticResource {x:Type Label}}">
<Style.Triggers>
<!--
parens on (Validation.HasError) are important: It's an attached
so its name has a dot in it. The parens tell the binding that.
-->
<DataTrigger
Binding="{Binding (Validation.HasError), ElementName=MyIntTextBox}"
Value="True">
<Setter
Property="Visibility"
Value="Hidden"
/>
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
对于消隐行为,我看到当我在MyInt框中键入无效字符串时,选项卡输出,重新标签,键入有效值,然后选项卡退出。只有在我选中有效值时,才会发生这种情况,此时我选中的上一个值无效。我认为这正是你所描述的(错误)行为。
我没有解释。我不喜欢在框架上大肆宣传“bug”,但我认为这是一个错误。该控件未显示其绑定的viewmodel属性值,并且该值未更改。我在MyInt setter中放了一个断点,它只用一个新的有效值击中断点一次(除了据我所知,没有显示为空字符串的整数值)。
如果谷歌没有提出任何解决方法,我会问这个问题。我试过“wpf textbox invalid tab out empty”并没有得到任何结果。