Feature Image

How to focus on another field when user presses Return in a Xamarin Forms app

How to focus on another field when user presses Return in a Xamarin Forms app

Whilst most people are familiar with the concept of pressing the tab key to allow users to move between fields on a Desktop or Web form, the same isn't as true for mobile devices. A more useable flow for mobile users is to jump to the next field when they press Return on the keyboard.

In Xamarin Forms, TabIndex is supported, but is only really useful for devices connected to a keyboard. For those more conventional touch devices, we need a different approach...Behaviors.

Sample source code

Using a custom behavior we can subscribe to an Entry's Completed event and assign focus to a new VisualElement.

The Behavior code:

public class SetFocusOnEntryCompletedBehavior : Behavior
{
    public static readonly BindableProperty TargetElementProperty
       = BindableProperty.Create(nameof(TargetElement), typeof(VisualElement), typeof(SetFocusOnEntryCompletedBehavior));

    public VisualElement TargetElement
    {
        get => (VisualElement)GetValue(TargetElementProperty);
        set => SetValue(TargetElementProperty, value);
    }
        
    protected override void OnAttachedTo(BindableObject bindable)
    {
        base.OnAttachedTo(bindable);
        
        if (bindable is Entry entry)
            entry.Completed += Entry_Completed;
    }

    protected override void OnDetachingFrom(BindableObject bindable)
    {
        if (bindable is Entry entry)
            entry.Completed -= Entry_Completed;

        base.OnDetachingFrom(bindable);
    }

    private void Entry_Completed(object sender, EventArgs e)
    {
        TargetElement?.Focus();
    }
}

We create a BindableProperty called TargetElement, this will hold a reference to the Element we want to focus on next when Return is pressed. Then, when the behavior is attached to its parent Entry, we hook up the Entry's Completed event and invoke the Focus() method when it's fired, remembering to detach the event when we're done.

The implementation

<ContentPage x:Class="NextFormFieldSample.Forms.MainPage"
             xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:behaviors="clr-namespace:NextFormFieldSample.Forms.Behaviors">
    <StackLayout Margin="20">   
        
        <Entry Placeholder="Field 1">
            <Entry.Behaviors>
                <behaviors:SetFocusOnEntryCompletedBehavior TargetElement="{x:Reference Entry2}" />
            </Entry.Behaviors>
        </Entry>

        <Entry x:Name="Entry2" Placeholder="Field 2"/>  
        
    </StackLayout>
</ContentPage>

This adds the behavior to listen to the Return key being pressed when the user is focused on the first Entry. The behavior's TargetElement property is set using {x:Reference} and uses the x:Name assigned to the second Entry as the reference point.

Now, when a user taps the Return key on their keyboard whilst in the first entry, the app will automatically move the cursor to the second field.

View the code within a sample app over on my GitHub.