Как пометить ввод текстового поля как недействительный, используя прикрепленное поведение
У меня есть много TextBox на моем xaml, где я реализовал проверку Regex (из
Как определить ограничения TextBox). На мой взгляд, это принимает форму:
<TextBox
h:ColorMaskingTextBoxBehavior.Mask="^(?:\d{5})(?:-\d{4})?$"
Text="{Binding ZipCode}"
Height="21" HorizontalAlignment="Left" Margin="152,207,0,0" VerticalAlignment="Top" Width="96"
/>
Я не хочу ограничивать движение пользователя, поэтому в настоящее время проверка просто меняет цвета текстового поля; красный цвет был обнаружен ошибка.
После того, как все входные данные собраны, пользователь должен нажать "Сохранить", чтобы сохранить окно. Коды регулярных выражений могут быть задействованы, и кажется неправильным копировать их из xaml в модель представления, где выполняется Save.
Как прикрепленное поведение может пометить текстовое поле как недействительное, так что модели представления нужно только проверить флаг недопустимого перед сохранением окна? Моя первая мысль - связать свойство зависимостей Tag с текстовым полем, но мне интересно, есть ли лучший способ?
Любые идеи приветствуются.
ТИА
1 ответ
Я бы перенес всю валидацию в модель представления, вот для чего она нужна. Это не очень хорошая практика MVVM иметь логику приложения в представлении. Представления должны быть взаимозаменяемыми без необходимости перекодирования логики проверки. Затем вы можете изменить внешний вид TextBox, используя триггеры в стиле, который привязывается к свойствам в модели представления вместо использования прикрепленного поведения.
Некоторые люди используют интерфейс IDataErrorInfo.. Я не.
Создайте свойство модели представления, которое определяет, является ли ZipCodeIsValid:
public bool ZipCodeIsValid
{
get
{
var zipCodeRegex = new Regex("^(?:\d{5})(?:-\d{4})?$");
var zipCodeMatch = zipCodeRegex.Match(ZipCodeText);
return zipCodeMatch.Success;
}
}
Каждый раз ZipCodeText
изменения свойств, поднять уведомление об изменении свойства для события ZipCodeIsValid
имущество.
Создайте стиль для вашего TextBox:
<Style TargetType="TextBox">
<Setter Property="Foreground" Value="Black"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ZipCodeIsValid}" Value="False">
<Setter Property="Foreground" Value="Black"/>
</DataTrigger>
</Style.Triggers>
</Style>
Если вы не хотите вносить такие большие изменения и ищете более быстрое решение, вы можете переместить строки регулярного выражения в статические свойства и использовать их с прикрепленным поведением, тогда вы не будете дублировать регулярное выражение и сможете использовать их в модель представления для проверки прохождения валидации.
Создайте класс с именем ValidationRegex со статическим строковым свойством с именем ZipCode:
public class ValidationRegex
{
public static string ZipCode = "^(?:\d{5})(?:-\d{4})?$";
}
Используйте его с прикрепленным поведением:
<TextBox h:ColorMaskingTextBoxBehavior.Mask="{x:Static ValidationRegex.ZipCode}"/>
Используйте его в вашей модели представления:
public void Save()
{
var zipCodeRegex = new Regex(ValidationRegex.ZipCode);
var zipCodeMatch = zipCodeRegex.Match(ZipCodeText);
if (!zipCodeMatch.Success)
{
throw new ValidationException("Zip code is invalid!");
}
}