6

I'm trying to set focus to an Entry control when a page loads to automatically trigger the keyboard.

However, while the Entry control receives focus (caret blinking) if done during Loaded event, the keyboard doesn't appear.

If done only in the Appearing event, the caret doesn't even appear.

My page has a single Entry like:

<StackLayout>
    <Entry x:Name="RoundsEntry" Keyboard="Numeric" />
</StackLayout>

In the code-behind, I'm setting focus during the Loaded event:

public RoundsPage()
{
    InitializeComponent();

    Loaded += RoundsPage_Loaded;

    // For Shell navigation, the Appearing event makes more sense, 
    // as page is only loaded once, but we want the Entry control 
    // to receive focus every time the user returns to the page.
    Appearing += RoundsPage_Loaded;
}

private void RoundsPage_Loaded(object? sender, EventArgs e)
{
    RoundsEntry.Focus();
}

Manually tapping the Entry control (even though it already has focus) does trigger the keyboard.

Am I missing something, or is there some other option to programmatically trigger (and later hide) the keyboard?

(Tested on Android.)

Edit: seems related to this issue on GitHub, so I think I'm looking for a viable workaround until it's fixed.

Ted Nyberg
  • 7,001
  • 7
  • 41
  • 72

2 Answers2

4

I think it's a question or a bug of which piece of version. Such as Visual Studio, .NET ...

Here is the code:

public partial class MainPage : ContentPage
{
    
    public MainPage()
    {
        InitializeComponent();
        Loaded += MainPage_Loaded;
    }

   private void MainPage_Loaded(object sender, EventArgs e)
    {
        entry.Focus();
    }
}
<VerticalStackLayout>        
    <Entry x:Name="entry" Keyboard="Numeric"/>    
</VerticalStackLayout>

VS: Community 2022 (64-bit) 17.3.4 --- .NET:6.0 --- Android: API 32

This is my screen recording

Rafael
  • 1,281
  • 2
  • 10
  • 35
Jianwei Sun - MSFT
  • 2,289
  • 1
  • 3
  • 7
  • Thanks for testing! Does the keyboard also disappear when invoking `Unfocus()`? For example if you, after a delay of say 2 seconds, call `entry.Unfocus()` or shift the focus to some other element? You could also try adding another `Entry` element (with a different `Keyboard` property value) to your XAML and switch focus programmatically between them to see if the correct keyboard appears. – Ted Nyberg Oct 18 '22 at 08:13
  • 1
    @TedNyberg Keyboard can't disappear when invoking `Unfocus()`, unless click `Esc`, I think there are some logics I didn't expect required code implementation. In addition, switching focus programmatically between different `Entry` is ok. [video](https://imgur.com/a/VOajyWO) – Jianwei Sun - MSFT Oct 18 '22 at 09:18
  • Please accept it ✅ as an answer if it's helpful to others facing the same problem. Thanks in advance! – Jianwei Sun - MSFT Oct 20 '22 at 05:23
  • Regrettably it's not a solution, it's still a verified bug. Also, doing this during `Appearing` ignores the focus completely (not even a caret in the textbox). I clarified this in OP. – Ted Nyberg Oct 20 '22 at 06:58
  • 2
    I tested `Appearing` before, and it doesn't work the same as [the issue on github](https://github.com/dotnet/maui/issues/5983) indeed. – Jianwei Sun - MSFT Oct 20 '22 at 07:11
  • this solution did not work for me – Eyner Mamani Jan 03 '23 at 04:50
  • this is very outrageous that to date it still does not work – Eyner Mamani Jan 06 '23 at 02:53
  • @TedNyberg To hide the keyboard and unfocus, I wrote a static function like below, maybe will be useful for someone else: public static class Helpers { public static void HideKeyboard(bool Unfocus = true) { #if ANDROID if (Platform.CurrentActivity.CurrentFocus != null) { Platform.CurrentActivity.HideKeyboard(Platform.CurrentActivity.CurrentFocus); if (Unfocus) Platform.CurrentActivity.CurrentFocus.ClearFocus(); } #endif } } – Ozan Yasin Dogan Jan 20 '23 at 22:19
3

This was bugging me for a while now.

It seems the Loaded event is too soon to be setting focus. i couldn't find another event after 'loaded' so the dirty work around that worked for me is building in a slight delay.

public partial class MainPage: ContentPage {
  public MainPage() {
    InitializeComponent();
    Loaded += MainPage_Loaded;
  }

  private void MainPage_Loaded(object sender, EventArgs e) {
    _ = Task.Delay(200).ContinueWith(t =>{
      entry.Focus();
    });
  }
}
Rafael
  • 1,281
  • 2
  • 10
  • 35