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 { public static PhoneNumberMaskBehavior Instance = new PhoneNumberMaskBehavior(); /// /// Attaches when the page is first created. /// protected override void OnAttachedTo(Entry entry) { entry.TextChanged += OnEntryTextChanged; base.OnAttachedTo(entry); } /// /// Detaches when the page is destroyed. /// 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:PhoneValidatorBehavior x:Name="PhoneMask" /> <behaviors:EntryLengthValidatorBehavior MaxLength="12" /> </Entry.Behaviors> </Entry> </AbsoluteLayout>
The end result would look like so:
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!