Setting the Focus to an Entry in Xamarin.Forms

Just inside OnAppearing(), add the following code,

protected async override void OnAppearing()
{
    await Task.Run(async () =>
    {
        await Task.Delay(100);
        Device.BeginInvokeOnMainThread(async () =>
        {
            txtName.Focus();
        });
    });
}

Note: txtName is the reference name of your Entry Field.


In one of my projects I did something like this. Please try the following example:

public class EntryFocusBehavior : Behavior<Entry>
{
    public string NextFocusElementName { get; set; }

    protected override void OnAttachedTo(Entry bindable)
    {
        base.OnAttachedTo(bindable);
        bindable.Completed += Bindable_Completed;
    }

    protected override void OnDetachingFrom(Entry bindable)
    {
        bindable.Completed -= Bindable_Completed;
        base.OnDetachingFrom(bindable);
    }

    private void Bindable_Completed(object sender, EventArgs e)
    {
        if (string.IsNullOrEmpty(NextFocusElementName))
            return;

        var parent = ((Entry)sender).Parent;
        while (parent != null)
        {
            var nextFocusElement = parent.FindByName<Entry>(NextFocusElementName);
            if (nextFocusElement != null)
            {
                nextFocusElement.Focus();
                break;
            }
            else
            {
                parent = parent.Parent;
            }
        }
    }
}

And then XAML: XAML Code

!!! Please let me know if I made a mistake in the code.


Use the Focus method

nameentry.Focus();

If you want the focus to be set when your page appears, you should probably do this in the OnAppearing method

    protected override void OnAppearing ()
    {
        base.OnAppearing ();

        nameentry.Focus();
    }

Focus() needs to have a visible page and visible control to focus on.

The issue in my case was that is is necessary that OnAppearing has to exit before a page is shown / visible. What helped in my case is to wait for page visibility in a different thread and then set the focus in the main (UI) thread:

protected override void OnAppearing()
        {
            base.OnAppearing();

            Task.Run(() =>
            {
                while (!IsVisible)
                {
                    Debug.WriteLine("Page not visible, waiting...");
                    Task.Delay(50).Wait();
                }

                Device.BeginInvokeOnMainThread(() =>
                {
                    bool gotFocus = Entry.Focus();
                    if (!gotFocus)
                        Debug.WriteLine("Could not set focus.");
                });
            });
        }

Tags:

C#

Focus

Xamarin