Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set focus from ViewModel in Xamarin Forms

I want to set the focus in a SearchBox control after do some asynchronous operations, and I would like to do it from my ViewModel.

How could I do this possible?

EDIT

ViewModel code:

    private bool _searchBarFocused;

    public bool SearchBarFocused
    {
        get { return _searchBarFocused; }
        set
        {
            _searchBarFocused = value;
            base.OnPropertyChanged("SearchBarFocused");
        }
    }

    public async Task InitializeData()
    {
        // Other operations...

        SearchBarFocused = true;
    }

View's code-behind code:

    protected override void OnAppearing()
    {
        base.OnAppearing();
        (this.BindingContext as MyViewModel).InitializeData();
    }

SearchBar XAML code:

  <SearchBar SearchCommand="{Binding SearchItemsCommand}">
    <SearchBar.Triggers>
      <DataTrigger TargetType="SearchBar"
                   Binding="{Binding SearchBarFocused, Mode=TwoWay}" Value="True">
        <Trigger.EnterActions>
          <triggers:SearchBarFocusTriggerAction Focused="True" />
        </Trigger.EnterActions>

        <Trigger.ExitActions>
          <triggers:SearchBarFocusTriggerAction Focused="False" />
        </Trigger.ExitActions>
      </DataTrigger>
    </SearchBar.Triggers>
  </SearchBar>

Trigger action code:

public class SearchBarFocusTriggerAction : TriggerAction<SearchBar>
{
    public bool Focused { get; set; }

    protected override void Invoke(SearchBar searchBar)
    {
        if (Focused)
            searchBar.Focus();
        else
            searchBar.Unfocus();
    }
}
like image 828
Fran_gg7 Avatar asked Aug 25 '15 14:08

Fran_gg7


People also ask

How do I associate a view to another view in Xamarin?

Connecting View Models to Views View models can be connected to views by using the data-binding capabilities of Xamarin.Forms. There are many approaches that can be used to construct views and view models and associate them at runtime. These approaches fall into two categories, known as view first composition, and view model first composition.

How do I instantiate a view model in XAML?

The simplest approach is for the view to declaratively instantiate its corresponding view model in XAML. When the view is constructed, the corresponding view model object will also be constructed. This approach is demonstrated in the following code example:

What is XAML ViewModel pattern?

The pattern enforces a separation between three software layers — the XAML user interface, called the View; the underlying data, called the Model; and an intermediary between the View and the Model, called the ViewModel. The View and the ViewModel are often connected through data bindings defined in the XAML file.

Why can't I access the methods on a control in Xamarin forms?

When developing in the MVVM pattern, you have no access to the View and hence no access to the methods on a Control. Most controls in Xamarin Forms have bindable properties but some do not.


2 Answers

This is an example of how I do, before this I used to do using MessagingCenter

in xaml , you need to give an x:Name to the obj you want to make focus.

<!-- PICKER's DEFINITION -->
<DatePicker
    x:Name="Datepicker"
    Date="{Binding SelectedDate, Mode=TwoWay}"
    IsEnabled="true"
    IsVisible="false">
</DatePicker>

then you have to make reference to that control in your command parameter on a button or for example in this case I use a toolbar item.

<!-- MENU TOOLBAR -->
<ContentPage.ToolbarItems>
    <ToolbarItem
        Command="{Binding ShowCalendarCommand}"
        Icon="Calendar"
        CommandParameter="{x:Reference Datepicker}" />
</ContentPage.ToolbarItems>

then in your vm command :

#region toolbar commands

public ICommand ShowCalendarCommand => new RelayCommand<Object>(ShowCalendar);

#endregion

private void ShowCalendar(Object obj)
{
    var calendar = (DatePicker)obj;
    calendar.Focus();
    //  MessagingCenter.Send(this, "Calendar");
}
like image 161
CarLoOSX Avatar answered Sep 21 '22 06:09

CarLoOSX


One of options is to use Triggers (XAML way):

 <SearchBar x:Name="searchBar"
       Text=""
       Placeholder="type something">
    <SearchBar.Triggers>

        <DataTrigger TargetType="SearchBar"
                     Binding="{Binding ViewModelIsSearchBarFocused}"
                     Value="True">

            <Trigger.EnterActions>
                <local:FocusTriggerAction Focused="True" />
            </Trigger.EnterActions>

            <Trigger.ExitActions>
                <local:FocusTriggerAction Focused="False" />
            </Trigger.ExitActions>

        </DataTrigger>   

        <EventTrigger Event="Unfocused">
            <local:UnfocusedTriggerAction />
        </EventTrigger>    

    </SearchBar.Triggers>       
</SearchBar>
public class FocusTriggerAction : TriggerAction<SearchBar>
{
    public bool Focused { get; set; }

    protected override async void Invoke (SearchBar searchBar)
    {
        await Task.Delay(1000);

        if (Focused)
        {
            searchBar.Focus();
        }
        else
        {
            searchBar.UnFocus();
        }
    }
}

public class UnfocusedTriggerAction : TriggerAction<SearchBar>
{
    protected override void Invoke (SearchBar searchBar)
    {
        YourViewModel.ViewModelIsSearchBarFocused = false;
    }
}

Read more here: https://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/triggers/

like image 31
Daniel Luberda Avatar answered Sep 22 '22 06:09

Daniel Luberda