Stylet的数据验证

1. 通过NuGet安装 FluentValidation 包

2. 从IModelValidator接口定义自己的验证类

  • 注意FluentModelValidator的版本,我使用的是8.1.2,不同版本的API可能修改
public class FluentModelValidator<T> : IModelValidator<T>
    {
        private readonly IValidator<T> validator;
        private T _subject;

        public FluentModelValidator(IValidator<T> validator)
        {
            this.validator = validator;
        }

        public void Initialize(object subject)
        {
            this._subject = (T)subject;
        }

        public async Task<IEnumerable<string>> ValidatePropertyAsync(string propertyName)
        {
            // If someone's calling us synchronously, and ValidationAsync does not complete synchronously,
            // we'll deadlock unless we continue on another thread.
            return (await this.validator.ValidateAsync(this._subject, CancellationToken.None, propertyName).ConfigureAwait(false))
                .Errors.Select(x => x.ErrorMessage);
        }

        public async Task<Dictionary<string, IEnumerable<string>>> ValidateAllPropertiesAsync()
        {
            // If someone's calling us synchronously, and ValidationAsync does not complete synchronously,
            // we'll deadlock unless we continue on another thread.
            return (await this.validator.ValidateAsync(this._subject).ConfigureAwait(false))
                .Errors.GroupBy(x => x.PropertyName)
                .ToDictionary(x => x.Key, x => x.Select(failure => failure.ErrorMessage));
        }
    }

3. 定义ViewModel

  • Screen继承了ValidatingModelBase ,所以可以ViewModel可以直接继承自Screen
public class LoginViewModel : Screen
    {
        /// <summary>
        /// 手机号
        /// </summary>
        public string PhoneNumber { get; set; }
       }

4. 为LoginViewModel 编写校验类

  • 注意命名规则 xxxViewModel + Validator, 符合这个命名规则的类,stylet框架会自己调用
 public class LoginViewModelValidator : AbstractValidator<LoginViewModel>
 {
       public LoginViewModelValidator()
        {
            RuleFor(x => x.PhoneNumber).NotEmpty().Length(11).WithMessage("请输入正确的手机号");
        }
}

5. 在页面绑定PhoneNumber

<TextBox Text="{Binding PhoneNumber,UpdateSourceTrigger=PropertyChanged}"></TextBox>

6. 联合按钮的禁用和启用状态

  • 在LoginViewModel中添加以下代码
protected override void OnValidationStateChanged(IEnumerable<string> changedProperties)
        {
            base.OnValidationStateChanged(changedProperties);
            // Fody can't weave other assemblies, so we have to manually raise this
            this.NotifyOfPropertyChange(() => this.CanSubmit);
        }
        public bool CanSubmit => !this.HasErrors;

        public async void Submit()
        {
            if (await this.ValidateAsync())
            {
                MessageBox.Show(”success“);
            }
        }
posted @ 2022-06-07 07:59  清楚xc  阅读(66)  评论(0)    收藏  举报