Как проверить два свойства, которые зависят друг от друга? - PullRequest
8 голосов
/ 16 октября 2019

У меня есть модель представления с 2 свойствами: A и B, и я хочу проверить это A < B.

Ниже представлена ​​моя упрощенная реализация, в которой я использую пользовательское правило проверки. Поскольку каждое свойство проверяется независимо, это приводит к неприятной проблеме: если введенное значение A недопустимо, оно остается таким даже после изменения B, поскольку проверка B ничего не знает о A.

Это можно увидеть на этой демонстрации:

A недопустимо после ввода 11, это правильно, так как 11 > 2. Изменение B на 22 не переоценивает A, мне нужно отредактировать A, чтобы пройти проверку.

Что я хочу? Я хочу, чтобы после включения 22 в B красная граница (ошибка проверки) исчезла, и A = 11, B = 22 были бы исходными значениями в модели представления.

Как я могу в B проверке каким-либо образом заставить A проверка после нового B значение синхронизируется с источником?


Просмотр модели:

public class ViewModel : INotifyPropertyChanged
{
    int _a;
    public int A
    {
        get => _a;
        set
        {
            _a = value;
            OnPropertyChanged();
        }
    }

    int _b;
    public int B
    {
        get => _b;
        set
        {
            _b = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public virtual void OnPropertyChanged([CallerMemberName] string property = "") =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}

Просмотр:

<StackPanel>
    <TextBox Margin="10" Text="{local:MyBinding A}" />
    <TextBox Margin="10" Text="{local:MyBinding B}" />
</StackPanel>

Просмотр кода:

public MainWindow()
{
    InitializeComponent();
    DataContext = new ViewModel { A = 1, B = 2 };
}

Связывание:

public class MyBinding : Binding
{
    public MyBinding(string path) : base(path)
    {
        UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
        ValidationRules.Add(new MyValidationRule());
    }
}

Правило проверки:

public class MyValidationRule : ValidationRule
{
    public MyValidationRule() : base(ValidationStep.ConvertedProposedValue, false) { }

    public override ValidationResult Validate(object value, CultureInfo cultureInfo) => ValidationResult.ValidResult; // not used

    public override ValidationResult Validate(object value, CultureInfo cultureInfo, BindingExpressionBase owner)
    {
        var binding = owner as BindingExpression;
        var vm = binding?.DataItem as ViewModel;
        switch (binding.ResolvedSourcePropertyName)
        {
            case nameof(vm.A):
                if ((int)value >= vm.B)
                    return new ValidationResult(false, "A should be smaller than B");
                break;
            case nameof(vm.B):
                if ((int)value <= vm.A)
                    return new ValidationResult(false, "B should be bigger than A");
                break;
        }
        return base.Validate(value, cultureInfo, owner);
    }
}

1 Ответ

6 голосов
/ 16 октября 2019

ValidationRules не поддерживает аннулирование свойства при установке другого свойства.

Что вам нужно сделать, это реализовать INotifyDataErrorInfo в модели представления и поднять ErrorsChangedсобытие, когда вы хотите обновить статус проверки свойства.

В этой статье TechNet имеется .

пример.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...