A mask on an entry field is way to format the input into something more human readable. For example, a phone number may look like +61 400 555 555, or (555) 555-555. There are many ways to implement a mask. For maximum configurability, you would use Regex, however for most simple cases, we can implement something much easier.
Behavior
The easiest way to implement a mask, is through a Behavior. This code will set the char positions that each mask character is meant to be located at. For example, in this code, we will choose X as our special character. Hence a mask of (XXX) XXX-XXX, will mean that spaces, brackets and dashes will all be included as part of the non-user typed entry.
public class MaskedBehavior : Behavior<Entry> { private string _mask = ""; public string Mask { get => _mask; set { _mask = value; SetPositions(); } } protected override void OnAttachedTo(Entry entry) { entry.TextChanged += OnEntryTextChanged; base.OnAttachedTo(entry); } protected override void OnDetachingFrom(Entry entry) { entry.TextChanged -= OnEntryTextChanged; base.OnDetachingFrom(entry); } IDictionary<int, char> _positions; void SetPositions() { if (string.IsNullOrEmpty(Mask)) { _positions = null; return; } var list = new Dictionary<int, char>(); for (var i = 0; i < Mask.Length; i++) if (Mask[i] != 'X') list.Add(i, Mask[i]); _positions = list; } private void OnEntryTextChanged(object sender, TextChangedEventArgs args) { var entry = sender as Entry; var text = entry.Text; if (string.IsNullOrWhiteSpace(text) || _positions == null) return; if (text.Length > _mask.Length) { entry.Text = text.Remove(text.Length - 1); return; } foreach (var position in _positions) if (text.Length >= position.Key + 1) { var value = position.Value.ToString(); if (text.Substring(position.Key, 1) != value) text = text.Insert(position.Key, value); } if (entry.Text != text) entry.Text = text; } }
This code, will also limit the amount of text you can enter, up to the mask.
Apply Mask
Now you want to apply your mask to an Entry element. Here I have added the MaskedBehavior, and added a mask of (XXX) XXX-XXX.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:behavior="clr-namespace:Enterprise.Behaviors" x:Class="Enterprise.View.Features.Main.MainView"> <ContentPage.Content> <StackLayout VerticalOptions="Center"> <Entry Keyboard="Numeric"> <Entry.Behaviors> <behavior:MaskedBehavior Mask="(XXX) XXX-XXX" /> </Entry.Behaviors> </Entry> </StackLayout> </ContentPage.Content> </ContentPage>
The mask can be anything you want, with the X as the character that the user types in.
Demonstration
Here you can see the entry of a phone number, and it automatically applies the mask, as they type.
Summary
To be a truly generic masked behavior, we would need to implement regex. Regex, while powerful can be difficult to understand, for many programmers perspectives, hence I like this masked behavior, to clearly indicate what you want. You can easily expand this behavior to include additional checks such as if it is a digit.
Cross platform mobile developer who loves delving deep into frameworks and solving problems.