Проверка нескольких связанных значений TextBox с привязкой к данным в WPF - PullRequest
2 голосов
/ 15 января 2010

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

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

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

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

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

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

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

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

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}" />

C #:

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));
    }
}

1 Ответ

1 голос
/ 15 января 2010

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

 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

...