ValidatesOnExceptions срабатывает, но не показывает сообщение об исключении - PullRequest
1 голос
/ 22 января 2009

У меня есть TextBox.TextProperty, связанный со свойством ViewModel. В привязке я явно установил 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 , но текст всплывающей подсказки содержит "Исключение было выдано целью invocation. " вместо сообщения, которое я написал в конструкторе исключений.

У вас есть предложения?

Заранее спасибо, Marco

Ответы [ 3 ]

2 голосов
/ 22 января 2009

Это потому, что код проверки вызывается через отражение. Все перехваченные исключения будут помещены в экземпляр TargetInvocationException . Исходное исключение будет сохранено как InnerException .

этого исключения.

Что произойдет, если вы свяжетесь со свойством ValidationError.Exception вместо ValidationError.ErrorContext ?

1 голос
/ 23 июня 2009

У меня такая же проблема, и я не понимаю, почему в моем случае проверка вызывается через рефлексию. Я рассматриваю одно из двух решений.

Сначала я собираюсь реализовать конвертер для извлечения InnerException из ValidationError.Exception, когда это необходимо. Примерно так:

[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 для Binding. Я реализовал фильтр, как показано ниже. Это решение довольно неудобно, потому что вы должны установить свойство 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);
}

Преобразователь прост, но изменяет только отображаемое сообщение. Фильтр является более полным решением, но с ним недружелюбно работать с каждой привязкой. Любые комментарии будут очень оценен!

Спасибо

0 голосов
/ 10 марта 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...