代码之家  ›  专栏  ›  技术社区  ›  Drake

validateNextExceptions激发,但不显示异常消息

  •  1
  • Drake  · 技术社区  · 15 年前

    我有一个textbox.textproperty绑定到一个viewModel属性。在绑定中,我已显式设置 验证NextExceptions .

    在资源中,文本框具有此触发器:

    <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"/>
    

    不幸的是,我的实现并不能很好地工作,因为当我遇到异常时,文本框背景会用 深红色的 颜色,但工具提示文本包含 “调用的目标引发了异常。” 而不是我在异常构造函数中编写的消息。

    你有什么建议吗?

    事先谢谢你, 马尔科

    3 回复  |  直到 15 年前
        1
  •  2
  •   Stu Mackellar    15 年前

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


    如果你绑定到 ValidationError.Exception 属性而不是 ValidationError.ErrorContext ?

        2
  •  1
  •   Terrence    15 年前

    我也遇到了同样的问题,我不明白为什么在我的案例中,验证是通过反射调用的。我正在考虑两种解决方案之一。

    首先,我想实现一个转换器,在必要时从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>
    

    或者,我想在绑定上使用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);
    }
    

    转换器很简单,但只更改显示的消息。过滤器是一个更完整的解决方案,但对每个绑定都不友好。任何评论都是 大大地 感谢!

    谢谢

        3
  •  0
  •   KarlZ    15 年前

    路径=(validation.errors)[0].exception.innerexception.message_