fsprojects-archive / zzarchive-FSharp.Desktop.UI

F# MVC framework for WPF.
http://fsprojects.github.io/FSharp.Desktop.UI/
Other
81 stars 21 forks source link

Added binding of view level validators (WPF ValidationRule). #15

Closed akasubi closed 8 years ago

akasubi commented 9 years ago

I've added binding of view level validators, i.e. ValidationRule descendants in WPF. I hope this is of interest!

Basic usage is:

let myIntValidator (value : obj) (_ : CultureInfo) = 
    if (value.ToString() |> Int64.TryParse |> fst
    then ViewValidation.Valid
    else ViewValidation.Invalid("Enter an integer.")

Binding.OfExpression 
    <@ textBox.Text <- model.Value |> ViewValidator myIntValidator ValidationStep.RawProposedValue false @>

Under the hood, the validation function gets wrapped in a ValidationRule object.

Thanks to FSharp.Quotations.Evaluator, you can supply extra arguments to the validation functions by currying:

let rangeValidator (min : int) (max : int) (value : obj) (_ : CultureInfo) = 
    // ...

Binding.OfExpression 
    <@ this.Root.MyField.Text <- 
        model.Value |> ViewValidator (rangeValidator 1 100) ValidationStep.Raw false @>

Any existing ValidationRule descendants can be bound by ViewValidationRule: <@ textBox.Text <- model.Value |> ViewValidationRule (ExceptionValidationRule()) @>

What's missing is maintaining a collection that keeps track of all view level validation rules, so that you can explicitly run them all with one call. That would useful for example when the user clicks "OK" and you want to validate the entire view. It's easy to implement, but I'm not sure where this would fit in best. One alternative is to have PartialView.SetBindings return a validator collection, which is stored in the view. This would require Binding.OfExpression to create and return that collection. Any thoughts about this?

dmitry-a-morozov commented 8 years ago

@wezeku Would like to be an owner of this project? I have no capacity to maintain it going forward.

akasubi commented 8 years ago

@dmitry-a-morozov I do like this project, so I'd be happy to be an owner of it. BTW, this pull req got closed because I'm moving it into a separate feature branch.