Handling Fields and Validating Behaviors in Xamarin Forms

When I started playing with Xamarin Forms I quickly found that I would have alot of properties in my class simply pointing towards Fields, and the fields’ behavior validators (the things that validate inputs, and potentially highlight invalid input.)

Exasperated at having two class members for each input, like so:

private Entry EmailField;
private EmailValidatorBehavior EmailValidator;

I wrote an ultra-simple wrapper that contains both the field and a property for validating its behaviors. Then I had each validator behavior (I have behaviors for passwords, emails, names, etc…) implement an interface saying that it supports an “IsValid” property.

The result is a quick way to validate each of your inputs (even if they have multiple behaviors/input) without polluting your class, or iterating over behaviors every time you want to check them.

Use it like this:

public class InputPage : ContentPage
	private BehaviorValidatedInput<Entry> EmailField = new BehaviorValidatedInput<Entry>();

	public InputPage() {
		Content = new StackLayout
		{
			Children =
			{
				(EmailField.Element = new Entry { 
					Placeholder = "Email", 
					Keyboard = Keyboard.Email,
					Behaviors = { new EmailValidatorBehavior() }}),
				/* Other form elements... */
			}
		};
	}

	public OnSubmit() {
		if (!EmailField.IsValid) {
			// Handle invalid input
		}

		Console.WriteLine("The user entered: {0}", EmailField.Element.Text);
	}
}

The two classes are below, or available in this GitHub Gist


using System;
using Xamarin.Forms;

namespace Behaviours
{
	public class BehaviorValidatedInput<T>; where T : InputView
	{
		public T Element { get; set; }

		public bool IsValid 
		{
			get {
				foreach (var b in Element.Behaviors)
				{
					if (b is IValidatorBehavior && !((IValidatorBehavior)b).IsValid)
					{
						return false;
					}
				}

				return true;
			}
		}
	}
}


namespace Behaviours
{
	public interface IValidatorBehavior
	{
		bool IsValid { get; set; }
	}
}

 

, , , , ,

No comments yet.

Leave a Reply

Proudly made in Canada