In the pattern MVVM
in the Xamarin.Forms
usually this is dealt with by the Command
called CanExecute
.
With it, when associating a command to a button, every time there is change in the CanExecute
and the response is False
, the button to which the command is associated is also disabled.
Developing on the scenario you have, we would have something like what I’m going to show you next.
Your model would be something like this:
public class CidadeDestino : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string nome;
public string Nome
{
get { return nome; }
set
{
if (value != nome)
{
nome = value;
OnPropertyChanged("Nome");
}
}
}
private string siglaEstado;
public string SiglaEstado
{
get { return siglaEstado; }
set
{
if (value != siglaEstado)
{
siglaEstado = value;
OnPropertyChanged("SiglaEstado");
}
}
}
protected void OnPropertyChanged(string propertyName)
{
if (!string.IsNullOrWhiteSpace(propertyName))
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Considering this scenario, in short, its condition of the CanExecute
is "City name and state acronym must be different from null and void".
So, continuing the development...
On screen (XAML)
...
<Entry Text="{Binding NomeCidadeDestino}"
Placeholder="Nome da Cidade"
.../>
<Entry Text="{Binding SiglaEstadoCidadeDestino}"
Placeholder="UF"
.../>
<Button Text="Confirmar"
Command="{Binding ComandoConfirmar}"
.../>
...
* - Although I defaced the screen in XAML, if the definition is done via C# the effect is the same.
And building the other layer...
Na View Model
public class MinhaViewModel
{
private CidadeDestino cidadeDestino = new CidadeDestino();
public Command ComandoConfirmar { get; }
public string NomeCidadeDestino
{
get { return this.cidadeDestino?.Nome; }
set
{
cidadeDestino.Nome = value;
ComandoConfirmar.ChangeCanExecute(); // Aqui você 'informa' que o estado do comando deve ser reavaliado
}
}
public string SiglaEstadoCidadeDestino
{
get { return this.cidadeDestino?.SiglaEstado; }
set
{
cidadeDestino.SiglaEstado = value;
ComandoConfirmar.ChangeCanExecute();
}
}
public MinhaViewModel()
{
ComandoConfirmar = new Command(ExecutarConfirmar, () => !string.IsNullOrWhiteSpace(cidadeDestino?.Nome) && !string.IsNullOrWhiteSpace(cidadeDestino?.SiglaEstado));
}
private void ExecutarConfirmar()
{
MessagingCenter.Send(cidadeDestino, "BuscaCidade");
}
}
And the result of that implementation would be:
Now just take this idea and apply in your real scenario that should solve. That same CanExecute
It also uses a common property in Viewmodels, which generally alternates the visibility of those "loading" marbles. The same idea applies.
Let me know if there’s any doubt left.
I hope this helps.
Hello Diego, your answer helped me too much, I had to make small changes because of my code, but the idea was the same. Thank you very much.
– Q.Wesley