I'm having this same issue and I can't see why in my case validation is being invoked through reflection. I'm considering one of two solutions.
First I'm thinking to implement a converter to extract the InnerException from the ValidationError.Exception when necessary. Something like this:
[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();
}
}
I'm using the converter on the Tooltip message:
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors).CurrentItem, Converter={StaticResource ErrorContentConverter}}"/>
</Trigger>
Alternatively, I thought to use the UpdateSourceExceptionFilter on the Binding. I've implemented a filter as below. This solution is kind of a pain to use because you have to set the UpdateSourceExceptionFilter property in the code behind.
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);
}
The converter is simple but only changes the message that is shown. The filter is a more complete solution but is unfriendly to work with on each binding. Any comments would be greatly appreciated!
Thanks