/// <summary> /// Binding a specified view model property to a provided action. /// </summary> /// <typeparam name="TView"></typeparam> /// <typeparam name="TViewModel"></typeparam> /// <typeparam name="TViewModelProperty1"></typeparam> /// <typeparam name="TOut"></typeparam> /// <param name="view"></param> /// <param name="viewModelProperty"></param> /// <param name="action"></param> /// <param name="formatter"></param> /// <param name="strict"></param> /// <returns></returns> public static IValidationBinding ForProperty <TView, TViewModel, TViewModelProperty1, TOut>(TView view, Expression <Func <TViewModel, TViewModelProperty1> > viewModelProperty, Action <ValidationState, TOut> action, IValidationTextFormatter <TOut> formatter = null, bool strict = true) where TView : IViewFor <TViewModel> where TViewModel : ReactiveObject, ISupportsValidation { if (formatter == null) { throw new ArgumentNullException(nameof(formatter)); } var vcObs = view.WhenAnyValue(v => v.ViewModel). Where(vm => vm != null). Select( viewModel => viewModel.ValidationContext.ResolveFor(viewModelProperty, strict) .ValidationStatusChange). Switch(). Select(vc => new { ValidationChange = vc, Formatted = formatter.Format(vc.Text) }). Do(r => action(r.ValidationChange, r.Formatted)). Select(_ => Unit.Default); return(new ValidationBinding(vcObs)); }
/// <summary> /// Create a binding between a view model property and a view property. /// </summary> /// <remarks>Supports multiple validations for the same property.</remarks> /// <typeparam name="TView">ViewFor of ViewModel type.</typeparam> /// <typeparam name="TViewModel">ViewModel type.</typeparam> /// <typeparam name="TViewModelProperty">ViewModel property type.</typeparam> /// <typeparam name="TViewProperty">View property type.</typeparam> /// <param name="view">View instance.</param> /// <param name="viewModelProperty">ViewModel property.</param> /// <param name="viewProperty">View property.</param> /// <param name="formatter">Validation formatter.</param> /// <param name="strict">Indicates if the ViewModel property to find is unique.</param> /// <returns>Returns a validation component.</returns> public static IValidationBinding ForProperty <TView, TViewModel, TViewModelProperty, TViewProperty>( TView view, Expression <Func <TViewModel, TViewModelProperty> > viewModelProperty, Expression <Func <TView, TViewProperty> > viewProperty, IValidationTextFormatter <string> formatter = null, bool strict = true) where TView : IViewFor <TViewModel> where TViewModel : ReactiveObject, ISupportsValidation { if (formatter == null) { formatter = SingleLineFormatter.Default; } var vcObs = view.WhenAnyValue(v => v.ViewModel) .Where(vm => vm != null) .Select( viewModel => viewModel.ValidationContext .ResolveForMultiple(viewModelProperty, strict) .Select(x => x.ValidationStatusChange) .CombineLatest()) .Switch() .Select(states => states.Select(state => formatter.Format(state.Text)).ToList()); var updateObs = BindToView(vcObs, view, viewProperty) .Select(_ => Unit.Default); return(new ValidationBindingEx(updateObs)); }
/// <summary> /// Bind a <see cref="ValidationHelper"/> to a specified action. /// </summary> /// <typeparam name="TView"></typeparam> /// <typeparam name="TViewModel"></typeparam> /// <typeparam name="TOut"></typeparam> /// <param name="view"></param> /// <param name="viewModelHelperProperty"></param> /// <param name="action"></param> /// <param name="formatter"></param> /// <returns></returns> public static IValidationBinding ForValidationHelperProperty <TView, TViewModel, TOut>(TView view, Expression <Func <TViewModel, ValidationHelper> > viewModelHelperProperty, Action <ValidationState, TOut> action, IValidationTextFormatter <TOut> formatter = null ) where TView : IViewFor <TViewModel> where TViewModel : ReactiveObject, ISupportsValidation { if (formatter == null) { throw new ArgumentNullException(nameof(formatter)); } var vcObs = view.WhenAnyValue(v => v.ViewModel). Where(vm => vm != null). Select( viewModel => viewModel.WhenAnyValue(viewModelHelperProperty).SelectMany(vy => vy.ValidationChanged)). Switch(). Select(vc => new { ValidationChange = vc, Formatted = formatter.Format(vc.Text) }); var updateObs = vcObs.Do(r => { action(r.ValidationChange, r.Formatted); }). Select(_ => Unit.Default); return(new ValidationBinding(updateObs)); }
/// <summary> /// Create a binding between a <see cref="ValidationHelper"/> and a specified view property. /// </summary> /// <typeparam name="TView"></typeparam> /// <typeparam name="TViewModel"></typeparam> /// <typeparam name="TViewProperty"></typeparam> /// <param name="view"></param> /// <param name="viewModelHelperProperty"></param> /// <param name="viewProperty"></param> /// <param name="formatter"></param> /// <returns></returns> public static IValidationBinding ForValidationHelperProperty <TView, TViewModel, TViewProperty>(TView view, Expression <Func <TViewModel, ValidationHelper> > viewModelHelperProperty, Expression <Func <TView, TViewProperty> > viewProperty, IValidationTextFormatter <string> formatter = null) where TView : IViewFor <TViewModel> where TViewModel : ReactiveObject, ISupportsValidation { if (formatter == null) { formatter = SingleLineFormatter.Default; } var vcObs = view.WhenAnyValue(v => v.ViewModel). Where(vm => vm != null). Select( viewModel => viewModel.WhenAnyValue(viewModelHelperProperty).SelectMany(vy => vy.ValidationChanged)). Switch(). Select(vc => formatter.Format(vc.Text)); var updateObs = BindToView(vcObs, view, viewProperty). Select(_ => Unit.Default); return(new ValidationBinding(updateObs)); }
/// <summary> /// Creates a binding between a ViewModel and a View property. /// </summary> /// <typeparam name="TView">ViewFor of ViewModel type.</typeparam> /// <typeparam name="TViewModel">ViewModel type.</typeparam> /// <typeparam name="TViewProperty">View property type.</typeparam> /// <param name="view">View instance.</param> /// <param name="viewProperty">View property to bind the validation message.</param> /// <param name="formatter">Validation formatter.</param> /// <returns>Returns a validation component.</returns> public static IValidationBinding ForViewModel <TView, TViewModel, TViewProperty>( TView view, Expression <Func <TView, TViewProperty> > viewProperty, IValidationTextFormatter <string>?formatter = null) where TView : IViewFor <TViewModel> where TViewModel : ReactiveObject, IValidatableViewModel { if (view is null) { throw new ArgumentNullException(nameof(view)); } if (viewProperty is null) { throw new ArgumentNullException(nameof(view)); } formatter ??= SingleLineFormatter.Default; var vcObs = view .WhenAnyValue(v => v.ViewModel) .Where(vm => vm != null) .SelectMany(vm => vm !.ValidationContext.ValidationStatusChange) .Select(vc => formatter.Format(vc.Text)); var updateObs = BindToView(vcObs, view, viewProperty) .Select(_ => Unit.Default); return(new ValidationBinding(updateObs)); }
/// <summary> /// Creates a binding from a specified ViewModel property to a provided action. /// </summary> /// <typeparam name="TView">ViewFor of ViewModel type.</typeparam> /// <typeparam name="TViewModel">ViewModel type.</typeparam> /// <typeparam name="TViewModelProperty">ViewModel property type.</typeparam> /// <typeparam name="TOut">Action return type.</typeparam> /// <param name="view">View instance.</param> /// <param name="viewModelProperty">ViewModel property.</param> /// <param name="action">Action to be executed.</param> /// <param name="formatter">Validation formatter.</param> /// <param name="strict">Indicates if the ViewModel property to find is unique.</param> /// <returns>Returns a validation component.</returns> public static IValidationBinding ForProperty <TView, TViewModel, TViewModelProperty, TOut>( TView view, Expression <Func <TViewModel, TViewModelProperty> > viewModelProperty, Action <IList <ValidationState>, IList <TOut> > action, IValidationTextFormatter <TOut> formatter, bool strict = true) where TView : IViewFor <TViewModel> where TViewModel : ReactiveObject, IValidatableViewModel { if (view is null) { throw new ArgumentNullException(nameof(view)); } if (viewModelProperty is null) { throw new ArgumentNullException(nameof(viewModelProperty)); } if (action is null) { throw new ArgumentNullException(nameof(action)); } if (formatter == null) { throw new ArgumentNullException(nameof(formatter)); } var vcObs = view .WhenAnyValue(v => v.ViewModel) .Where(vm => vm != null) .Select( viewModel => viewModel ! .ValidationContext .ResolveFor(viewModelProperty, strict) .Select(x => x.ValidationStatusChange) .CombineLatest()) .Switch() .Select(states => new { ValidationChange = states, Formatted = states .Select(state => formatter.Format(state.Text)) .ToList() }) .Do(r => action(r.ValidationChange, r.Formatted)) .Select(_ => Unit.Default); return(new ValidationBinding(vcObs)); }
/// <summary> /// Creates a binding between a ViewModel property and a view property. /// </summary> /// <typeparam name="TView">ViewFor of ViewModel type.</typeparam> /// <typeparam name="TViewModel">ViewModel type.</typeparam> /// <typeparam name="TViewModelProperty">ViewModel property type.</typeparam> /// <typeparam name="TViewProperty">View property type.</typeparam> /// <param name="view">View instance.</param> /// <param name="viewModelProperty">ViewModel property.</param> /// <param name="viewProperty">View property.</param> /// <param name="formatter">Validation formatter. Defaults to the <see cref="SingleLineFormatter"/>.</param> /// <param name="strict">Indicates if the ViewModel property to find is unique.</param> /// <returns>Returns a validation component.</returns> public static IValidationBinding ForProperty <TView, TViewModel, TViewModelProperty, TViewProperty>( TView view, Expression <Func <TViewModel, TViewModelProperty> > viewModelProperty, Expression <Func <TView, TViewProperty> > viewProperty, IValidationTextFormatter <string>?formatter = null, bool strict = true) where TView : IViewFor <TViewModel> where TViewModel : ReactiveObject, IValidatableViewModel { if (view is null) { throw new ArgumentNullException(nameof(view)); } if (viewModelProperty is null) { throw new ArgumentNullException(nameof(viewModelProperty)); } if (viewProperty is null) { throw new ArgumentNullException(nameof(viewProperty)); } formatter ??= SingleLineFormatter.Default; var vcObs = view .WhenAnyValue(v => v.ViewModel) .Where(vm => vm != null) .Select( viewModel => viewModel ! .ValidationContext .ResolveFor(viewModelProperty, strict) .Select(x => x.ValidationStatusChange) .CombineLatest()) .Switch() .Select( states => states .Select(state => formatter.Format(state.Text)) .FirstOrDefault(msg => !string.IsNullOrEmpty(msg)) ?? string.Empty); var updateObs = BindToView(vcObs, view, viewProperty) .Select(_ => Unit.Default); return(new ValidationBinding(updateObs)); }