Xamarin.Forms - Simplificando o tratamento de eventos com Command


Neste artigo vou apresentar os conceitos na utilização de Command para simplificar o tratamento de eventos em aplicações Xamarin Forms usando o Visual Studio 2015 Community e a linguagem C#. (artigo traduzido e adaptado a partir do original : https://blog.xamarin.com/simplifying-events-with-commanding/ )

Neste artigo eu vou tratar de um recurso chamado commanding que permite ao data binding fazer chamada de métodos diretamente para uma ViewModel.

Existe duas formas de fazer o tratamento de eventos quando o usuário clica em um botão ou digita um texto em um controle de entrada de texto.

1- Adicionar um manipulador de eventos no arquivo code-behind tratando o evento;
2- Adicionar uma propriedade Command no XAML e adicionar o manipulador no ViewModel;

A ViewModel é uma classe que orquestra entre a View e Modelo. As ViewModels são projetadas para serem tão simples quanto possível, sem lógica de negócio dentro delas, mas pouca lógica para lidar com o roteamento de mensagens de/para as Views e outros Modelos usados no aplicativos.

A abordagem tradicional para executar um método em resposta a uma interação com a interface do usuário (UI) é chamar o método a partir de um tratamento de evento Clicked de um botão ou Tapped de um TapGestureRecognizer.

Podemos também usar a propriedade Command e fazer chamadas direta para a ViewModel a partir das seguintes classes:

  • Button
  • MenuItem
  • ToolbarItem
  • SearchBar
  • TextCell
  • ImageCell
  • ListView
  • TapGestureRecognizer

Para suportar esse recurso duas propriedades públicas são definidas na maioria dessas classes:

  • Command,  do tipo System.Windows.Input.ICommand.
  • CommandParameter,  do tipo object.

Como implementar um Command  ?

Afim de implementar um Command, a ViewModel deverá definir uma ou mais propriedades do tipo ICommand. A interface ICommand define dois métodos e um evento:

public interface ICommand
{
    void Execute(object arg);
    bool CanExecute(object arg)
    event EventHandler CanExecuteChanged;   
}

As classes Command e Command<T> fornecidos pelo Xamarin.Forms implementam a interface ICommand, onde T é o tipo dos argumentos para Execute e CanExecute.

Bem como implementar a interface ICommand, essas classes também incluem o método ChangeCanExecute, que faz com que o objeto Command dispare o evento CanExecuteChanged.

Dentro de um ViewModel, deve haver um objeto do tipo Command ou Command<T> para cada propriedade pública no ViewModel do tipo ICommand.

O construtor de Command ou Command<T> requer um objeto Action de retorno, que é chamado quando o botão chama o método ICommand.Execute.

O método CanExecute é um parâmetro de construtor opcional, e toma a forma de um Func que retorna um booleano.

Entendeu ???

Vamos ver um exemplo prático.

Xamarin Forms - Implementando um Comando

Abra o Visual Studio Community 2015 e clique em New Project;

Selecione Visual C#, o template Cross Plataform e a seguir Blank App (Xamarin.Forms Portable);

Informe o nome CommandDemo1 e clique no botão OK;

Incluindo uma nova página XAML no projeto : Pagina1.axml

Selecione o projeto compartilhado (PCL) e no menu Project clique em Add New Item;

Selecione o template Cross Plataform -> Forms Xaml Page e informe o nome Pagina1.xaml e clique em Add;

Dessa forma temos a página onde vamos implementar o Command.

Antes de prosseguir abra o arquivo App.cs e altere o código do construtor conforme abaixo:

        public App()
        {
            // The root page of your application
            var content = new Pagina1();
        }

