Я начинаю с использования ValidationRules в своем приложении WPF, но довольно запутан.
У меня есть следующее простое правило:
class RequiredRule : ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
if (String.IsNullOrWhiteSpace(value as string))
{
return new ValidationResult(false, "Must not be empty");
}
else
{
return new ValidationResult(true, null);
}
}
}
Используется в XAML следующим образом:
<TextBox>
<TextBox.Text>
<Binding Path="Identity.Name">
<Binding.ValidationRules>
<validation:RequiredRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
В основном это работает, как я ожидал. Я был удивлен, увидев, что мое исходное свойство (Identity.Name
) не было установлено; У меня есть функция отмены, которая никогда не видит изменения, и нет способа вернуть значение, отличное от повторного ввода (не хорошо).
Microsoft Обзор привязки данных описывает процесс проверки в нижней части, что очень хорошо объясняет это поведение. Исходя из этого, я хочу, чтобы мой ValidationStep
был установлен в UpdatedValue
.
<validation:RequiredRule ValidationStep="UpdatedValue"/>
Это то, что для меня странно. Вместо того, чтобы вызывать Validate() с значением объекта, являющимся значением свойства, которое было установлено (т.е. Строка), я получаю a System.Windows.Data.BindingExpression
! Я не вижу ничего в документации Microsoft, которая описывает это поведение.
В отладчике я могу увидеть исходный объект (DataContext
TextBox
), перейдите по пути к свойству и убедитесь, что значение установлено. Тем не менее, я не вижу никакого хорошего способа добраться до правильной собственности в правиле проверки.
Примечание: с ValidationStep
как ConvertedProposedValue
, я получаю введенную строку (у меня нет используемого конвертера), но она также блокирует обновление исходного кода, когда проверка не выполняется, как и ожидалось. С CommittedValue
вместо строки вызывается BindingExpression
.
Здесь есть несколько вопросов:
-
Почему я получаю несогласованный тип аргумента, который передается в Validate() на основе параметра ValidationStep?
-
Как я могу получить фактическое значение из BindingExpression?
-
Альтернативно, есть ли хороший способ разрешить пользователю вернуть TextBox в предыдущее (действительное) состояние? (Как я уже упоминал, моя собственная функция отмены никогда не видит изменения.)