Meu aplicativo tem um switch configurado em XAML e código C # back-end que responde ao evento toggle
<ViewCell x:Name="ss">
<Switch x:Name="ssSwitch" Toggled="SsSwitch" />
</ViewCell>
void SsSwitch(object sender, ToggledEventArgs e) {
// Code to update database here
}
Quando a página é carregada pela primeira vez, noto que o evento SwSwitch Toggled é chamado.
Existe alguma maneira de impedir que isso aconteça, pois não há razão para fazer uma atualização do banco de dados na inicialização.
Respostas:
1 para resposta № 1Opção 1: usar configurador de propriedade em ViewModel
Se você estiver usando MVVM - a opção mais simples para resolver isso seria usar configurador de propriedade para detectar a atualização do valor (como mencionado neste ligação) Mas esta opção não funciona se você quiser chamar métodos aguardáveis aqui. Além disso, como prática recomendada, é recomendado que as propriedades não implementem qualquer operação demorada.
bool _isToggled;
public bool IsToggled
{
get
{
return _isToggled;
}
set
{
_isToggled = value;
// Add your update code here
}
}
Opção 2: Use PropertyChanged
evento em ViewModel
A próxima opção seria inscrever-se para PropertyChanged
evento em seu viewmodel e manipule-o apropriadamente. Isso permite definir manipuladores assíncronos que, por sua vez, podem aguardar métodos assíncronos.
// 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();
}
}
Opção 3: substituir OnAppearing()
em ViewCell
Outra opção é certificar-se de que o Toggled
manipulador de eventos é atribuído após o BindingContext
é atualizado no ViewCell
. Então, fiz uma experiência rápida para rastrear o pedido Handle_Toggled
, OnBindingContextChanged
, OnAppearing
métodos são chamados durante o carregamento da visualização. O pedido acabou sendo:
Handle_Toggled
OnBindingContextChanged
OnAppearing
Conseqüentemente, atribuindo o manipulador em OnAppearing
método (no code-behind de ViewCell) também deve 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");
}
Deste jeito Handle_Toggled
só será chamado quando o usuário alternar a chave.
1 para resposta № 2
Com seu código acima do Switch
não deve disparar o evento na primeira partida. Ele dispara apenas se você tiver vinculado o seu IsToggled
propriedade com o seu ViewModel! A razão para isso é que a página é inicializada primeiro, o ViewModel alterna o switch e, em seguida, o evento é disparado.
A primeira solução seria lidar com o IsToggled
propriedade e o Toggled
evento ambos do code-behind (não recomendado se você estiver fazendo mvvm-ing seu código). A melhor solução seria lidar com ambos a partir do ViewModel.
O problema é que o Switch
O controle não tem um Command
propriedade. Você tem que usar um comportamento para ligar a um Command.
Sharada Gururaj já postou um Link acima com uma boa explicação.
Aqui está o link de stackoverflow de Sharada Gururajs do formulário de solução: O evento Xamarin Forms Switch Toggled não se vincula ao viewmodel
<Switch IsToggled="{Binding IsToggled}">
<Switch.Behaviors>
<behaviors:EventHandlerBehavior EventName="Toggled">
<behaviors:InvokeCommandAction Command="{Binding ToggleSwitchCommand}" />
</behaviors:EventHandlerBehavior>
</Switch.Behaviors>
Mais informações:
- https://blog.xamarin.com/turn-events-into-commands-with-behaviors/
- https://forums.xamarin.com/discussion/64374/switch-with-istoggled-binding-is-throwing-toggled-event-on-init-when-bound-value-is-true