Input Validation In Xamarin Forms Behaviors

Introduction

Xamarin.Forms Behaviors are created by deriving from the Behavior or Behavior<T> class, where T is the type of the control (Entry, DateTime, etc) to which the Behavior should apply.

In this article, I will demonstrate how to create and consume Xamarin.Forms Behaviors and input validation, using Xamarin Forms Behaviors.

Why Do We Need Behaviors?

Normally, we will write the validation code into the code at the backend because it directly interacts with API of the control, so that we can create Behaviors and reuse them into the different controls. They can be used to provide a full range of the functionality to the controls, as shown below-

  • Number validation
  • Date validation
  • Email validation \
  • Password validation
  • Compare validation

Building and Running the Application

To create Xamarin.Forms Behaviors Application, follow the steps, given below- 

Step 1 - Create new Xamarin Form Application

Let's start with creating a new Xamarin Forms Project in Visual Studio.

Open Run - Type Devenev.Exe and enter - New Project (Ctrl+Shift+N) - select Blank Xaml app (Xamarin.Forms Portable) template.



You can find my previous article for more ways to create new Xamarin.Form Application here.

Step 2 – Create new class and inherit from the Behavior

Create a new class and it inherits from the Behavior or Behavior<T> class. We can add the behavior to any control, so you can specify your control name instead of T.



Step 3 –Override Behavior class method

We need to override OnAttachedTo and OnDetachingFrom method from our validation class.



The OnAttachedTo method is fired immediately after the behavior is attached to a control. This can be used to register event handlers or perform other setup that's required to support the behavior functionality.

The OnDetachingFrom method is fired when the behavior is removed from the control. This method receives a reference to the control to which it is attached, and is used to perform any required cleanup.

Step 4 –Validation Behavior Class

  1. PasswordValidationBehavior

    The code, given below is Password validation Behaviors. Password rule should contain at least 8 characters, 1 numeric, 1 lowercase, 1 uppercase, 1 special character [eg: No1C#cornar]

    The Password validation Behavior is added into Entry control. We can re-use this Behavior to Entry control.
    1. using System.Text.RegularExpressions;  
    2. using Xamarin.Forms;  
    3.   
    4. namespace DevenvExeBehaviors  
    5. {  
    6.     public class PasswordValidationBehavior : Behavior<Entry>  
    7.     {  
    8.         const string passwordRegex = @"^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,}$";  
    9.   
    10.   
    11.         protected override void OnAttachedTo(Entry bindable)  
    12.         {  
    13.             bindable.TextChanged += HandleTextChanged;  
    14.             base.OnAttachedTo(bindable);  
    15.         }  
    16.   
    17.         void HandleTextChanged(object sender, TextChangedEventArgs e)  
    18.         {  
    19.             bool IsValid = false;  
    20.             IsValid = (Regex.IsMatch(e.NewTextValue, passwordRegex));  
    21.             ((Entry)sender).TextColor = IsValid ? Color.Default : Color.Red;  
    22.         }  
    23.   
    24.         protected override void OnDetachingFrom(Entry bindable)  
    25.         {  
    26.             bindable.TextChanged -= HandleTextChanged;  
    27.             base.OnDetachingFrom(bindable);  
    28.         }  
    29.     }  
    30. }  
  2. Date Validation Behaviors

    The code, given below, is Date of birth validation Behaviors. I used a DatePicker and restricted the max date to be 100 years from the current day and min date to be one.

    The DOB validation Behavior is added into DatePicker control. We can re-use this Behavior to Date Picker control.
    1. using System;  
    2. using Xamarin.Forms;  
    3. namespace DevenvExeBehaviors  
    4. {  
    5.     class DateValidationBehavior : Behavior<DatePicker>  
    6.     {  
    7.         protected override void OnAttachedTo(DatePicker datepicker)  
    8.         {  
    9.             datepicker.DateSelected += Datepicker_DateSelected;  
    10.             base.OnAttachedTo(datepicker);  
    11.         }  
    12.   
    13.         private void Datepicker_DateSelected(object sender, DateChangedEventArgs e)  
    14.         {  
    15.             DateTime value = e.NewDate;  
    16.             int year = DateTime.Now.Year;  
    17.             int selyear = value.Year;  
    18.             int result = selyear - year;  
    19.             bool isValid=false;  
    20.             if(result <=100 && result >0)  
    21.             {  
    22.                 isValid = true;  
    23.             }  
    24.            ((DatePicker)sender).BackgroundColor = isValid ? Color.Default : Color.Red;  
    25.         }  
    26.   
    27.         protected override void OnDetachingFrom(DatePicker datepicker)  
    28.         {  
    29.             datepicker.DateSelected -= Datepicker_DateSelected;  
    30.             base.OnDetachingFrom(datepicker);  
    31.         }  
    32.   
    33.       
    34.     }  
    35. }  
  3. EmailValidation Behaviors

    The code, given below, is Email validation Behaviors. Email validation Behavior is added into Entry control. We can re-use this Behavior to Entry control.
    1. using System;  
    2. using System.Text.RegularExpressions;  
    3. using Xamarin.Forms;  
    4.   
    5. namespace DevenvExeBehaviors  
    6. {  
    7.     public class EmailValidatorBehavior : Behavior<Entry>  
    8.     {  
    9.         const string emailRegex = @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" +  
    10.             @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$";  
    11.   
    12.   
    13.         protected override void OnAttachedTo(Entry bindable)  
    14.         {  
    15.             bindable.TextChanged += HandleTextChanged;  
    16.             base.OnAttachedTo(bindable);  
    17.         }  
    18.   
    19.         void HandleTextChanged(object sender, TextChangedEventArgs e)  
    20.         {  
    21.             bool IsValid = false;  
    22.             IsValid = (Regex.IsMatch(e.NewTextValue, emailRegex, RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250)));  
    23.             ((Entry)sender).TextColor = IsValid ? Color.Default : Color.Red;  
    24.         }  
    25.   
    26.         protected override void OnDetachingFrom(Entry bindable)  
    27.         {  
    28.             bindable.TextChanged -= HandleTextChanged;  
    29.             base.OnDetachingFrom(bindable);  
    30.         }  
    31.     }  
    32. }  
  4. Number Validation

    The code, given below, is Number validation Behaviors. The Entry box will allow only the numeric value.
    1. using Xamarin.Forms;  
    2.   
    3. namespace DevenvExeBehaviors  
    4. {  
    5.     public class NumberValidationBehavior : Behavior<Entry>  
    6.     {  
    7.         protected override void OnAttachedTo(Entry entry)  
    8.         {  
    9.             entry.TextChanged += OnEntryTextChanged;  
    10.             base.OnAttachedTo(entry);  
    11.         }  
    12.   
    13.         protected override void OnDetachingFrom(Entry entry)  
    14.         {  
    15.             entry.TextChanged -= OnEntryTextChanged;  
    16.             base.OnDetachingFrom(entry);  
    17.         }  
    18.   
    19.         void OnEntryTextChanged(object sender, TextChangedEventArgs args)  
    20.         {  
    21.             int result;  
    22.              
    23.             bool isValid = int.TryParse(args.NewTextValue, out result);  
    24.   
    25.             ((Entry)sender).TextColor = isValid ? Color.Default : Color.Red;  
    26.         }  
    27.     }  
    28. }  

