One of the very common tasks that any mobile developer meets is validation of the user input. It can be an email, password complexity, length, not empty or any other sort of input validation. In this article we will try to find an appropriate light-weight and reusable solution, so let’s start!
I am using PropertyChanged.Fody to reduce the INotifyPropertyChanged bloatware related code. Some while ago I wrote a tiny article about it. Beside that, there will be no special requirements, just plain MVVM, C# and Xamarin.Forms.
Let’s start by introducing a generic interface IValidationRule<T>. It has to have a Validate method which needs to return a bool and a string property to represent the validation description.
Now let’s create a generic class ValidatableObject<T>. It should have a collection of IValidationRule<T>, bool property to represent the validity of the value, property to represent the value itself, string property to aggregate all the validation descriptions and a constructor that takes all the necessary input.
The code above might be unclear for you if you are not familiar with Fody. For example usage of OnValueChanged() and usage of DependsOn attribute, luckily the official documentation nicely explains both of them. I also introduced an optional Action propertyChangedCallback which might be useful in case you want to change the button state right after the value change or take some extra action.
The implementation above takes a string as an input, validates that the string is not null or empty and ensures that the string length is equal or greater than 6.
The implementation above takes a string as an input, validates that the string is not null or empty and ensures that the string represents a valid email address format.
Now lets take a look on a simplified LoginViewModel that has two ValidatableObjects: Email and Password.
LoginCmd will automatically set the button state to enabled / disabled according to validity of the user input. Preceding is done by triggering ChangeCanExecute every time the value of the ValidatableObject is changed.
There is one more thing to demonstrate before switching to XAML and it is our very simple BaseViewModel:
Now let’s take a look on our LoginPage:
We use InvertBooleanConverter to hide / display the validation error descriptions by binding to IsValid properties of our ValidatableObjects. We also use DataTriggers to set the TextColor property of Entry to red if the input is not valid. Rather then that, there is nothing extraordinary in the XAML above.
User input validation is rather fun than hard. The proposed solution nicely encapsulates the validation logic and can be easily covered by unit tests. One ValidatableObject can have multiple IValidationRules and you can easily decide yourself how to reflect the validity of the input on the UI layer.