Search code examples
xamarinxamarin.formscustom-renderer

Auto focus entry when it is visible or enabled in xamarin forms using custom renderers


I have a page where i display a list of items in a listview which has a footer. The footer of the listview is visible only in certain conditions. Here is the listview footer which has an entry.

<listview:SfListView.FooterTemplate>
    <DataTemplate>
        <Grid Padding="15,5,10,10" IsVisible="{Binding NewListEntryVisible}">
            <Grid.RowDefinitions>
                <RowDefinition Height="50"/>
            </Grid.RowDefinitions>    
            <local:AutoFocusEntry ReturnType="Done" IsVisible="{Binding NewListEntryVisible}" Grid.Row="0" IsEnabled="{Binding FocusEntry}" Text="{Binding cartName}" x:Name="NewListEntry" Placeholder="Enter list name">
                <local:AutoFocusEntry.Behaviors>
                    <behaviors:EventToCommandBehavior                    
                        EventName="Completed"
                        Command="{Binding NewListCommand}" />
                </local:AutoFocusEntry.Behaviors>
            </local:AutoFocusEntry>    
        </Grid>    
    </DataTemplate>    
</listview:SfListView.FooterTemplate>

As soon as the footer is visible (as I said earlier it is visible based on certain conditions), I want the entry in the footer to get focussed automatically. How can I achieve this using Entry Custom Renderer.

Thanks in advance.


Solution

  • Solved my issue by calling method for getting focus on custom renderers

    Custom Entry:

    public class AutoFocusEntry : Entry
        {
            public AutoFocusEntry()
            {
            }
        }
    }
    

    CustomRenderer in Android:

    [assembly: ExportRenderer(typeof(AutoFocusEntry), typeof(AutoFocusEntryRenderer))]
    namespace Test.Mobile.Droid.CustomRenderers
    {
        public class AutoFocusEntryRenderer : EntryRenderer
        {
            public AutoFocusEntryRenderer(Context context) : base(context)
            {
            }
    
            protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                base.OnElementPropertyChanged(sender, e);
    
                MocoAutoFocusEntry entry = (MocoAutoFocusEntry)this.Element;
    
                if (this.Control != null && e.PropertyName == "IsVisible")
                {
                    if (entry != null && entry.IsVisible)
                    {
                        Control.RequestFocus();
                        InputMethodManager inputMethodManager = this.Control.Context.GetSystemService(Android.Content.Context.InputMethodService) as InputMethodManager;
                        inputMethodManager.ShowSoftInput(this.Control, ShowFlags.Forced);
                        inputMethodManager.ToggleSoftInput(ShowFlags.Forced, HideSoftInputFlags.ImplicitOnly);
                    }
                }
            }
        }
    }
    

    CustomRenderer in iOS:

    [assembly: ExportRenderer(typeof(AutoFocusEntry), typeof(AutoFocusEntryRenderer))]
    namespace Test.Mobile.iOS.CustomRenderers
    {
        public class AutoFocusEntryRenderer : EntryRenderer
        {
            public AutoFocusEntryRenderer()
            {
            }
    
            protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                base.OnElementPropertyChanged(sender, e);
    
                MocoAutoFocusEntry entry = (MocoAutoFocusEntry)this.Element;
    
                if (this.Control != null && e.PropertyName == "IsEnabled")
                {
                    if (entry != null && entry.IsVisible)
                    {
                        Control.BecomeFirstResponder();
                    }
                }
    
                if (this.Control != null && e.PropertyName == "IsVisible")
                {
                    if (entry != null && entry.IsVisible)
                    {
                        Control.BecomeFirstResponder();
                    }
                }
            }
        }
    }
    

    Based on the PropertyName (IsVisible & IsEnabled), I get the focus on the entry