Step 5 – Behaviors with Parameter

You can create multiple properties in behaviors class and assign the value in XAML controls.

  1. Max length Behaviors

    You can restrict the number of characters in the Entry field, as given below-
    1. using Xamarin.Forms;  
    2.   
    3. namespace DevenvExeBehaviors  
    4. {  
    5.     public class MaxLengthValidatorBehavior : Behavior<Entry>  
    6.     {  
    7.          public static readonly BindableProperty MaxLengthProperty = BindableProperty.Create("MaxLength"typeof(int), typeof(MaxLengthValidatorBehavior), 0);  
    8.   
    9.         public int MaxLength  
    10.         {  
    11.             get { return (int)GetValue(MaxLengthProperty); }  
    12.             set { SetValue(MaxLengthProperty, value); }  
    13.         }  
    14.   
    15.         protected override void OnAttachedTo(Entry bindable)  
    16.         {  
    17.             bindable.TextChanged += bindable_TextChanged;  
    18.         }  
    19.   
    20.         private void bindable_TextChanged(object sender, TextChangedEventArgs e)  
    21.         {  
    22.                   if (e.NewTextValue.Length >= MaxLength)  
    23.                     ((Entry)sender).Text = e.NewTextValue.Substring(0, MaxLength);                    }  
    24.   
    25.         protected override void OnDetachingFrom(Entry bindable)  
    26.         {  
    27.             bindable.TextChanged -= bindable_TextChanged;  
    28.   
    29.         }  
    30.     }  
    31. }  
  2. Compare Validation

    CompareValidator control allows you to compare the value entered by the user into an input control, such as an Entry control with the value entered into another Entry control.
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5. using System.Text.RegularExpressions;  
    6. using System.Threading.Tasks;  
    7. using Xamarin.Forms;  
    8.   
    9. namespace DevenvExeBehaviors  
    10. {  
    11.       
    12.     public class CompareValidationBehavior : Behavior<Entry>  
    13.     {  
    14.          
    15.         public static BindableProperty TextProperty = BindableProperty.Create<CompareValidationBehavior, string>(tc => tc.Text, string.Empty, BindingMode.TwoWay);  
    16.   
    17.         public string Text  
    18.         {  
    19.             get  
    20.             {  
    21.                 return (string)GetValue(TextProperty);  
    22.             }  
    23.             set  
    24.             {  
    25.                 SetValue(TextProperty, value);  
    26.             }  
    27.         }  
    28.   
    29.          
    30.         protected override void OnAttachedTo(Entry bindable)  
    31.         {  
    32.             bindable.TextChanged += HandleTextChanged;  
    33.             base.OnAttachedTo(bindable);  
    34.         }  
    35.   
    36.         void HandleTextChanged(object sender, TextChangedEventArgs e)  
    37.         {  
    38.             bool IsValid = false;  
    39.             IsValid =  e.NewTextValue ==Text;  
    40.              
    41.             ((Entry)sender).TextColor = IsValid ? Color.Default : Color.Red;  
    42.         }  
    43.   
    44.         protected override void OnDetachingFrom(Entry bindable)  
    45.         {  
    46.             bindable.TextChanged -= HandleTextChanged;  
    47.             base.OnDetachingFrom(bindable);  
    48.         }  
    49.     }  
    50. }  

