예제 #1
0
        public ValidationViewModel()
        {
            // null is success(have no error), string is error message
            ValidationData = new ReactiveProperty <string>()
                             .SetValidateNotifyError((string s) => !string.IsNullOrEmpty(s) && s.Cast <char>().All(Char.IsUpper) ? null : "not all uppercase");

            // async validation
            // first argument is self observable sequence
            // null is success(have no error), IEnumerable is error messages
            ValidationNotify = new ReactiveProperty <string>("foo!", ReactivePropertyMode.RaiseLatestValueOnSubscribe)
                               .SetValidateNotifyError(self => self
                                                       .Delay(TimeSpan.FromSeconds(3)) // asynchronous validation...
                                                       .Select(s => string.IsNullOrEmpty(s) ? null : "not empty string"));

            // both validation
            ValidationBoth = new ReactiveProperty <string>()
                             .SetValidateNotifyError(s => !string.IsNullOrEmpty(s) && s.Cast <char>().All(Char.IsLower) ? null : "not all lowercase")
                             .SetValidateNotifyError(self => self
                                                     .Delay(TimeSpan.FromSeconds(1)) // asynchronous validation...
                                                     .Select(s => string.IsNullOrEmpty(s) || s.Length <= 5 ? null : (IEnumerable) new[] { "length 5" }));

            // Validation result is pushed to ObserveErrors
            var errors = new[]
            {
                ValidationData.ObserveErrorChanged,
                ValidationBoth.ObserveErrorChanged,
                ValidationNotify.ObserveErrorChanged
            }
            .CombineLatest();

            // Use OfType, choose error source
            ErrorInfo = errors
                        .SelectMany(x => x)
                        .Where(x => x != null)
                        .Select(x => x.OfType <string>())
                        .Select(x => x.FirstOrDefault())
                        .ToReactiveProperty();

            // Validation is view initialized not run in default.
            // If want to validate on view initialize,
            // use ReactivePropertyMode.RaiseLatestValueOnSubscribe to ReactiveProperty
            // that mode is validate values on initialize.
            NextCommand =
                new[]
            {
                ValidationData.ObserveHasErrors,
                ValidationBoth.ObserveHasErrors,
                ValidationNotify.ObserveHasErrors
            }
            .CombineLatestValuesAreAllFalse()
            .ToReactiveCommand();
            this.AlertMessage = NextCommand.Select(_ => "Can go to next!").ToReactiveProperty(
                initialValue: "Can go to next!",
                mode: ReactivePropertyMode.None);
        }
예제 #2
0
        public ValidationViewModel()
        {
            // IDataErrorInfo, call SetValidateError and set validate condition
            // null is success(have no error), string is error message
            ValidationData = new ReactiveProperty <string>()
                             .SetValidateNotifyError((string s) => !string.IsNullOrEmpty(s) && s.Cast <char>().All(Char.IsUpper) ? null : "not all uppercase");

            // INotifyDataErrorInfo, call SetValidateNotifyErro and set validate condition
            // first argument is self observable sequence
            // null is success(have no error), IEnumerable is error messages
            ValidationNotify = new ReactiveProperty <string>("foo!", ReactivePropertyMode.RaiseLatestValueOnSubscribe)
                               .SetValidateNotifyError(self => self
                                                       .Delay(TimeSpan.FromSeconds(3)) // asynchronous validation...
                                                       .Select(s => string.IsNullOrEmpty(s) ? null : (IEnumerable) new[] { "not empty string" }));

            // Can set both validation
            ValidationBoth = new ReactiveProperty <string>()
                             .SetValidateNotifyError((string s) => !string.IsNullOrEmpty(s) && s.Cast <char>().All(Char.IsLower) ? null : "not all lowercase")
                             .SetValidateNotifyError(self => self
                                                     .Delay(TimeSpan.FromSeconds(1)) // asynchronous validation...
                                                     .Select(s => string.IsNullOrEmpty(s) || s.Length <= 5 ? null : (IEnumerable) new[] { "length 5" }));

            // Validation result is pushed to ObserveErrorChanged
            var errors = Observable.Merge(
                ValidationData.ObserveErrorChanged,
                ValidationBoth.ObserveErrorChanged,
                ValidationNotify.ObserveErrorChanged);

            // Use OfType, choose error source
            ErrorInfo = Observable.Merge(
                errors.Where(o => o == null).Select(_ => ""),   // success
                errors.OfType <string>(),                       // from IDataErrorInfo
                errors.OfType <string[]>().Select(xs => xs[0])) // from INotifyDataErrorInfo
                        .ToReactiveProperty();

            // Validation is view initialized not run in default.
            // If want to validate on view initialize,
            // use ReactivePropertyMode.RaiseLatestValueOnSubscribe to ReactiveProperty
            // that mode is validate values on initialize.
            NextCommand = ValidationData.ObserveErrorChanged
                          .CombineLatest(
                ValidationBoth.ObserveErrorChanged,
                ValidationNotify.ObserveErrorChanged,
                (a, b, c) => new[] { a, b, c }.All(x => x == null))
                          .ToReactiveCommand(initialValue: false);
            this.AlertMessage = NextCommand.Select(_ => "Can go to next!").ToReactiveProperty(
                initialValue: "Can go to next!",
                mode: ReactivePropertyMode.None);
        }