0

UPDATED - Trimmed down user control:

using CommunityToolkit.Maui.Core.Platform;
using CommunityToolkit.Mvvm.Input;
using System.Diagnostics;

namespace GSL.Presentation.CustomControls;

public partial class GSLEntryControl : ContentView
{

public GSLEntryControl()
{
    try
    {
        InitializeComponent();
    }
    catch (Exception ex)
    {
        Debug.WriteLine($"GEORGE: Exception: {ex}");
    }
}

[RelayCommand]
private void ClearText()
{
    Text = string.Empty;
}


// All the updates will be done in the property set. 
public static readonly BindableProperty IsInFocusProperty = BindableProperty.Create(
    nameof(IsInFocus),
    typeof(bool),
    typeof(GSLEntryControl),
    false,
    BindingMode.OneWay,
    propertyChanged: (bindable, oldValue, newValue) =>
    {
        Debug.WriteLine("George: IsInFocusProperty Start");
        if (bindable is GSLEntryControl editText)
        {
            editText.IsInFocus = (bool)newValue;
        }
        Debug.WriteLine("George: IsInFocusProperty End");
    });

public string _text = string.Empty;
public string Text
{
    get
    {
        return _text;
    }
    set
    {
        //Run all this code on the main UI Thread 
        Application.Current.Dispatcher.Dispatch(() =>
        {
            Debug.WriteLine("GEORGE: Text Set Start");
            _text = value;
            //IsClearButtonVisible = _text?.Length > 0;
            //SetBorderColor();
            Debug.WriteLine("GEORGE: Text Set End");
        });
    }
}


private bool _isInFocus = false;
public bool IsInFocus
{
    get
    {
        return _isInFocus;
    }
    set
    {
        Debug.WriteLine($"GEORGE: IsInFocus Set Start.  Value: {value}");
        _isInFocus = value;

        Application.Current.Dispatcher.Dispatch(async () =>
        {

            if (_isInFocus)
            {
                var tempResult = gslEntry.Focus();

            

    Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping("MyCustomization", (handler, view) =>
                    {
#if ANDROID
                        handler.PlatformView.ShowSoftInputOnFocus = false;
#endif
                    });
                //var workResult = await gslEntry.HideSoftInputAsync(CancellationToken.None);
                //Debug.WriteLine($"GEORGE: Focus ShowKeyboard Result: {workResult}");

                Debug.WriteLine($"GEORGE: Focus-KeyBoardShown: {gslEntry.IsSoftKeyboardShowing()}" );
            }
            else
            {
                gslEntry.Unfocus();
            }
            //SetBorderColor();
            Debug.WriteLine("GEORGE: IsInFocus Set End");
        });
    }
}

//When entry is focused, change border color to blue
async void Entry_Focused(object sender, FocusEventArgs e)
{
    Debug.WriteLine("GEORGE: Entry_Focused start");
    //EntryFocused?.Invoke(sender, e);

    bool workResult = false;
    Application.Current.Dispatcher.Dispatch(async () =>
    {
        workResult = await gslEntry.HideSoftInputAsync(CancellationToken.None);
        Debug.WriteLine($"GEORGE: Focus ShowKeyboard Result: {workResult}");
    });

    Debug.WriteLine("GEORGE: Entry_Focused end");
}

}

Here is the XAML for the control:

<ContentView.Resources>
    <ResourceDictionary>
        <mct:InvertedBoolConverter x:Key="InvertedBoolConverter"/>
    </ResourceDictionary>

