ReactiveUI.Validation icon indicating copy to clipboard operation
ReactiveUI.Validation copied to clipboard

feature: Bind validation to non-string view properties

Open scribblemaniac opened this issue 3 years ago • 0 comments

Is your feature request related to a problem? Please describe.

Not related to a problem.

Describe the solution you'd like

So what I'm trying to do is change the color of control in my view based on the validation state of a validation helper. The control does have an error property or something similar, and I do not want to show an inline error message anyway for this particular situation. What I would like to be able to do is something like this:

this.BindValidation(ViewModel, viewModel => viewModel.Property, view => view.Control.Color,
    validationState => validationState.IsValid ? Color.Green : Color.Red); 

This would similar to the overload of the OneWayBind function that allows you to bind between types like so:

this.OneWayBind(ViewModel, viewModel => vm.BoolProperty, view => view.Control.Color,
    boolProperty => boolProperty ? Color.Green : Color.Red);

Describe alternatives you've considered

Currently this is how I'm achieving the same effect:

this.WhenAnyObservable(v => v.ViewModel.PropertyValidator.ValidationChanged)
    .Select(validationState => validationState.IsValid ? Color.Green : Color.Red)
    .BindTo(this, v => v.Control.Color);

This works, and I don't necessarily hate it, but I would prefer the proposed form for brevity and to match with the rest of my simple bindings.

Describe suggestions on how to achieve the feature

I'm not sure exactly how to make this work or I probably just would have made done it and made PR, but I think the signatures of the overloads for such a change would look something like this:

public static IDisposable BindValidation<TView, TViewModel, TViewModelProperty, TViewProperty>(
    this TView view,
    TViewModel? viewModel,
    Expression<Func<TViewModel, TViewModelProperty>> viewModelProperty,
    Expression<Func<TView, TViewProperty>> viewProperty,
    Expression<Func<IValidationState, TViewProperty>> selector,
    IValidationTextFormatter<string>? formatter = null)
    where TView : IViewFor<TViewModel>
    where TViewModel : class, IReactiveObject, IValidatableViewModel

and this:

public static IDisposable BindValidation<TView, TViewModel, TViewProperty>(
    this TView view,
    TViewModel? viewModel,
    Expression<Func<TViewModel?, ValidationHelper?>> viewModelHelperProperty,
    Expression<Func<TView, TViewProperty>> viewProperty,
    Expression<Func<IValidationState, TViewProperty>> selector,
    IValidationTextFormatter<string>? formatter = null)
    where TView : IViewFor<TViewModel>
    where TViewModel : class, IReactiveObject, IValidatableViewModel

Additional context

scribblemaniac avatar Jun 26 '22 23:06 scribblemaniac