Keep the keyboard always on in a page in Xamarin forms.

Isayas 1 Reputation point
2021-02-02T20:30:20.463+00:00

I am developing a phone dialler-like functionality. I want the keyboard to be always visible on the page instead of getting hidden when the entry loses focus. How can I achieve this in Xamarin forms?

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,366 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 77,256 Reputation points Microsoft Vendor
    2021-02-03T03:09:07.463+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    I am developing a phone dialler-like functionality. I want the keyboard to be always visible on the page instead of getting hidden when the entry loses focus.

    You do not need to achieve the system's keyboard always on, just achieve a custom keboard like following code.

       <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"   
                    xmlns:local="clr-namespace:App32"  
                    x:Class="App32.Page2">  
           <ContentPage.Content>  
               <StackLayout>  
                   <Grid HorizontalOptions="Center"  
                 VerticalOptions="Center">  
                       <Grid.BindingContext>  
                           <local:KeypadViewModel />  
                       </Grid.BindingContext>  
         
                       <Grid.RowDefinitions>  
                           <RowDefinition Height="Auto" />  
                           <RowDefinition Height="Auto" />  
                           <RowDefinition Height="Auto" />  
                           <RowDefinition Height="Auto" />  
                           <RowDefinition Height="Auto" />  
                       </Grid.RowDefinitions>  
         
                       <Grid.ColumnDefinitions>  
                           <ColumnDefinition Width="80" />  
                           <ColumnDefinition Width="80" />  
                           <ColumnDefinition Width="80" />  
                       </Grid.ColumnDefinitions>  
         
                       <!-- Internal Grid for top row of items -->  
                       <Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3">  
                           <Grid.ColumnDefinitions>  
                               <ColumnDefinition Width="*" />  
                               <ColumnDefinition Width="Auto" />  
                           </Grid.ColumnDefinitions>  
         
                           <Frame Grid.Column="0"  
                              >  
                               <Label Text="{Binding DisplayText}" />  
                           </Frame>  
         
                           <Button Text="&#x21E6;"  
                           Command="{Binding DeleteCharCommand}"  
                           Grid.Column="1"  
                           BorderWidth="0" />  
                       </Grid>  
         
                       <Button Text="1"  
                       Command="{Binding AddCharCommand}"  
                       CommandParameter="1"  
                       Grid.Row="1" Grid.Column="0" />  
         
                       <Button Text="2"  
                       Command="{Binding AddCharCommand}"  
                       CommandParameter="2"  
                       Grid.Row="1" Grid.Column="1" />  
         
                       <Button Text="3"  
                       Command="{Binding AddCharCommand}"  
                       CommandParameter="3"  
                       Grid.Row="1" Grid.Column="2" />  
         
                       <Button Text="4"  
                       Command="{Binding AddCharCommand}"  
                       CommandParameter="4"  
                       Grid.Row="2" Grid.Column="0" />  
         
                       <Button Text="5"  
                       Command="{Binding AddCharCommand}"  
                       CommandParameter="5"  
                       Grid.Row="2" Grid.Column="1" />  
         
                       <Button Text="6"  
                       Command="{Binding AddCharCommand}"  
                       CommandParameter="6"  
                       Grid.Row="2" Grid.Column="2" />  
         
                       <Button Text="7"  
                       Command="{Binding AddCharCommand}"  
                       CommandParameter="7"  
                       Grid.Row="3" Grid.Column="0" />  
         
                       <Button Text="8"  
                       Command="{Binding AddCharCommand}"  
                       CommandParameter="8"  
                       Grid.Row="3" Grid.Column="1" />  
         
                       <Button Text="9"  
                       Command="{Binding AddCharCommand}"  
                       CommandParameter="9"  
                       Grid.Row="3" Grid.Column="2" />  
         
                       <Button Text="*"  
                       Command="{Binding AddCharCommand}"  
                       CommandParameter="*"  
                       Grid.Row="4" Grid.Column="0" />  
         
                       <Button Text="0"  
                       Command="{Binding AddCharCommand}"  
                       CommandParameter="0"  
                       Grid.Row="4" Grid.Column="1" />  
         
                       <Button Text="#"  
                       Command="{Binding AddCharCommand}"  
                       CommandParameter="#"  
                       Grid.Row="4" Grid.Column="2" />  
                   </Grid>  
               </StackLayout>  
           </ContentPage.Content>  
       </ContentPage>  
    

    Here is KeypadViewModel.cs

       using System;  
       using System.Collections.Generic;  
       using System.ComponentModel;  
       using System.Text;  
       using System.Windows.Input;  
       using Xamarin.Forms;  
         
       namespace App32  
       {  
           class KeypadViewModel : INotifyPropertyChanged  
           {  
               string inputString = "";  
               string displayText = "";  
               char[] specialChars = { '*', '#' };  
         
               public event PropertyChangedEventHandler PropertyChanged;  
         
               // Constructor  
               public KeypadViewModel()  
               {  
                   AddCharCommand = new Command<string>((key) =>  
                   {  
                       // Add the key to the input string.  
                       InputString += key;  
                   });  
         
                   DeleteCharCommand = new Command(() =>  
                   {  
                       // Strip a character from the input string.  
                       InputString = InputString.Substring(0, InputString.Length - 1);  
                   },  
                       () =>  
                       {  
                           // Return true if there's something to delete.  
                           return InputString.Length > 0;  
                       });  
               }  
         
               // Public properties  
               public string InputString  
               {  
                   protected set  
                   {  
                       if (inputString != value)  
                       {  
                           inputString = value;  
                           OnPropertyChanged("InputString");  
                           DisplayText = FormatText(inputString);  
         
                           // Perhaps the delete button must be enabled/disabled.  
                           ((Command)DeleteCharCommand).ChangeCanExecute();  
                       }  
                   }  
         
                   get { return inputString; }  
               }  
         
               public string DisplayText  
               {  
                   protected set  
                   {  
                       if (displayText != value)  
                       {  
                           displayText = value;  
                           OnPropertyChanged("DisplayText");  
                       }  
                   }  
                   get { return displayText; }  
               }  
         
               // ICommand implementations  
               public ICommand AddCharCommand { protected set; get; }  
         
               public ICommand DeleteCharCommand { protected set; get; }  
         
               string FormatText(string str)  
               {  
                   bool hasNonNumbers = str.IndexOfAny(specialChars) != -1;  
                   string formatted = str;  
         
                   if (hasNonNumbers || str.Length < 4 || str.Length > 10)  
                   {  
                   }  
                   else if (str.Length < 8)  
                   {  
                       formatted = String.Format("{0}-{1}",  
                                                 str.Substring(0, 3),  
                                                 str.Substring(3));  
                   }  
                   else  
                   {  
                       formatted = String.Format("({0}) {1}-{2}",  
                                                 str.Substring(0, 3),  
                                                 str.Substring(3, 3),  
                                                 str.Substring(6));  
                   }  
                   return formatted;  
               }  
         
               protected void OnPropertyChanged(string propertyName)  
               {  
                   PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));  
               }  
           }  
       }  
    

    For iOS running screenshot.

    63206-image.png

    For Android running screenshot.

    63270-image.png

    ===========================
    Update=======================================

    I want to show the TelephoneKeyboard when the entry is focused, but I want the keyboard to be always visible even if the user clicks on other elements on the page. >So, I am basically looking for a way to make the entry to never lose focus, or make the keyboard always visible irrespective of what element is selected on the page. >How could I achieve that?

    If you prefer to make keyboard to be always visible even if the user clicks on other elements on the page. you can try to use following ways. When user click the entry, the keyboard will always show, But I think this way is not elegant, if you want to custom this system's keyboard, that is hard to do it( And you will back to create a custom keyboard like first answer).

    For android, create a custom control for Entry.

       [assembly: ExportRenderer(typeof(Entry), typeof(MyEntryCustomRenderer))]  
       namespace App32.Droid  
       {  
           public class MyEntryCustomRenderer : EntryRenderer  
           {  
               public MyEntryCustomRenderer(Context context) : base(context)  
               {  
               }  
               protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)  
               {  
                   base.OnElementChanged(e);  
         
                
               }  
           }  
       }  
    

    Add following code to MainActivity.cs

       private bool _lieAboutCurrentFocus;  
               public override bool DispatchTouchEvent(MotionEvent ev)  
               {  
                   var focused = CurrentFocus;  
                   bool customEntryRendererFocused = focused != null && focused.Parent is MyEntryCustomRenderer;  
         
                   _lieAboutCurrentFocus = customEntryRendererFocused;  
                   var result = base.DispatchTouchEvent(ev);  
                   _lieAboutCurrentFocus = false;  
         
                   return result;  
               }  
         
               public override Android.Views.View CurrentFocus  
               {  
                   get  
                   {  
                       if (_lieAboutCurrentFocus)  
                       {  
                           return null;  
                       }  
         
                       return base.CurrentFocus;  
                   }  
               }  
    

    Best Regards,

    Leon Lu


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.