触发ValidatesOnExceptions但它不显示异常消息

时间:2009-01-22 13:44:21

标签: wpf validation binding

我有一个绑定到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已被目标抛出一个调用。“而不是我在异常构造函数中写的消息。

你有什么建议吗?

提前谢谢你, 马可

3 个答案:

答案 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