我有一个文本框绑定到一个具有Timespan类型属性的类,并编写了一个值转换器来将字符串转换为TimeSpan。
如果在文本框中输入非数字,我希望显示自定义错误消息(而不是默认的“输入字符串格式错误”)。
转换器代码为:
public object ConvertBack(
object value,
Type targetType,
object parameter,
CultureInfo culture)
{
try
{
int minutes = System.Convert.ToInt32(value);
return new TimeSpan(0, minutes, 0);
}
catch
{
throw new FormatException("Please enter a number");
}
}
我在XAML绑定中设置了'ValidatesOnExceptions = True'。
但是,我遇到了以下MSDN文章,该文章解释了上述原因无效的原因:
“数据绑定引擎不会捕获由用户提供的转换器抛出的异常.Rinit方法抛出的任何异常,或者Convert方法调用的方法抛出的任何未捕获的异常都被视为运行时错误“
我已经读过'ValidatesOnExceptions会捕获TypeConverters中的异常,所以我的具体问题是:
答案 0 :(得分:10)
我会使用ValidationRule
,这样转换器可以确保转换有效,因为只有在验证成功时才会调用它,并且您可以使用附加的属性Validation.Errors
包含ValidationRule
创建的错误,如果输入不符合您的要求。
e.g。 (注意工具提示绑定)
<TextBox>
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Background" Value="Pink"/>
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
<TextBox.Text>
<Binding Path="Uri">
<Binding.ValidationRules>
<vr:UriValidationRule />
</Binding.ValidationRules>
<Binding.Converter>
<vc:UriToStringConverter />
</Binding.Converter>
</Binding>
</TextBox.Text>
</TextBox>
答案 1 :(得分:7)
我使用验证和转换器接受null
和数字
XAML:
<TextBox x:Name="HeightTextBox" Validation.Error="Validation_Error">
<TextBox.Text>
<Binding Path="Height"
UpdateSourceTrigger="PropertyChanged"
ValidatesOnDataErrors="True"
NotifyOnValidationError="True"
Converter="{StaticResource NullableValueConverter}">
<Binding.ValidationRules>
<v:NumericFieldValidation />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
代码背后:
private void Validation_Error(object sender, ValidationErrorEventArgs e)
{
if (e.Action == ValidationErrorEventAction.Added)
_noOfErrorsOnScreen++;
else
_noOfErrorsOnScreen--;
}
private void Confirm_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = _noOfErrorsOnScreen == 0;
e.Handled = true;
}
ValidationRule:
public class NumericFieldValidation : ValidationRule
{
private const string InvalidInput = "Please enter valid number!";
// Implementing the abstract method in the Validation Rule class
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
float val;
if (!string.IsNullOrEmpty((string)value))
{
// Validates weather Non numeric values are entered as the Age
if (!float.TryParse(value.ToString(), out val))
{
return new ValidationResult(false, InvalidInput);
}
}
return new ValidationResult(true, null);
}
}
转换器:
public class NullableValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (string.IsNullOrEmpty(value.ToString()))
return null;
return value;
}
}
答案 2 :(得分:0)
您不应该从转换器中抛出异常。我将实现IDataErrorInfo并在其上实现错误和字符串。请检查http://www.codegod.biz/WebAppCodeGod/WPF-IDataErrorInfo-and-Databinding-AID416.aspx。 HTH daniell