Agora abra o arquivo Pagina1.xaml e inclua o código abaixo:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="AppCommand1.Pagina1">
    <StackLayout Padding="0,20,0,0">
        <Label Text="Demo de uso de Command" FontAttributes="Bold" 
               HorizontalOptions="Center" />
        <StackLayout Orientation="Horizontal">
            <Label Text="Digite um número:" FontSize="Large" />
            <Entry Text="{Binding Numero}" WidthRequest="100" FontSize="Large" />
        </StackLayout>
        
        <Button Text="Calcular a Raiz Quadrada" Command="{Binding RaizQuadradaCommand}"
                HorizontalOptions="Center" />
        
        <StackLayout Orientation="Horizontal">
            <Label Text="Raiz Quadrada =" FontSize="Large" />
            <Label Text="{Binding RaizQuadradaResultado}" FontSize="Large"/>
        </StackLayout>
    </StackLayout>
</ContentPage>

Neste código temos estamos usando somente o layout StackLayout para empilhar as views na página. A primeira verticalmente e as outras duas horizontalmente.

Estamos usando também as views:

  • Label - para exibir texto;
  • Entry - para permitir que o usuário digite/edite texto;

O data binding esta ocorrendo na propriedade Text das views Entry e Label. Logo elas são o destino da ligação.

Para mostrar isso estamos usando a extensão de marcação Binding entre colchetes seguido do nome do objeto origem:  {Binding nome_origem}

Agora observe que na view Button estamos definindo uma propriedade Command : Command="{Binding RaizQuadradaCommand}"

Precisamos definir uma  ViewModel, chamada DemoViewModel, e implementar as propriedades e o método que desejamos executar, no caso CalculaRaizQuadra,  que será chamado pela instância da classe Command que é do tipo ICommand.

No menu Project clique em Add Class e informe o nome DemoViewModel.cs.

A seguir vamos definir as propriedades Numero e RaizQuadradaResultado que representam o número informado na View Entry o resultado do cálculo exibido na view Label.

Precisamos também definir um comando RaizQuadradaCommand usando a interface ICommand para representar a ação associado ao Button.

using System;
using System.ComponentModel;
using System.Windows.Input;
using Xamarin.Forms;
namespace AppCommand1
{
    public class DemoViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public int Numero { get; set; }
        public double RaizQuadradaResultado { get; private set; }
        public ICommand RaizQuadradaCommand { get; private set; }
        public DemoViewModel()
        {
            Numero = 25;
            RaizQuadradaCommand = new Command(CalculaRaizQuadrada);
        }
        void CalculaRaizQuadrada()
        {
            RaizQuadradaResultado = Math.Sqrt(Numero);
            OnPropertyChanged("RaizQuadradaResultado");
        }
        protected virtual void OnPropertyChanged(string propertyName)
        {
            var changed = PropertyChanged;
            if (changed != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

Observe que a nossa ViewModel implementa a interface INotifyPropertyChanged para notificar a View das alterações ocorridas no resultado da raiz quadrada.

A ViewModel implementa o cálculo da raiz quadrada no método CalculaRaizQuadrada usando a proprieda Numero e atribui o resultado á propriedade RaziQuadradaResultado.

Quando o botão for clicado ele chama o método ICommand.Execute do objeto vinculado a sua propriedade Command.

Dessa forma o método CalcularRaizQuadrada será chamado com o valor da propriedade Numero sendo usada para fazer o cálculo.

A raiz quadrada deste valor será calculada e a Label que esta vinculada à propriedade RaizQuadradaResultado será atualizada com o resultado.

Antes de executar o projeto temos que vincular a ViewModel com a View e podemos fazer isso definindo uma instância da ViewModel atribuindo-a ao BindingContext da ContentPage no code-behind.

Abra o arquivo Pagina1.xaml.cs e definda o código abaixo :

    public partial class Pagina1 : ContentPage
    {
        public RaizQuadradaPage()
        {
            InitializeComponent();
            this.BindingContext = new DemoViewModel ();
        }
    }

Executando o projeto e alterando e digitando valores na interface veremos o resultado ser exibido nas Label.

Concluimos assim que os elementos envolvidos na implementação de um comando são :

Pegue o projeto aqui :    AppCommand1.zip (sem as referências)

Porque há um só Deus, e um só Mediador entre Deus e os homens, Jesus Cristo homem.
1 Timóteo 2:5

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

     Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti