pages ejemplo crear botones c# xaml focus viewmodel xamarin-forms

c# - ejemplo - xamarin forms pages



Cómo establecer el foco desde ViewModel en formularios Xamarin (2)

Una de las opciones es usar disparadores (forma XAML):

<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; } }

Lea más aquí: https://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/triggers/

Quiero establecer el foco en un control de SearchBox después de hacer algunas operaciones asincrónicas, y me gustaría hacerlo desde mi ViewModel .

¿Cómo podría hacer esto posible?

EDITAR

Código de ViewModel:

private bool _searchBarFocused; public bool SearchBarFocused { get { return _searchBarFocused; } set { _searchBarFocused = value; base.OnPropertyChanged("SearchBarFocused"); } } public async Task InitializeData() { // Other operations... SearchBarFocused = true; }

Ver código de código detrás:

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

Código SearchBar XAML:

<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>

Código de acción desencadenante:

public class SearchBarFocusTriggerAction : TriggerAction<SearchBar> { public bool Focused { get; set; } protected override void Invoke(SearchBar searchBar) { if (Focused) searchBar.Focus(); else searchBar.Unfocus(); } }


Este es un ejemplo de cómo lo hago, antes de esto solía hacer uso de MessagingCenter

en xaml, necesitas dar un x: Name al obj que quieres enfocar.

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

entonces tiene que hacer referencia a ese control en su parámetro de comando en un botón o, por ejemplo, en este caso utilizo un elemento de la barra de herramientas.

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

luego en tu comando vm:

#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"); }