在我们的项目中,我们有一个绑定到double的WPF文本框。有一个转换器允许在convertback中同时使用"."one_answers","作为小数点,在convert方法中,它将双精度设置为n2数字格式。在这里,您可以看到我们转换器的简化版本:
public class DoubleConverter:IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null || value.GetType() != typeof(double))
return null;
else
return ((double)value).ToString("n2");
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return null
else
return Double.Parse(((string)value).Replace('.',','));
}
}
文本框如下所示:
<TextBox Text="{Binding Path=Factor, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="500" Height="50" />
双重属性引发属性更改事件:
public double Factor
{
get { return _factor; }
set
{
_factor = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Factor"));
}
}
这在以前版本的WPF中曾经很好地工作,因为在输入文本时没有调用convert。这种行为显然已经改变了,现在对每个文本条目都调用convert方法,导致在键入内容时对double进行格式化。即使你不使用格式,你也有无法输入小数点的问题。
这可以通过不使用UpdateSourceTrigger=Propertychanged来解决,但我们需要它进行验证。我们使用IDataErrorInterface来实现验证。我知道有一个ValidateWithoutUpdate方法,但这不适用于使用IDataErrorInterface的验证。
因此,我基本需要的是ConvertBack(以及验证)在PropertyChanged上发生,而Convert只在LostFocus上发生
这可能吗?或者我们的问题还有其他解决方案吗?
是的,行为从.Net 3.5更改为.Net 4.0,在.Net 4.0中,即使更新源自目标,它也会将源更新发送回目标。这篇SO文章对此进行了一些解释,并提供了一个解决方案:
为什么绑定设置在.NET 4和.NET 3.5 中表现不同
到目前为止,我发现了以下几种处理方法:
- 让转换器在ConvertBack上保持输入的状态,并在Convert中恢复它(在上面的链接中建议)
- 将后台数据更改为字符串,处理模型中的转换
- 创建一个自定义控件来处理这种数字输入,类似于DateTimePicker的工作方式(它维护数据的字符串和双精度表示;显示字符串,但受双精度约束)