ReactiveUI Validate только при изменении пользовательского ввода - PullRequest
0 голосов
/ 08 марта 2020

Я новичок ie в ReactiveUI, поэтому я застрял с проблемой, что мои сообщения об ошибках отображаются в начале страницы, а не после изменения пользовательского ввода.

Я полагаю, у меня есть проблема с ComplexRule. Итак, вот мой код во ViewModel:

    public LoginViewModel(IScreen screen)
    {
        HostScreen = screen;
        NameRule = this.ValidationRule(
            viewModel => viewModel.UserName,
            name => name.Length > 2,
            "You must specify a valid name longer then 2 sybols.");

        //checks with Regexp password
        PasswordRule = this.ValidationRule(
            viewModel => viewModel.Password,
            password => PasswordValidator.Validate(password),
            "You must specify a valid password longer then 8 sybols with at least 1 digit, upper 
             case, lower case and special characters.");

        var nameAndPasswordRules = this
            .WhenAnyValue(
                x => x.UserName,
                x => x.Password,
                (name, password) => NameRule.IsValid && PasswordRule.IsValid);

        ComplexRule = this.ValidationRule(
            _ => nameAndPasswordRules,
            (vm, state) => !state ? "Username and Password should be both valid!" : string.Empty);

        var canNavigate = this.IsValid();

        NavigateToMainPage = ReactiveCommand.CreateFromObservable(() =>
        {
            return HostScreen.Router.NavigateAndReset.Execute(new MyTabbedViewModel(HostScreen));
        }, canNavigate);
    }

А вот мой вид:

    public LoginView()
    {
        InitializeComponent();
        this.WhenActivated(disposables =>
        {
            this.Bind(ViewModel, vm => vm.UserName, v => v.username.Text)
                .DisposeWith(disposables);

            this.BindValidation(ViewModel, vm => vm.NameRule, v => v.usernameErrors.Text)
                .DisposeWith(disposables);

            this.Bind(ViewModel, vm => vm.Password, v => v.password.Text)
                .DisposeWith(disposables);

            this.BindValidation(ViewModel, vm => vm.PasswordRule, v => v.passwordErrors.Text)
                .DisposeWith(disposables);

            this.BindCommand(ViewModel, x => x.NavigateToMainPage, x => x.loginButton)
                .DisposeWith(disposables);
        });
    }

Итак, я пытаюсь добиться проверки после изменений пользовательского ввода (пароль / имя пользователя) и показать соответствующее сообщение. Я взял этот пример из документации.

1 Ответ

0 голосов
/ 10 марта 2020

Я пробовал пару подходов и закончил с этим. Не уверен, что это лучший способ сделать это, но он работает (Хотелось бы услышать ваше мнение, если вы знаете, как это сделать лучше.

Я присваиваю null значение для свойства

[Reactive]
public string UserName { get; set; } = null;

[Reactive]
public string Password { get; set; } = null;

поэтому мы предположим, что null - означает, что он никогда не использовался.

И поместим такую ​​проверку в ValidationRule

        var name = this
            .WhenAnyValue(x => x.UserName)
            .Select(x => x == null || x?.Length > 2);

        var password = this
            .WhenAnyValue(x => x.Password)
            .Select(x => x == null || PasswordValidator.Validate(x));

        var nameAndPasswordRules = this
            .WhenAnyValue(
                x => x.UserName,
                x => x.Password)
            .DefaultIfEmpty()
            .DistinctUntilChanged()
            .SkipWhile(item => !string.IsNullOrWhiteSpace(item.Item1) && !string.IsNullOrWhiteSpace(item.Item2))
            .Select(prop1 =>
                        !string.IsNullOrEmpty(prop1.Item1)
                        && this.NameRule.IsValid
                        && !string.IsNullOrEmpty(prop1.Item2)
                        && this.PasswordRule.IsValid);

        NameRule = this.ValidationRule(
            _ => name,
            (vm, state) => !state ? "You must specify a valid name longer then 2 sybols." : string.Empty);

        PasswordRule = this.ValidationRule(
            _ => password,
            (vm, state) => !state ? "You must specify a valid password longer then 8 sybols with at least 1 digit, upper case, lower case and special characters." : string.Empty);

        ComplexRule = this.ValidationRule(
            _ => nameAndPasswordRules,
            (vm, state) => !state ? "Username and Password should be both valid!" : string.Empty);

Как видите, я делаю x == null || ... Средства для обхода первой попытки, потому что пользователь не редактировал запись

...