WPF: проверка и конвертеры

В конвертере я могу различать по меньшей мере 4 типа поведения относительно обновления значения источника:

  • преобразование в правильное значение (- > источник обновления)
  • return null (- > указать ошибку)
  • сброс исключения и включение правила проверки исключения (- > указать ошибку)
  • return Binding.DoNothing (- > не обновлять источник, но не указывать на ошибку)

С ValidationRule я могу различать только успех (- > источник обновления) и отказ (- > не обновлять источник), но я не могу имитировать поведение, связанное с Binding.DoNothing

Есть ли способ использовать ValidationRule таким образом, который похож на поведение Binding.DoNothing преобразователей?

Ответы

Ответ 1

Идеи конвертеров и ValidationRule довольно разные. Преобразователи берут одно значение и превращают его в другое. 4 случая, которые вы упомянули, достаточно распространены для преобразования: сделайте это; скажем, это нуль; Взрывать; игнорировать. Однако ValidationRules - это да/нет - они действительны или нет. Хотя может иметь смысл иметь опцию "игнорировать", ее нет.

Ближайшим семантически было бы установить IsValid = true в конструкторе, но это не совсем то, что вы хотите.

public override ValidationResult Validate(object value, CultureInfo cultureInfo) 
{
    try
    {
        // try normal setup/validation
    } 
    catch 
    {
        // handle exceptions, return false
    }
    // decide if you want to return false
    // return true (equivalent to nothing/ignore)
    return new ValidationResult(true, null);
}

Последнее, что у меня есть, - это если вам нужны специальные случаи, и попытка try-catch или другая логика взорвутся. Единственное, что я могу придумать, это проверка типа в ValidationRule, что довольно сомнительно, поскольку вы создаете нежелательную зависимость, но обойдете проблемы. т.е.

if (value is SpecialType)
{
    return new ValidationResult(true, null);
}

НТН!

ОБНОВЛЕНО

Или как насчет IgnorableValidationRule?

public class IgnorableValidationRule : ValidationRule
{
    public bool Ignore { get; set; } = false;

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        if (Ignore) return new ValidationResult(true, null);

        return new ValidationResult(false, "Why does everyone ignore me?");
    }
}

<TextBox.Text>
    <Binding Path="Data">
        <Binding.ValidationRules>
            <local:IgnorableValidationRule Ignore="True"/> <!-- na na -->
        </Binding.ValidationRules>
    </Binding>
</TextBox.Text>