Проверка нескольких связанных значений TextBox с привязкой к данным в WPF

2

Я пытаюсь найти элегантный способ проверки двух связанных значений TextBox в WPF.

Свойство Text каждого текстового поля привязано к общедоступному десятичному свойству в моем классе, который реализует привязку INotifyPropertyChanged для TwoWay.

Я хочу проверить два значения таким образом, что: BiggerValue >= SmallerValue >= 0

Мне удалось получить каждое значение для проверки независимо от этих условий с помощью IDataErrorInfo и индексатора строк.

Моя проблема заключается в следующем: пользователь намеревается уменьшить оба значения и начать с BiggerValue, так что теперь он меньше, чем SmallerValue. Проверка на BiggerValue TextBox не выполняется (хотя значение сохраняется). Затем пользователь переходит к SmallerValue и устанавливает его меньше, чем новый BiggerValue. Теперь оба значения действительны снова, но как я могу заставить текстовое поле BiggerValue автоматически отражать, что его (неизменное) значение теперь действительно?

Должен ли я искать обработчик событий, например LostFocus() в текстовых полях, или добавлять что-то вроде этого в средства настройки свойств, чтобы принудительно обновить?

biggerValueTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
smallerValueTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();

Мой полный код приведен ниже. Как-то все это кажется довольно неуклюжим и сложным для этой простой проблемы. Будучи новичком WPF (это второй день), любые комментарии о моем подходе, пусть и радикальные, будут с благодарностью приняты.

XAML:

<TextBox x:Name="biggerValueTextBox"
         Text="{Binding Path=BiggerValue,
                        Mode=TwoWay,
                        ValidatesOnDataErrors=True,
                        ValidatesOnExceptions=True}" />
<TextBox x:Name="smallerValueTextBox"
         Text="{Binding Path=SmallerValue,
                        Mode=TwoWay,
                        ValidatesOnDataErrors=True,
                        ValidatesOnExceptions=True}" />

С#:

public partial class MyClass : UserControl,
    INotifyPropertyChanged, IDataErrorInfo
{
    // properties
    private decimal biggerValue = 100;
    public decimal BiggerValue
    {
        get
        {
            return biggerValue;
        }
        set
        {
            biggerValue = value;
            OnPropertyChanged("BiggerValue");
        }
    }
    private decimal smallerValue = 80;
    public decimal SmallerValue
    {
        get
        {
            return smallerValue;
        }
        set
        {
            smallerValue = value;
            OnPropertyChanged("SmallerValue");
        }
    }

    // error handling
    public string this[string propertyName]
    {
        get
        {
            if (propertyName == "BiggerValue")
            {
                if (BiggerValue < SmallerValue)
                    return "BiggerValue is less than SmallerValue.";
                if (BiggerValue < 0)
                    return "BiggerValue is less than zero.";
            }
            if (propertyName == "SmallerValue")
            {
                if (BiggerValue < SmallerValue)
                    return "BiggerValue is less than SmallerValue.";
                if (SmallerValue < 0)
                    return "SmallerValue is less than zero.";
            }
            return null;
        }
    }
    // WPF doesn't use this property.
    public string Error { get { return null; } }

    // event handler for data binding
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}
Теги:
wpf
data-binding
inotifypropertychanged

1 ответ

1
Лучший ответ

ну, простой хакерский метод должен был бы также изменить свойство свойства для largeValue (это приведет к обновлению проверки для большего значения):

 public decimal SmallerValue
    {
        get
        {
            return smallerValue;
        }
        set
        {
            bool fireForBigger = smallerValue > biggerValue && smallerValue < value;
            smallerValue = value;
            OnPropertyChanged("SmallerValue");
            if (fireForBigger)
            {
                OnPropertyChanged("BiggerValue");
            }
        }
    }

Но более твердое решение заключалось бы в создании пользовательских правил валидации и их настройке самостоятельно: http://msdn.microsoft.com/en-us/library/system.windows.data.binding.validationrules.aspx

  • 0
    Спасибо за это и за быстрый ответ - это хорошее и простое решение. Я также посмотрю на пользовательские правила проверки.
  • 0
    Как может помочь использование пользовательских правил проверки? Похоже, это будет та же проблема, что и с IDataErrorInfo.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню