In this post I would like to share how I’ve implemented user input data validation in Xamarin Forms.

Over the years I’ve tried a few approaches, some with success, others without. This one is an implementation I’ve used in my latest projects and that I’m liking a lot. I’m not saying this is THE best way of doing data validation, but I think it is an elegant way (both in code AND in XAML) of doing it. It works for me, so I would like to share it with you. One of the things I really like about this solution is that I’m having some default UI right out of the box, but I can easily customize the look and feel of the controls per project, as I will show you throughout this post.

Note: For the sake of this blogpost, I’ve left out some non-vital parts, but the full source code can be found on GitHub. And if you have any questions, don’t hesitate to contact me (comments, mail, twitter,…)

 

This blog post is part of the Xamarin UI July organised by Steven Thewissen. Be sure to check out all other posts of Xamarin UI July!

Xamarin UI July

What I think is important for Data Validation

To me, one of the hardest things with data validation is getting an error message on to the screen. Why? Well, because of a couple of reasons:

  • Because of UX reasons, I would like to display a message right at the control where the inputted data is not OK so that user undoubtebly knows where to correct it.
  • Error messages should be localized, don’t they?
  • Also because of “I’m a lazy developer” reasons, I want to define where and how to display these error messages in an easy, concise and reusable manner in my XAML, whilst keeping my XAML clean.
  • Notwithstanding having the ability to be very flexible and not being tight to ‘only one way of doing it’. Maybe, on a particular screen, I don’t want the error message right next to input control, but instead I want to show a summary of error messages.

And of top of that, I don’t want to make the data validation complex. You want to focus on the business or validation logic rather then needing to focus on tying everything up in your ViewModel, right? We don’t want to clutter our ViewModel, we just want to have our validation logic there in a clean way.

Let’s take a look at my approach

Implementing the validation

One of the core parts of my solution is the ErrorStateManager. Basically, this is a very simple class that has a Dictionary which holds the errors per property. It has methods for clearing all errors, adding an error and it also has an indexed property. With this indexed property, you can pass in the name of a property and it will return the errors on that property (if any).

Next to my ErrorStateManager object, I’ve also have an ErrorState object. It holds error/violation messages that belong to one property. This is how this looks like:

 

Let’s go one level up: to the ViewModel
I created a base ViewModel which contains an ErrorStateManager and which holds a collection of Validators.
This base ViewModel takes responsability for executing Validators and updating the ErrorStateManager.

About these Validators. There are always validations and rules that come back in each project: checking for not null, regex checking, … just to name a few. I wanted to be able to have a standard set of validation rules that I could easily re-use in multiple projects, as well as having the ability to create dedicated (business) rules for a particular project. Hence, I created the IValidator interface and the ValidatorBase classes to back these needs. This gives me all flexibility of having standard and reusable validators as well as being able to create custom validation rules in an elegant way.

This all results, IMHO, in clean ViewModels that allow me to do simple validation. Take a look at how my MainPageViewModel looks, which does (multiple) validations on 3 inputs.

How do I get this on my screen?

Simple! Recall the fact that my ViewModels now have an ErrorStateManager. This class has an indexed property to which I can pass a string (name of the property, or basically anything you want) to get the associated ErrorState back which holds a list of errors/violations. Like this:

As you can see in the snippet above, I created this custom ErrorView. It is used to show one particular ErrorState. Remember, that is errormessages/violations for a particular key (==property name). This control has a BindableProperty ‘ErrorState’ to which we can bind.
How does the XAML of this control looks like?

In the code behind, you can see I’ve created a BindableProperty so that I’m able to bind a particular ErrorState object to this Control.

But, nothing in XAML? Well, that is because I define the look of the control through a ControlTemplate. Why? Combination of laziness and flexibility is the answer!
I have a default template defined in my SimpleDataValidator project, which I can use without any effort.

In my projects in which I use my DataValidation, I’ll have to make sure I merge the ResourceDictionary of the SimpleDataValidator project, containing my default templates, with the ResourceDictionary of my project.

Next to my ErrorView, I also have a ErrorSummaryView. The whole ErrorStateManager is bound to this control so we can easily access all errors and violations for that particular view. Just like with the ErrorView, I’m using ControlTemplates to visualize this control, having a default template in the SimpleDataValidator project.

This is what the ErrorView looks like by default:

Customizing the ErrorView

However, for particular projects, my validation errors might need to be displayed in a different way. In that case I can define my own ControlTemplate, apply it via a Style and do whatever I want with it. I found this nice Lottie animation that I would like to embed in my ErrorView: https://lottiefiles.com/3541-error

Lottie-Error animation

I downloaded the json file and referenced the ‘Com.Airbnb.Xamarin.Forms.Lottie’ NuGet Package which allows me to show Lottie animations. Next, I added the Lottie json file to my head projects and created my ControlTemplate with the AnimationView inside of it:

As you can see, I’m binding the ErrorState.HasError to the IsPlaying property of the AnimationView. This will cause the ANimation to start as soon as the HasError property returns ‘true’.

There was just one thing bugging me… I didn’t like the first part of the Lottie animation, the ‘loading’ part. The AnimationView has a method PlayProgressSegment that can be used to specify from where to where the animation needs to be played (where 0 is the start of the animation and 1 the end). Calling PlayProgressSegment(.5f, 1f); would play the animation from the half of the animation till the end.

What would be the easiest way configure this in a dynamic way in the ControlTemplate?

Attached Properties to the rescue

I created a bunch of Attached Properties which should help me achieving this. 1 property would take a float representing from where the animation should start, and other one, also a float, to where the animation should run. The third property, a bool, should start the animation.

As you can see, when the StartPlayAtProgress property is set to true, the PlayProgressSegment method is called, passing in the offsets that are defined.

Once this is in place, we can configure everything in XAML like this:

The final result looks something like this:

 

That’s it folks! With this blogpost I’ve shown you how I’m doing validation in my most recent projects. I think it is an elegant and simple way of doing this kind of stuff, but still being very flexible both on the code/viewmodel side as well as on the UI part of the story.

Moreover, I elaborated a bit on how to customize the ErrorView to suite special needs/specs. I showed how I’ve created Attached Properties to start Lottie animations going from and to a particular process segment.

You can find all the source code on GitHub!

I’d love to hear about your suggestions or remarks on this!