Added Validation logics

This commit is contained in:
TheXamlGuy
2024-06-16 13:42:36 +01:00
parent bca4a32964
commit a0b074c9e0
12 changed files with 160 additions and 58 deletions
+86 -7
View File
@@ -1,10 +1,89 @@
namespace Toolkit.Foundation;
using System.ComponentModel;
using System.Linq.Expressions;
public record Validation
namespace Toolkit.Foundation;
public class Validation(IValidatorCollection validators) :
IValidation
{
public static ValidationEventArgs<TValue> As<TValue>(TValue value) =>
new(value);
public event PropertyChangedEventHandler? PropertyChanged;
public static ValidationEventArgs<TValue> As<TValue>() where TValue : new() =>
new(new TValue());
}
public ValidationErrorCollection Errors { get; } = [];
public bool HasErrors =>
Errors.Count > 0;
internal IValidatorCollection Validators { get; } = validators;
public void Add<TProperty>(Expression<Func<TProperty>> property,
ValidationRule[] rules,
ValidationTrigger trigger = ValidationTrigger.Deferred)
{
string? name = GetPropertyName(property);
Validators.Add(name, new Validator(name, rules));
if (trigger is ValidationTrigger.Immediate)
{
Validate(name);
}
}
public virtual void OnPropertyChanged(string propertyName,
object? before, object? after)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public bool Validate(string name)
{
if (Errors.ContainsKey(name))
{
Errors.Remove(name);
}
if (Validators.TryGet(name, out Validator? validator))
{
if (validator is not null)
{
if (!validator.TryValidate(out string? message))
{
Errors[name] = message ?? "";
}
}
}
OnPropertyChanged(nameof(Errors), null, null);
OnPropertyChanged(nameof(HasErrors), null, null);
return !HasErrors;
}
public bool Validate()
{
Errors.Clear();
foreach (Validator? validator in Validators)
{
if (validator.PropertyName is string name)
{
if (!validator.TryValidate(out string? message))
{
Errors[name] = message ?? "";
}
}
}
OnPropertyChanged(nameof(Errors), null, null);
OnPropertyChanged(nameof(HasErrors), null, null);
return !HasErrors;
}
private string GetPropertyName<T>(Expression<Func<T>> predicate)
{
Expression? body = predicate.Body;
MemberExpression? memberExpression = body as MemberExpression ??
(MemberExpression)((UnaryExpression)body).Operand;
return memberExpression.Member.Name;
}
}