如何复制 WPF 绑定类型转换错误行为
How to duplicate WPF binding type conversion error behavior
考虑以下因素:
C#:
public class MyVM {
public double DValue { get; set; }
}
XAML:
<TextBox Text={Binding DValue, UpdateSourceTrigger=PropertyChanged} />
用户在框中键入“asdf”。这无法转换为 double
,因此您会在文本框上看到错误模板——它周围有一个红色边框。
在按键时验证的数字文本输入的经典问题是,如果用户键入“-”,则这不是有效的数值。如果用户将值补全为“-1”,那很好,但文本框已经合适了。
一种解决方法是为 ViewModel 提供一个 StringDValue
属性,该属性将“-”和“”视为 0,保持 DValue
属性正确更新,等等。你可以做到这一点。值转换器是有问题的,因为事情是双向的:用户键入“-”,0 返回到 ViewModel 属性,OnPropertyChanged
被触发,0 返回,文本框中出现零。我想这也是可以解决的,但这不是我在这里选择的路径。
所以问题来了:
问题是当用户键入“asdf”时会发生什么。 StringDValue
如何告诉 Binding
该值是无效输入?您是否可以抛出一些异常,绑定将捕获并将其视为非崩溃输入错误?我抛出的每个异常类型都未在绑定中捕获。
这应该是显而易见的。
答案是写一个ValidationRule, as in this answer here:
C#
public class NumericInputTextValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
var s = (value ?? "").ToString().Trim();
double d;
var valid = s == "-" || s == "+" || s == "" || double.TryParse(s, out d);
if (!valid)
{
return new ValidationResult(false, "Not a Number");
}
return new ValidationResult(true, "");
}
}
XAML
<TextBox>
<TextBox.Text>
<Binding Path="StringDValue" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<MyNS:NumericInputTextValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
考虑以下因素:
C#:
public class MyVM {
public double DValue { get; set; }
}
XAML:
<TextBox Text={Binding DValue, UpdateSourceTrigger=PropertyChanged} />
用户在框中键入“asdf”。这无法转换为 double
,因此您会在文本框上看到错误模板——它周围有一个红色边框。
在按键时验证的数字文本输入的经典问题是,如果用户键入“-”,则这不是有效的数值。如果用户将值补全为“-1”,那很好,但文本框已经合适了。
一种解决方法是为 ViewModel 提供一个 StringDValue
属性,该属性将“-”和“”视为 0,保持 DValue
属性正确更新,等等。你可以做到这一点。值转换器是有问题的,因为事情是双向的:用户键入“-”,0 返回到 ViewModel 属性,OnPropertyChanged
被触发,0 返回,文本框中出现零。我想这也是可以解决的,但这不是我在这里选择的路径。
所以问题来了:
问题是当用户键入“asdf”时会发生什么。 StringDValue
如何告诉 Binding
该值是无效输入?您是否可以抛出一些异常,绑定将捕获并将其视为非崩溃输入错误?我抛出的每个异常类型都未在绑定中捕获。
这应该是显而易见的。
答案是写一个ValidationRule, as in this answer here:
C#
public class NumericInputTextValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
var s = (value ?? "").ToString().Trim();
double d;
var valid = s == "-" || s == "+" || s == "" || double.TryParse(s, out d);
if (!valid)
{
return new ValidationResult(false, "Not a Number");
}
return new ValidationResult(true, "");
}
}
XAML
<TextBox>
<TextBox.Text>
<Binding Path="StringDValue" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<MyNS:NumericInputTextValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>