/ / ¿Cómo puedo evitar que se active un evento Toggled en un interruptor cuando se carga una página? - xamarin, xamarin.forms

¿Cómo puedo evitar que un Evento Toggled en un interruptor se dispare cuando se carga una página? - xamarin, xamarin.forms

Mi aplicación tiene un interruptor configurado en XAML y un código C # de backend que responde al evento de alternancia

<ViewCell x:Name="ss">
<Switch x:Name="ssSwitch" Toggled="SsSwitch"   />
</ViewCell>

void SsSwitch(object sender, ToggledEventArgs e) {
// Code to update database here
}

Cuando la página se carga por primera vez, noto que se llama al evento SwSwitch Toggled.

¿Hay alguna forma de evitar que esto suceda ya que no hay razón para hacer una actualización de la base de datos al inicio?

Respuestas

1 para la respuesta № 1

Opción 1: utilizar el configurador de propiedades en ViewModel

Si está utilizando MVVM, la opción más simple para resolver esto sería usar establecedor de propiedades para detectar la actualización de valor (como se menciona en este enlazar) Pero esta opción no funciona si desea llamar a métodos pendientes aquí. Además, como práctica recomendada, se recomienda que las propiedades no se implementen operaciones que requieren mucho tiempo.

bool _isToggled;
public bool IsToggled
{
get
{
return _isToggled;
}
set
{
_isToggled = value;
// Add your update code here
}
}

Opción 2: uso PropertyChanged evento en ViewModel

La siguiente opción sería Suscribirse a PropertyChanged evento en su modelo de vista y manejarlo adecuadamente. Esto le permite definir manejadores asíncronos que a su vez pueden esperar métodos asincrónicos.

// Subscribe to event while constructing/assigning viewmodel
// viewCellVM.PropertyChanged += CategoryVM_PropertyChanged;

async void ViewCellVM_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName == nameof(ViewCellVM.IsToggled))
{
//call update code here
//await DB.Update();
}
}

Opción 3: anulación OnAppearing() en ViewCell

Otra opción es asegurarse de que el Toggled el controlador de eventos se asigna después de BindingContext se actualiza en el ViewCell. Entonces, hice un experimento rápido para rastrear el pedido Handle_Toggled, OnBindingContextChanged, OnAppearing se llaman a los métodos mientras se carga la vista. El orden resultó ser:

Handle_Toggled
OnBindingContextChanged
OnAppearing

Por lo tanto, asignando el manejador en OnAppearing El método (en el código subyacente de ViewCell) también debería funcionar para este caso:

//XAML:<Switch x:Name="switchBtn" IsToggled="{Binding IsToggled}" />
protected override void OnAppearing()
{
base.OnAppearing();

switchBtn.Toggled += Handle_Toggled;
Debug.WriteLine("OnAppearing");
}

protected override void OnDisappearing()
{
base.OnDisappearing();

switchBtn.Toggled -= Handle_Toggled;
Debug.WriteLine("OnDisappearing");
}

De esta manera Handle_Toggled solo se llamará cuando el usuario cambie el interruptor.


1 para la respuesta № 2

Con su código arriba del Switch no debería activar el evento en el primer inicio. Solo se activa si ha vinculado su IsToggled propiedad con su ViewModel! La razón de esto es que la página se inicializa primero, el modelo de vista cambia el interruptor y luego se activa el evento.

La primera solución sería manejar el IsToggled propiedad y el Toggled evento ambos del código subyacente (no recomendado si está mvvm-ing su código). Una mejor solución sería manejar ambos desde ViewModel.

El problema es que el Switch El control no tiene Command propiedad. Tienes que usar un comportamiento para enlazar a un Command. Sharada Gururaj ya publicó un enlace arriba con una buena explicación.

Aquí está la solución corta del enlace de stackoverflow de Sharada Gururaj: Xamarin Forms Switch Toggled event no enlaza con viewmodel

<Switch IsToggled="{Binding IsToggled}">
<Switch.Behaviors>
<behaviors:EventHandlerBehavior EventName="Toggled">
<behaviors:InvokeCommandAction Command="{Binding ToggleSwitchCommand}" />
</behaviors:EventHandlerBehavior>
</Switch.Behaviors>

Más información: