Skip to content

Instantly share code, notes, and snippets.

@danielplawgo
Last active June 13, 2018 13:11
Show Gist options
  • Save danielplawgo/46edba368218a0a602b492b02034ea35 to your computer and use it in GitHub Desktop.
Save danielplawgo/46edba368218a0a602b492b02034ea35 to your computer and use it in GitHub Desktop.
Integracja Fluent Validation z WPF wersja async
<TextBox
Text="{Binding Email,
UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay,
ValidatesOnNotifyDataErrors=True}"
Name="Email"/>
public override Task<ValidationResult> SelfValidate()
{
return Validator.ValidateAsync(this);
}
public class MainWindowViewModelValidator : AbstractValidator<MainWindowViewModel>
{
public MainWindowViewModelValidator()
{
RuleFor(u => u.Email)
.Cascade(CascadeMode.StopOnFirstFailure)
.NotEmpty()
.EmailAddress()
.MustAsync((email, token) => ValidateEmail(email, token))
.WithMessage("Email must be unique");
}
private async Task<bool> ValidateEmail(string email, CancellationToken token)
{
await Task.Delay(2000);
return email != "daniel@plawgo.pl";
}
}
public virtual Task<ValidationResult> SelfValidate()
{
return Task.FromResult(new ValidationResult());
}
private bool _isValidating;
public bool IsValidating
{
get { return _isValidating; }
set
{
if (_isValidating != value)
{
_isValidating = value;
OnPropertyChanged(() => this.IsValidating);
}
}
}
private ValidationResult ValidationResult { get; set; }
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
private void OnErrorsChanged(string propertyName)
{
if (ErrorsChanged == null)
{
return;
}
ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));
}
public bool HasErrors => IsValid == false;
public IEnumerable GetErrors(string propertyName)
{
if (ValidationResult == null)
{
return new List<string>();
}
return ValidationResult.Errors.Where(e => e.PropertyName == propertyName).Select(e => e.ErrorMessage).ToList();
}
protected async Task<bool> Validate()
{
IsValidating = true;
ValidationResult = await SelfValidate();
IsValidating = false;
IsValid = ValidationResult.IsValid;
if (IsValid == false)
{
foreach(var propertyName in ValidationResult.Errors.Select(e => e.PropertyName).Distinct())
{
OnErrorsChanged(propertyName);
}
}
return IsValid;
}
private async void OnPropertyChanged(string propertyName)
{
var propertyChanged = PropertyChanged;
if (propertyChanged == null)
{
return;
}
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
if (propertyName != nameof(IsValid) && propertyName != nameof(IsValidating))
{
await Validate();
if(ValidationResult.Errors.Any(e => e.PropertyName == propertyName) == false)
{
OnErrorsChanged(propertyName);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment