XamaWIN – Phone Number Mask Behavior

Xamawin • zam-ah win | noun
A quick, easy to implement enhancement for a Xamarin App that improves performance, appearance, or functionality


Behaviors are super easy to make and offer a lot of bang for your buck – I recently wrote how to highlight incomplete fields on an entry while a user completes a form. Let’s expand upon that concept and do some field masking, like one might use for a phone number entry. We want to ensure the end result conforms to the format XXX-XXX-XXXX, so we need to consider placement of the dashes and the full minimum and maximum length of the field. Since our length validator will handle the latter, we only need to worry about the format

	public class PhoneNumberMaskBehavior : Behavior<Entry>
	{
		public static PhoneNumberMaskBehavior Instance = new PhoneNumberMaskBehavior();

		/// <summary>
		/// Attaches when the page is first created.
		/// </summary>

		protected override void OnAttachedTo(Entry entry)
		{
			entry.TextChanged += OnEntryTextChanged;
			base.OnAttachedTo(entry);
		}

		/// <summary>
		/// Detaches when the page is destroyed.
		/// </summary>

		protected override void OnDetachingFrom(Entry entry)
		{
			entry.TextChanged -= OnEntryTextChanged;
			base.OnDetachingFrom(entry);
		}

		private void OnEntryTextChanged(object sender, TextChangedEventArgs args)
		{
			if (!string.IsNullOrWhiteSpace(args.NewTextValue))
			{
                // If the new value is longer than the old value, the user is
                if (args.OldTextValue != null && args.NewTextValue.Length < args.OldTextValue.Length)
                    return;

				var value = args.NewTextValue;

				if (value.Length == 3)
				{
					((Entry)sender).Text += "-";
					return;
				}

				if (value.Length == 7)
				{
					((Entry)sender).Text += "-";
					return;
				}

				((Entry)sender).Text = args.NewTextValue;
			}
		}
	}

Let’s see what the xaml should look like: we want to stack this masking behavior with our entry length validator from earlier and ensure the user uses the numeric keyboard. Note, we could get even more robust here and add another behavior (or just expand on this one) to ensure the user is respecting our numeric requirement, but we’ll leave that as an exercise for another day 🤔.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:behaviors="clr-namespace:Sandbox.Behaviors"
<!-- More stuff -->
            <AbsoluteLayout>
                <Label Text="Phone:" AbsoluteLayout.LayoutBounds="0,20,.3,40" AbsoluteLayout.LayoutFlags="WidthProportional" />
                <Entry Text="{Binding Phone}" AbsoluteLayout.LayoutBounds="1,10,.75,40" AbsoluteLayout.LayoutFlags="XProportional,WidthProportional" Keyboard="Telephone">
                    <Entry.Behaviors>
                        <behaviors:PhoneNumberMaskBehavior x:Name="PhoneMask" />
                        <behaviors:EntryLengthValidatorBehavior MinLength="12" MaxLength="12" />
                    </Entry.Behaviors>
                </Entry>
            </AbsoluteLayout>

The end result would look like so:

Aug-28-2017 16-42-16

This only handles US-style phone number, but we could modify or extend it to handle different regions. This is a simple example, so feel free to share any improvements/suggestions you may have.

Enjoy!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s