我有一个绑定到ViewModel属性的TextBox.TextProperty。在绑定中,我明确将 ValidatesOnExceptions 设置为 True 。
在资源中,TextBox具有以下触发器:
<Trigger Property="Validation.HasError" Value="true">
<Setter
Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
<Setter TargetName="Border" Property="Background" Value="Crimson"/>
不幸的是我的实现并不完美,因为当我有一个例外时,TextBox背景会以 Crimson 颜色突出显示,但工具提示文本包含“Exception已被目标抛出一个调用。“而不是我在异常构造函数中写的消息。
你有什么建议吗?
提前谢谢你, 马可
答案 0 :(得分:2)
这是因为验证代码是通过反射调用的。任何捕获的异常都将包含在TargetInvocationException实例中。原始异常将存储为此异常InnerException。
如果绑定到ValidationError.Exception属性而不是ValidationError.ErrorContext会发生什么?
答案 1 :(得分:1)
我遇到了同样的问题,我无法理解为什么在我的案例中验证是通过反射调用的。我正在考虑两种解决方案中的一种。
首先,我想在必要时实现转换器从ValidationError.Exception中提取InnerException。像这样:
[ValueConversion(typeof(ValidationError), typeof(string))]
public class ErrorContentConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var validationError = (ValidationError)value;
if ((validationError.Exception == null) || (validationError.Exception.InnerException == null))
return validationError.ErrorContent;
else
return validationError.Exception.InnerException.Message;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
我在Tooltip消息上使用转换器:
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors).CurrentItem, Converter={StaticResource ErrorContentConverter}}"/>
</Trigger>
或者,我想在Binding上使用UpdateSourceExceptionFilter。我已经实现了如下过滤器。这个解决方案很难使用,因为你必须在后面的代码中设置UpdateSourceExceptionFilter属性。
object InnerExceptionFilter(object bindingExpression, Exception exception)
{
if (exception.InnerException != null)
{
var be = (System.Windows.Data.BindingExpression)bindingExpression;
var rule = be.ParentBinding.ValidationRules.First(x=>x is ExceptionValidationRule);
return new ValidationError(rule, be, exception.InnerException.Message, exception.InnerException);
}
else
return exception;
}
usage:
public MyConstructor()
{
myTextBox.GetBindingExpression(TextBox.TextProperty).ParentBinding.UpdateSourceExceptionFilter
= new UpdateSourceExceptionFilterCallback(InnerExceptionFilter);
}
转换器很简单,但只更改显示的消息。过滤器是一个更完整的解决方案,但对每个绑定都不友好。任何评论都会非常赞赏!
由于
答案 2 :(得分:0)
路径=(Validation.Errors)[0]} .Exception.InnerException.Message