Back-End

25 jan, 2017

Xamarin Forms – MVVM, DataBinding e a interface ICommand – Parte 01

Publicidade

Neste artigo, vou apresentar os principais conceitos sobre MVVM, DataBinding e da interface ICommand: apresentando o cenário e criando o projeto.

Quando trabalhamos com o Xamarin Forms em aplicações de negócios, geralmente definimos um modelo de domínio que representam as classes da nossa aplicação. Estamos, assim, definindo o Model que é constituido de classes C# e, geralmente, essas classes são classes POCO contendo apenas propriedades.

Outro componente essencial de uma aplicação Xamarin Forms são as páginas que contém layouts e outras views e representam o componente visual da nossa aplicação, conhecido como Views.

Para separar a lógica de negócio da parte visual, usamos o padrão MVVM e criamos para isso as classes que vão conter todo o código responsável por gerenciar a dar a vida às Views. Essas classes são conhecidas como o ViewModel é possui o objetivo de reunir toda a lógica de atualização, acesso e conversão de dados.

Temos assim o tripé: Model, View e ViewModel.

O recurso DataBinding atua de forma crucial para que a aplicação do padrão MVVM funcione. Vamos ver um pouco sobre ele.

O famigerado DataBinding e a interface ICommand

Se você procurar pela definição de DataBinding na Wikipédia vai encontrar:

“Ligação de dados, do inglês DataBinding, é uma técnica geral que une duas fontes de dados/informações e as mantêm em sincronia em um processo que estabelece uma conexão entre UI (interface de usuário) da aplicação e a lógica de negócio.”

Uma forma de fazer a ligação de dados no Xamarin Forms é fazer a ligação entre o Code-Behind, representado pelo código C#, e o código XAML, que define a interface do usuário. É assim que declaramos um evento para uma View no código XAML e fazemos o tratamento do evento no Code-Behind com C#.

Essa abordagem funciona, mas nos traz muitos problemas quando precisamos testar nossas aplicações. Esse é um dos motivos da utilização do padrão MVVM. Então, para contornar esse problema, usamos a abordagem MVVM onde o DataBinding é feito praticamente no código XAML, usando as propriedades BindingContext e Binding.

Nesta abordagem, o DataBinding, ou vinculação de dados, é usado para conectar as propriedades dos elementos visuais na View com as propriedades dos dados na ViewModel, permitindo a manipulação direta dos dados através da interface do usuário.

Mas diante da complexidade das aplicações de negócios, nem tudo são propriedades e, muitas vezes, a ViewModel expõe métodos públicos que precisam ser chamados a partir da View com base em uma interação do usuário.

Sem usar MVVM, teríamos que fazer a chamada dos métodos a partir de um evento, como um evento Clicked de um Button ou Tapped de um TapGestureRecognizer.

Para tornar um elemento de interface do usuário clicável com o gesto de toque, criamos uma instância de TapGestureRecognizer, manipulamos o evento Tapped e adicionamos o novo reconhecimento de gestos à coleção GestureRecognizers no elemento de interface do usuário.

Mas como podemos fazer a chamada de métodos acionados pela interação do usuário em uma View a partir de uma ViewModel?

A boa notícia é que o Xamarin Forms fornece um recurso que permite que a ligação de dados ou DataBinding realize chamada de métodos na ViewModel diretamente a partir de um Button ou TapGestureRecognizer e alguns outros elementos.

Esse recurso é a interface ICommand que permite definir e implementar um comando o que chamamos de commanding.

Usando comandos, o DataBinding pode fazer chamadas de método diretamente de uma ViewModel a partir das seguinte classes:

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

Nota: Podemos também implementar comandos em classes customizadas.

Implementando um comando

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> fornecidas 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 na 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.

Vamos ver uma aplicação prática desse recurso em um exemplo bem simples para entendermos melhor o seu funcionamento.

Recursos usados: Visual Studio Community 2015

Nota: Baixe e use a versão Community 2015 do VS. Ela é grátis e é equivalente a versão Professional.

Criando um projeto no VS 2015 com Xamarin

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 XF_Apps e clique no botão OK.

Ao clicar no botão OK, será criada uma solução contendo 4 projetos (dependendo do seu ambiente pode haver alguma variação nos projetos).

O projeto comum possui a classe App.cs que irá conter o código compartilhado e que vamos usar neste artigo.

Não esqueça de atualizar o Xamarin Forms acionando o menu Tools e as opções Nuget Package Manager -> Manage Nuget Packages for Solution.

A seguir, clique em Update e selecione o item Xamarin Forms e clique em Install.

Criando a páginas MainPage

No menu Project, clique em Add New Item e, a seguir, em Cross Platform e em Forms Xaml Page. Depois informe o nome MainPage:

Inclua o código XAML abaixo na página MainPage:

<?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="XF_Apps.AppMvvm1.Views.MainPage">
    
    <StackLayout Spacing="20" VerticalOptions="Center" 
                 HorizontalOptions="Center">
        <Label Text="Xamarin Forms - MVVM" TextColor="Navy" 
               FontSize="20"/>
        <Entry x:Name="txtNome" Placeholder="Informe o nome" 
               FontSize="20" />
        <Button Text="Boas Vindas" TextColor="White" 
                BackgroundColor="Teal" 
                FontSize="20"
                Clicked="btn_Click" />
        <Label x:Name="lblMensagem" FontSize="30" 
               TextColor="Red" 
               FontAttributes="Bold" />
    </StackLayout>
    
</ContentPage >

Acima vemos a tela gerada pela página ContentPage e pelo Layout StackLayout e as views Label, Entry e Button definidas no código XAML em MainPage.

No arquivo code-behind MainPage.xaml.cs, vamos definir o tratamento do evento Clicked conforme abaixo:

private void btn_Click(object sender, System.EventArgs e)
{
        var nome = txtNome.Text;
        lblMensagem.Text = "Bem-Vindo " + nome;
}

Neste código, quando o usuário clicar no botão, o nome informado será exibido na Label – lblMensagem – com o texto: “Bem-Vindo nome_digitado”.

Tudo bem… A aplicação funciona. Mas essa é a abordagem tradicional sem MVVM.

Vamos melhorar a nossa aplicação aplicando o padrão MVVM na segunda parte do artigo.