Проверка данных WPF из функции установки свойств - PullRequest
2 голосов
/ 02 августа 2010

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

<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, так как данные не должны быть установлены на объекте, если он недопустим, и из-за взаимозависимости свойства с другими свойствами объекта эту проверку невозможно сделать через конвертеры или обычные правила проверки ...

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

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

1 Ответ

2 голосов
/ 04 августа 2010

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

Я изменил привязку подсказки так:

<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
    }
...