Не работает валидация данных в WinUI приложении
Пробую сделать валидацию вводимых данных в WinUI приложении. Пример взял отсюда. Используемый материал
XAML код страницы
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock Text="Login" Margin="5"/>
<!-- InputValidationKind="Hidden" этого свойства почему то нет -->
<TextBox
PlaceholderText="login"
Text="{x:Bind ViewModel.UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="5"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<TextBlock Text="Password" Margin="5"/>
<TextBox
PlaceholderText="password"
Text="{x:Bind ViewModel.Password, Mode=TwoWay}"
Margin="5"/>
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Horizontal">
</StackPanel>
<StackPanel Grid.Row="3" Orientation="Horizontal">
<Button
Content="Добавить"
Command="{x:Bind ViewModel.AddUserCommand}"
Margin="5"/>
</StackPanel>
</Grid>
Код ViewModel
namespace TestWinUIValidation.ViewModels;
public partial class TestViewModel : BindableBase
{
public TestViewModel()
{
AddUserCommand = new RelayCommand(AddUser);
}
private string _userName = string.Empty;
[MinLength(2, ErrorMessage = "Item name must be at least 2 characters.")]
public string UserName
{
get => _userName;
set => SetProperty(ref _userName, value);
}
private string _password = string.Empty;
public string Password
{
get => _password;
set => SetProperty(ref _password, value);
}
public ICommand AddUserCommand { get; set; }
private void AddUser()
{
//Здесь добавляем пользователя в модель
}
}
Код BindableBase
public partial class BindableBase : INotifyPropertyChanged, INotifyDataErrorInfo, IValidatable
{
public event PropertyChangedEventHandler? PropertyChanged;
/// <summary>
/// Происходит при изменении ошибок проверки для свойства или для всей сущности.
/// </summary>
public event EventHandler<DataErrorsChangedEventArgs>? ErrorsChanged;
/// <summary>
/// Этот метод устанавливает новое значение свойства, только если оно отличается от предыдущего,
/// после чего вызывает OnPropertyChanged
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="originalValue"></param>
/// <param name="newValue"></param>
/// <param name="propertyName"></param>
/// <returns></returns>
protected bool SetProperty<T>(ref T originalValue, T newValue, [CallerMemberName] string propertyName = "")
{
if (!EqualityComparer<T>.Default.Equals(originalValue, newValue))
{
originalValue = newValue;
OnPropertyChanged(propertyName, newValue);
return true;
}
return false;
}
readonly Dictionary<string, List<ValidationResult>> _errors = new Dictionary<string, List<ValidationResult>>();
/// <summary>
/// Возвращает значение, указывающее, имеет ли сущность ошибки проверки.
/// </summary>
public bool HasErrors
{
get
{
return _errors.Count > 0;
}
}
/// <summary>
/// Возвращает ошибки проверки для указанного свойства или для всей сущности.
/// </summary>
public IEnumerable GetErrors(string propertyName)
{
_errors.TryGetValue(propertyName, out List<ValidationResult> errors);
return errors;
}
/// <summary>
/// Этот метод просто генерирует событие PropertyChanged, которое представление должно будет обработать
/// </summary>
/// <param name="propertyName"></param>
private void OnPropertyChanged(string propertyName, object value)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
Validate(propertyName, value);
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
/// <summary>
/// Добавление ошибки в справочник ошибок
/// </summary>
/// <param name="propertyName">Имя свойства</param>
/// <param name="results">Объект результатов валидации</param>
private void AddErrors(string propertyName, IEnumerable<ValidationResult> results)
{
if (!_errors.TryGetValue(propertyName, out List<ValidationResult> errors))
{
errors = new List<ValidationResult>();
_errors.Add(propertyName, errors);
}
errors.AddRange(results);
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
}
private void ClearErrors(string propertyName)
{
if (_errors.TryGetValue(propertyName, out List<ValidationResult> errors))
{
errors.Clear();
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
}
}
public void Validate(string memberName, object value)
{
ClearErrors(memberName);
List<ValidationResult> results = new List<ValidationResult>();
bool result = Validator.TryValidateProperty(
value,
new ValidationContext(this, null, null)
{
MemberName = memberName
},
results);
if (!result)
{
AddErrors(memberName, results);
}
}
}
Интерфейс IValidatable
public interface IValidatable
{
void Validate(string memberName, object value);
}
И при вводе неправильных данных (например одного символа), поле ввода красным не становится. Хотя в отладчике видно, что ошибка ввода зафиксирована. Не подскажете почему не работает?