Проверка данных WPF из функции установки свойств

У меня есть класс, который привязан к элементам графического интерфейса следующим образом:

<TextBox Style="{StaticResource ValidatedTextBox}" 
  Text="{Binding MaxDistance, ValidatesOnExceptions=True}" >
  <TextBox.Style>
    <Style TargetType="TextBox" >
      <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="True">
          <Setter Property="ToolTip">
            <Setter.Value>
              <Binding Path="(Validation.Errors).CurrentItem.ErrorContent"
                RelativeSource="{RelativeSource Self}" />
            </Setter.Value>
          </Setter>
        </Trigger>
      </Style.Triggers>
    </Style>
  </TextBox.Style>
</TextBox>

Установщик для свойства MaxDistance реализован здесь:

public float MaxDistance
{
  get { return m_maxDistance; }
  set
  {
    // Check for valid values
    if (value < MinDistance)
      throw new ArgumentException(
        "Max distance must be greater than min distance");

    m_maxDistance = value;
  }
}

Проблема в том, что когда я ввожу недопустимое значение в TextBox, появляется всплывающая подсказка с сообщением «Исключение было создано целью вызова» вместо «Максимальное расстояние должно быть больше минимального».

Что мне делать, чтобы всплывающая подсказка считывала строку ArgumentException? ПРИМЕЧАНИЕ. Исключения преобразования стандартного типа также должны отображаться правильно (т.е. если я ввожу строку вместо числа с плавающей запятой, стандартное сообщение об ошибке все равно должно появиться).

Я не могу переместить исключения в интерфейс IDataErrorInfo, поскольку данные не должны устанавливаться для объекта, если он недействителен, и из-за взаимозависимости свойства от других свойств объекта эту проверку нельзя выполнить с помощью преобразователей или типовые правила валидации ...

В приведенном выше примере проверка есть и работает, она просто не предоставляет пользователю полезной информации.

Спасибо за помощь


person JoshG    schedule 02.08.2010    source источник


Ответы (1)


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

Я изменил привязку всплывающей подсказки следующим образом:

<Binding Path="(Validation.Errors)[0]"
     RelativeSource="{RelativeSource Self}"
     Converter="{StaticResource ValidationExceptionConverter}"/>

И реализовал преобразователь следующим образом:

    public class ValidationExceptionConverter : IValueConverter
    {
        #region IValueConverter Members

        // From string to 
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            ValidationError error = value as ValidationError;
            if (error == null)
                return null;

            Exception exception = error.Exception;
            if (exception == null)
            {
                return error.ErrorContent;
            }
            else
            {
                // Find the innermost exception
                while (exception.InnerException != null)
                    exception = exception.InnerException;

                // Use it's message as output
                return exception.Message;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
person JoshG    schedule 04.08.2010