ValidatesOnExceptions срабатывает, но не отображает сообщение об исключении

У меня есть TextBox.TextProperty, привязанный к свойству ViewModel. В привязке я явно установил ValidatesOnExceptions в Правда.

В ресурсах 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 выделяется цветом малиновый, но текст всплывающей подсказки содержит «Исключение было выброшено целью вызова». вместо сообщения, которое я написал в конструкторе исключения.

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

Заранее спасибо, Марко

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
3 746
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

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


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

Хороший улов, Стю! Если привязка к Path = (Validation.Errors) [0] .Exception, я получаю во всплывающей подсказке все сообщение об исключении. Затем я попытался выполнить привязку к: (Validation.Errors) [0] .Exception.InnerException.Message и наконец получил ожидаемое. Но теперь ... правильно ли ведет себя ValidatesOnExcpetions?

Drake 22.01.2009 17:47

Кажется, что в вашей проверке действительно происходит что-то странное - я думаю, вам нужно понять, почему ваше исключение вообще обертывается. Привязка к внутреннему исключению немного хрупкая, потому что она перестанет работать, если у вас есть какие-либо развернутые исключения.

Stu Mackellar 22.01.2009 18:42

Путь = (Validation.Errors) [0] .Exception.InnerException.Message}

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

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

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

Спасибо

Другие вопросы по теме