1

我有一个绑定到 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 背景会以深红色突出显示,但工具提示文本包含“调用目标已引发异常”。而不是我在异常构造函数中写的消息。

你有什么建议吗?

提前谢谢你,马可

4

3 回答 3

2

这是因为验证代码是通过反射调用的。任何捕获的异常都将包含在TargetInvocationException实例中。原始异常将存储为此异常的InnerException


如果绑定到ValidationError.Exception属性而不是ValidationError.ErrorContext会发生什么?

于 2009-01-22T13:56:11.380 回答
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();
    }
}

我在工具提示消息上使用转换器:

<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);
}

转换器很简单,但只会更改显示的消息。过滤器是一个更完整的解决方案,但对每个绑定都不友好。任何意见将不胜感激!

谢谢

于 2009-06-23T10:59:41.460 回答
0

Path=(Validation.Errors)[0].Exception.InnerException.Message}

于 2009-03-10T16:10:31.883 回答