Validate input in Xamarin.Forms using INotifyDataErrorInfo, custom Behaviors, Effects and Prism

This post is also available in the Premier Developer blog.

I have recently been investigating the support available in Xamarin.Forms for validation and, in particular, researched the possibility of using INotifyDataErrorInfo to complement the traditional approach of using Behaviors.

In simple scenarios, it’s possible to perform validation by simply attaching a Behavior to the required view, as shown by the following sample code:

In this case, we are validating the input and modifying the UI if the number of characters entered is less than 5.

What about more articulated scenarios when multiple business rules are required to be checked for the input values?

In these cases, we could take advantage of other types available to make our code more structured and extensible:

  • INotifyDataErrorInfo: available in Xamarin.Forms. When implemented it permits specifying custom validation supporting multiple errors per property, cross-property errors and entity-level errors;
  • DataAnnotations decorate the data models using attributes which specify validation conditions to be applied to the specific field;
  • Forms Behaviors specify the specific UI to be applied to the specific validation scenarios, integrating with INotifyDataErrorInfo and DataAnnotations.

To start exploring this approach, I created a new Xamarin.Forms Prism solution using the Prism Template Pack which generated the following project structure:

Then, I added the following new model to be validated using DataAnnotations and INotifyDataErrorInfo:

The model uses attributes declared in the SystemComponentModel.DataAnnotations namespace which can be referenced in the solution modifying the Portable Class Library profile of the UsingValidation common project:

Quick tip: to be able to change the PCL profile I had to remove all the NuGet packages used by the common project, remove the Windows Phone 8 profile and then add back all the removed NuGet packages to the UsingValidation PCL.

To use the capability offered by INotifyDataErrorInfo, the model needs to implements 3 members defined in the interface:

  • GetErrors() returns an IEnumerable sequence of strings containing the error messages triggered by validation;
  • the HasErrors property returns a boolean value indicating if there are validation errors;
  • ErrorsChanged event can be triggered to Notify if the validation errors have been updated.

This interface is quite flexible and is designed to be customised depending on the different scenarios needed: I took as a starting point this implementation available on GitHub and modified it accordingly: I decided to separate the implementation of INotifyDataErrorInfo in a different base class called ValidationBase which contains the following code using a Dictionary<string, List<string>> needed for storing the generated validation errors:

The validation is performed by this method which evaluates the DataAnnotations decorating the model using the Validator available in the System.ComponentModel.DataAnnotations namespace and then stores the error messages in the dictionary:

At this stage, I needed a solution for linking the UI to the model, and modifying the visuals depending on the presence or not of validation errors.

The ViewModel for the sample page, contains only a property storing an instance of the item defined in the model:

Then, the corresponding XAML contains two Entry views used for input and a ListView used for showing the validation errors:

The sample page uses a Behavior called EntryValidationBehavior which take care of changing the colour of the Entry background views in the case validation errors are present:

The UI is also fine-tuned using a Xamarin.Forms effect applied only to the UWP platform, in order to change the colour of the Entry border when validation errors occur:

And this is the result when the application is executed on Android and UWP:

Conclusions

Xamarin.Forms provides a rich set of features for implementing validation: the usage of INotifyDataErrorInfo, Data Annotations, Behaviors and Effects permit the handling of complex scenarios including multiple conditions per field, cross-property validation, entity-level validation and custom UI depending on the platform.

The source code of the sample demo is available for download on GitHub here.

Happy coding!

Xamarin.Forms: sharing resources in XAML using Styles

Previously, I’ve blogged about creating a custom Behavior in Xamarin.Forms. The sample published on GitHub initially used the default template available in Visual Studio which instantiates the Application singleton from C# using the following App class:

This is a great approach, however very often it is useful to define common resources in XAML and reuse them across the application using Styles.

To achieve this, It’s possible to transform the App class in a partial one and add a new App.xaml source file containing a resource dictionary to be shared:

In this code, I’ve defined a new resource with a specific Padding to be applied only on iOS via the OnPlatform class, and an explicit style named PageStyle targeting ContentPage types.

The modified code behind is now taking care of parsing/loading the XAML (via the InitializeComponent() call) and then creates an instance of SamplePage:

The page can now consume the new style specifying Style=”{StaticResource PageStyle}” (dynamic resources are also supported):

This is a basic example of using styles in Xamarin.Forms: a complete coverage of the various options is available on the Xamarin official documentation.

The source code is available for download here.

Xamarin.Forms: using the PanGestureRecognizer

Recently I’ve blogged about Xamarin.Forms and how to create a XAML Behavior for enabling Multi-Touch gestures to generic elements and implementing a scale / pinch functionality.

Fortunately the framework provides three types of recognizer that greatly simplify the implementation:

  • PinchGestureRecognizer allows user interactions for zoom / scale functionalities;
  • PanGestureRecognizer enables pan / translate transformations;
  • TapGestureRecognizer detects tap events.

Yesterday I decided to try the PanGestureRecognizer for extending the capabilities of the Behavior described in the previous post.

First of all, I added two Bindable properties in order to permit activation / deactivation of individual gestures (Bindable properties are equivalent to Dependency ones in UWP XAML)

In this way we can specify in our XAML what gestures are enabled:

Then I initialised the GestureRecognizers adding a new PanGestureRecognizer to the recognizers list:

And subscribed to the PanUpdated event in order to apply the translate transform:

The implementation of this event handler permits to update the X and Y coordinates of the element when a Pan gesture is detected:

Here we go: the sample app can now be deployed to the emulators and iOS / Android / Windows devices.

Just a couple of notes:

  • deployment to iOS required this workaround to work properly since the new sample app uses different assemblies;
  • Tap gestures on Android requires Xamarin.Forms – minimum version v2.1.0.6501-pre1 as pointed by the official documentation.

As usual, the latest source code is available for download on GitHub.

Having fun with Xamarin.Forms and Multi-Touch Behaviors

Recently Xamarin has released preview support for the Universal Windows Platform in their Xamarin.Forms framework so I have been playing around with version 2.0 for testing its features and verify how easy is to target multiple platforms (iOS, Android, Windows 10 UWP, Windows Phone, Windows 8.1) with a single codebase.

One of the experiments I have done is related to custom multi-touch gestures: the idea to use a XAML Behavior is a common scenario to write well structured code so I started creating a new Cross-Platform Xamarin.Forms Portable project and upgraded the NuGet packages to the latest stable version of the framework (currently v2.0.1.6505).

I have then read the official documentation and analysed the samples available on GitHub: a very good example is the PinchGesture one so, starting from it, I created a new MultiTouchBehavior implementing this gesture and attached the same Behavior to an Image object added to a sample ContentPage, as described below in this lovely cross-platform XAML 🙂

The BindingContext=”{Binding}” is used to trigger the BindingContextChanged event and initialise correctly the GestureRecognizers  for the parent object since the AssociatedObject.Parent is set to null when the Behavior.OnAttachedTo() is called (I suppose that the XAML tree is not yet completely created when the behavior is attached in Xamarin.Forms):

Here is the project deployed to the Android, iOS and Windows 10 emulators:

MultiTouch_Android_Emulator   Simulator Screen Shot 14 Feb 2016, 18.25.00   MultiTouch_Windows10_Emulator

I’ve been particularly impressed by Xamarin.Forms: the possibility to target so many platforms using the same code is a killer feature and the development environment is also very comfortable to use.

The sample code used in this post is available on GitHub, I’m planning to add more functionalities in the future with particular regard to other common multi-touch gestures using Xamarin.Forms and XAML.