</ContentView.Resources>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
    </Grid.RowDefinitions>

    <Border x:Name="entryFrame"
            StrokeThickness="2"
            Padding="0"
            HeightRequest="50"
            VerticalOptions="CenterAndExpand"
            HorizontalOptions="FillAndExpand" 
            Grid.Row="0"
            Grid.Column="0"
            Grid.ColumnSpan="2">

        <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" ColumnDefinitions="*,auto">
            <Entry x:Name="gslEntry"
                       Margin="10,0,0,0"
                       ReturnType="Done"
                       Keyboard="Text"
                       TextTransform="Uppercase"
                       FontSize="16"
                       Text="{Binding Text,Mode=TwoWay}"
                       IsEnabled="True"
                       Placeholder=""
                       IsPassword="False"
                       VerticalOptions="CenterAndExpand"
                       HorizontalOptions="FillAndExpand"
                   Grid.Column="0"/>


            <!-- Clear Button -->
            <ImageButton Source="ic_delete.xml"
                     x:Name="clearButton"
                     WidthRequest="32"
                     HeightRequest="32"
                     VerticalOptions="Center"
                     HorizontalOptions="End"
                     Margin="0,0,5,0"
                     Command="{Binding ClearTextCommand}"
                     Grid.Column="1"/>
        </Grid>
    </Border>

    <Label x:Name="invalidLabel"
           Text="Error"
           Margin="5,0,0,0"
           HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
           IsVisible="false"
           Style="{StaticResource ValidationErrorLabelStyle}"
           Grid.Row="1"/>
</Grid>

I have code in the IsInFocus event to hide the keyboard when an entry control gets focus. I have tried it several ways including using HideSoftInputAsync(CancellationToken.None) on the entry control

Using a handler for Android to hide the keyboard as see in the current code. Neither of these are working.

I also tried adding and removing async from the Dispatcher and event completely removing the Dispatcher and they had no effect.

2 Answers 2

1

You can use the handler to hide the softkeyboard.

First, you need to create a custom Entry.

public class NoKeyBoardEntry:Entry{


}

Second, you can add the handler to the GSLEntryControl.xaml.cs to hide the keyboard when you get focus of the.

 public partial class GSLEntryControl : ContentView
    {
    
        public GSLEntryControl()
        {
            InitializeComponent();
            NokeyBoard();           
        }
    
    void NokeyBoard()
        {
            Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping("MyCustomization", (handler, view) =>
            {
                if (view is NoKeyBoardEntry)
                {
    #if ANDROID
                    handler.PlatformView.ShowSoftInputOnFocus = false;
    
    #endif
                }
            });
        }
    }

Last, you can create the custom entry like this.

<ContentPage

...
xmlns:local="clr-namespace:yourProject"
>

<local:NoKeyBoardEntry>
7
  • @guangyBai I tried the above suggestion (see updated code) and it had no affect. I also trimmed down the code a great deal so more simply trouble shoot... Commented Jun 27 at 13:44
  • You can try the code handler.PlatformView.GotFocus += (s, e) => { handler.PlatformView.ShowSoftInputOnFocus = false; }; when you got the focus of the entry. Commented Jun 28 at 9:37
  • I added that line of code and now I am getting a compilation error: Severity Code Description Project File Line Suppression State Error CS1061 'AppCompatEditText' does not contain a definition for 'GotFocus' and no accessible extension method 'GotFocus' accepting a first argument of type 'AppCompatEditText' could be found (are you missing a using directive or an assembly reference?) UserControlTest (net8.0-android) C:\Users\xff7wvm\source\repos\UserControlTest\UserControlTest\CustomControls\GSLEntryControl\GSLEntryControl.xaml.cs 91 Active Commented Jun 28 at 14:11
  • I update the answer and you can check it. Commented Jul 3 at 7:01
  • OK - So you are basically saying I have to replace the Entry control used in my custom control with the new NoKeyBoardEntry item. Then add all the code for the handler in my custom control -- I don't understand the last part - creating the custom entry -- wouldn't the be inside my custom control and not on a content page? Commented Jul 5 at 15:14
0

In xaml

<ContentPage ...
               HideSoftInputOnTapped="True">

//rest of the code

</ContentPage> 

This works for me, so whenever you tapped outside of entry or other control keyboard close itself. Works both on ios and android in .net 8 latest version.

1
  • This is not quite what I am looking for. I need to run code and in specific situations, when the entry control gets focus - I do not want to show the keyboard. Commented Jun 27 at 14:11

Not the answer you're looking for? Browse other questions tagged or ask your own question.