Search code examples
c#xamarinxamarin.formsfreshmvvm

Xamarin.Forms set focus from mvvm ViewModel


I'm working on a chat application using Xamarin.Forms.

And I want to avoid to hide the keyboard when the Entry loses focus and button Send is clicked.

How can I do it on Android and iOS?

I use XF, full Mvvm without XAML(only C#)

Updated:

In page class:

private EntrySetBorder _newMessageEntry;
...
_newMessageEntry = new EntrySetBorder
{
    TextColor = Color.Black,
    HorizontalOptions = LayoutOptions.FillAndExpand,
    VerticalOptions = LayoutOptions.End,
    Margin = new Thickness(0, 0, 5, 0)
};

In model class:

var entry = CurrentPage.FindByName<EntrySetBorder>("_newMessageEntry");
entry.Focus();

}


Solution

  • This can be achieved easily by using the FindByName<>() function inside the PCL.
    This is one way of doing that:

    Entry myEntry = CurrentPage.FindByName<Entry>("YourEntryName");
    myEntry.Focus();
    

    You can add that at the end of the click handler of your send button.

    Edit:

    In your case I think your problem is that your entry is set to private, so I would suggest either expose it as public or expose it using another public property. Two solutions that might work:

    public EntrySetBorder _newMessageEntry;
    ...
    _newMessageEntry = new EntrySetBorder
    {
    
        TextColor = Color.Black,
        HorizontalOptions = LayoutOptions.FillAndExpand,
        VerticalOptions = LayoutOptions.End,
        Margin = new Thickness(0, 0, 5, 0)
    };
    

    And:

    EntrySetBorder entry = CurrentPage.FindByName<EntrySetBorder>("_newMessageEntry");
    entry.Focus();
    

    Or you go with this:

    private EntrySetBorder _newMessageEntry;
    ...
    _newMessageEntry = new EntrySetBorder
    {
    
        TextColor = Color.Black,
        HorizontalOptions = LayoutOptions.FillAndExpand,
        VerticalOptions = LayoutOptions.End,
        Margin = new Thickness(0, 0, 5, 0)
    };
    public EntrySetBorder NewMessageEntry => _newMessageEntry;
    

    and :

    EntrySetBorder entry = CurrentPage.FindByName<EntrySetBorder>("NewMessageEntry");
    entry.Focus();
    

    Please try that :)

    Edit 2:

    After reviewing your code, and testing it, the final way to fix it was by sending the Entry as a parameter in the command you're using, example:

    Inside the page you're creating:

    sendButton.CommandParameter = NewMessageEntry; // We're adding the Entry we want to focus as a command parameter.
    

    And inside your PageModel and the command we want to use:

    public Command SendCommand
    {
        get
        {
            return new Command<Entry>((obj) => //obj here means the parameters we're sending I.E: the entry we set it in the page.
            {
                //The code you want to execute
                Entry entry = obj;
                entry.Focus();
            });
        }
    }
    

    Note that I used Entry because I didn't have all the implementation of your custom entry.