我有一个在XAML中定义的
WPF文本框,如下所示:
<Window.Resources> <Style x:Key="textBoxInError" TargetType="{x:Type TextBox}"> <Style.Triggers> <Trigger Property="Validation.HasError" Value="true"> <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self},Path=(Validation.Errors)[0].ErrorContent}"/> </Trigger> </Style.Triggers> </Style> </Window.Resources> <TextBox x:Name="upperLeftCornerLatitudeTextBox" Style="{StaticResource textBoxInError}"> <TextBox.Text> <Binding Path="UpperLeftCornerLatitude" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:LatitudeValidationRule ValidationStep="RawProposedValue"/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox>
如您所见,我的文本框绑定到我的业务对象上的一个名为UpperLeftCornerLatitude的十进制属性,如下所示:
private decimal _upperLeftCornerLongitude; public decimal UpperLeftCornerLatitude { get { return _upperLeftCornerLongitude; } set { if (_upperLeftCornerLongitude == value) { return; } _upperLeftCornerLongitude = value; OnPropertyChanged(new PropertyChangedEventArgs("UpperLeftCornerLatitude")); } }
我的用户将在此文本框中输入纬度值,为了验证该条目,我创建了一个如下所示的验证规则:
public class LatitudeValidationRule : ValidationRule { public override ValidationResult Validate(object value,System.Globalization.CultureInfo cultureInfo) { decimal latitude; if (decimal.TryParse(value.ToString(),out latitude)) { if ((latitude < -90) || (latitude > 90)) { return new ValidationResult(false,"Latitude values must be between -90.0 and 90.0."); } } else { return new ValidationResult(false,"Latitude values must be between -90.0 and 90.0."); } return new ValidationResult(true,null); } }
我的文本框最初是空的,我在验证规则的开头设置了断点.我在文本框中输入1,当我的调试器在验证规则内部时,我可以看到value =“1”.到现在为止还挺好.现在我继续运行并在文本框中输入一个小数点(所以我们现在应该有“1”).同样,调试器在验证规则内部中断,并且如预期的那样,值=“1”.如果我单步执行验证规则代码,我会看到它通过了纬度值检查并返回以下内容:
new ValidationRule(true,null);
但是,只要验证规则返回并且我进入下一行代码,我就会发现自己位于UpperLeftCornerLatitude属性setter的第一行.将鼠标置于价值上会显示它的值为“1”而不是“1”.正如我所料.所以当我继续运行我的代码时,我自然会回到文本框中,盯着值“1”而不是“1”.如果我删除所有断点,效果是我似乎无法在文本框中输入小数点.有没有明显的东西,我在这里失踪,这导致我的二传手最终得到一个值为“1”,即使我已输入“1”.在文本框中?非常感谢!
解决方法
以下是解决此问题的几种方法
A.为绑定指定LostFocus(默认文本框)
<Binding Path="UpperLeftCornerLatitude" Mode="TwoWay" UpdateSourceTrigger="LostFocus"> </Binding
B.指定绑定的延迟,允许您输入一些小数
<Binding Path="UpperLeftCornerLatitude" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" Delay="1000"> </Binding
C.将十进制更改为字符串并自行解析
D.编写ValueConverter以覆盖默认转换过程
class DecimalConverter : IValueConverter { public object Convert(object value,Type targetType,object parameter,CultureInfo culture) { ... } public object ConvertBack(object value,CultureInfo culture) { ... } }