Step 6 – Add Behaviors into Control

Refer to the XAML code, given below, to add behaviors into entry box, as given below-

  1. <Entry x:Name="txtpassword" IsPassword="True" Placeholder="Enter Your Password" >  
  2.       <Entry.Behaviors>  
  3.         <local:PasswordValidationBehavior />  
  4.       </Entry.Behaviors>  
  5.     </Entry>  
Step 7 – Add Multiple Behaviors into Control

Refer to the code, given below, to attach multiple behaviors into single entry box and pass the parameter value, as given below-
  1. <Entry IsPassword="True" Placeholder="Enter same as above" >  
  2.       <Entry.Behaviors>  
  3.         <local:PasswordValidationBehavior />  
  4.         <local:CompareValidationBehavior BindingContext="{x:Reference txtpassword}" Text="{Binding Text}"/>  
  5.       </Entry.Behaviors>  
  6.     </Entry>  
Step 8 - UI Design

You can refer to the UI Design for all control and Behaviors Design, as given below-
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
  4.              xmlns:local="clr-namespace:DevenvExeBehaviors"  
  5.              x:Class="DevenvExeBehaviors.MainPage" >  
  6.   <StackLayout Padding="0,20,0,0">  
  7.   
  8.     <Label Text="Name" FontSize="Small" />  
  9.     <Entry Placeholder="Enter Your Name" />  
  10.     <Label Text="Age" FontSize="Small" />  
  11.     <Entry Placeholder="Age" FontSize="Small">  
  12.       <Entry.Behaviors>  
  13.         <local:MaxLengthValidatorBehavior  MaxLength="2"/>  
  14.         <local:NumberValidationBehavior/>  
  15.       </Entry.Behaviors>  
  16.     </Entry>  
  17.   
  18.     <Label Text="DOB" FontSize="Small" />  
  19.     <DatePicker >  
  20.       <DatePicker.Behaviors>  
  21.         <local:DateValidationBehavior/>  
  22.       </DatePicker.Behaviors>  
  23.     </DatePicker>  
  24.   
  25.     <Label Text="Email" FontSize="Small" />  
  26.     <Entry Placeholder="Enter Your Email ID" >  
  27.       <Entry.Behaviors>  
  28.         <local:EmailValidatorBehavior />  
  29.       </Entry.Behaviors>  
  30.     </Entry>  
  31.     <Label Text="Password" FontSize="Small" />  
  32.     <Entry x:Name="txtpassword" IsPassword="True" Placeholder="Enter Your Password" >  
  33.       <Entry.Behaviors>  
  34.         <local:PasswordValidationBehavior />  
  35.       </Entry.Behaviors>  
  36.     </Entry>  
  37.   
  38.     <Label Text="Confirm Password" FontSize="Small" />  
  39.     <Entry IsPassword="True" Placeholder="Enter same as above" >  
  40.       <Entry.Behaviors>  
  41.         <local:PasswordValidationBehavior />  
  42.         <local:CompareValidationBehavior BindingContext="{x:Reference txtpassword}" Text="{Binding Text}"/>  
  43.       </Entry.Behaviors>  
  44.     </Entry>  
  45.     <Label Text="Phone Number" FontSize="Small" />  
  46.     <Entry  Placeholder="Enter 10 digit phone number" >  
  47.       <Entry.Behaviors>  
  48.         <local:MaxLengthValidatorBehavior  MaxLength="10"/>  
  49.         <local:NumberValidationBehavior />  
  50.       </Entry.Behaviors>  
  51.     </Entry>  
  52.   </StackLayout>  
  53.   
  54. </ContentPage>  
You can download the sample source code and run the Application.