.NET MAUI - MVVM, DataBinding e a interface ICommand - II
Vou continuar a apresentar os principais conceitos sobre MVVM, DataBinding e da interface ICommand : Implementando o MVVM com DataBinding. |
Na primeira parte do artigo apresentei os conceitos sobre o MVVM, databinding e ICommand e criei uma aplicação bem simpes sem usar o padrão MVVM. Vamos agora implementar o MVVM e aplicar o databinding e definir o comando usando a interface ICommand.
Até o momento a nossa aplicação possui o seguinte desenho, onde vemos que a lógica de apresentação esta no code-behind, e, temos assim um forte acoplamento entre a View e o Model:
Nosso objetivo neste artigo é implementar o padrão MVVM criando a ViewModel, e assim separar a lógica de apresentação do code-behind:
Recursos usados:
Implementando MVVM e definindo um Comando
Abra o projeto criado no artigo anterior no Visual Studio Community 2022.
Vamos criar uma classe em nosso projeto que irá conter o código responsável pela criação e apresentação da view SaudacaoView. Clique com o botão direito na pasta ViewModels e selecione a opção Add Class e informe o nome SaudacaoViewModel.
Precisamos definir nesta classe as propriedades e métodos necessários para criar a nossa view.
Se analisarmos a nossa view veremos que vamos precisar definir duas propriedades:
Então o código da classe SaudacaoViewModel deve ficar assim:
public class SaudacaoViewModel
{ //propriedade para o nome public string Nome { get; set; } //propriedade para a mensagem |
Mas perceba que a nossa view possui também um botão com um evento definido no code-behind que ao ser disparado monta a mensagem e a exibe na Label.
Precisamos então definir em nossa ViewModel um comando que irá atuar da mesma forma.
É aqui que entra a interface ICommand e a classe Command.
Veja como fica a implementação de um comando que será disparado quando o usuário clicar no botão definido na view:
public class SaudacaoViewModel
{ //propriedade para o nome public string Nome { get; set; } //propriedade para a mensagem public ICommand SaudacaoCommand { get; private set; } public SaudacaoViewModel() void SaudacaoCmd() |
Vamos entender o código:
1 - Primeiro definimos uma propriedade SaudacaoCommand do tipo ICommand:
public ICommand SaudacaoCommand { get; private set; }
2 - Depois criamos no construtor uma instância da classe Command onde definimos um delegate que aponta para classe SaudacaoCmd e que irá implementar o nosso comando
SaudacaoCommand = new Command(SaudacaoCmd);
3 - Finalmente implementamos o nosso comando
no método SaudacaoCmd:
Mensagem = $"Bem-Vindo {Nome}";
Nota: Uma forma mais simplificada de implementar o comando seria assim:
public Command SaudacaoCommand { get { return new Command(() => { Mensagem = $"Bem-Vindo {Nome}"; }); } } |
Aplicando o DataBinding
Muito bem. Agora podemos alterar a nossa view SaudacaoView e aplicar o DataBinding.
Primeiro temos que definir como a nossa View vai se comunicar com a nossa ViewModel. Fazemos isso no arquivo code-behind SaudacaoView.xaml.cs definindo o código a seguir:
public partial Class SaudacaoView:
ContentPage { InitializeComponent(); this.BindingContext = new SaudacaoViewModel(); } |
Criamos uma instância da nossa ViewModel e atribuímos ao BindingContext da ContentPage. Assim podemos aplicar o databinding na view.
Vamos definir o DataBindind para as propriedades que serão gerenciadas nas views Label, Entry e no Button. A view Image vai permanecer inalterada.
Nota: Poderíamos ter feito essa referência no código XAML.
Veja como ficou a nossa view SaudacaoView após aplicarmos o databinding:
<?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"
<Label Text="Xamarin Forms - MVVM" TextColor="Navy"
<Entry Text="{Binding Nome}" Placeholder="Informe o nome"
<Button Text="Boas Vindas" TextColor="White"
<Label Text="{Binding Mensagem}" FontSize="30"
</StackLayout> </ContentPage > |
Note que removemos os atributos x:Name das Labels e o evento Clicked do Button pois não vamos mais precisar deles.
A seguir implementamos o databinding vinculando a View às propriedades Nome e Mensagem e usando a propriedade Command fizemos a vinculação à propriedade SaudacaoCommand:
Text="{Binding Nome}"
Text="{Binding Mensagem}"
Command="{Binding SaudacaoCommand}"
Dessa forma podemos remover o evento Clicked que havíamos definido no arquivo code-behind.
Se você executar o projeto neste momento vai ficar surpreso ao ver que ao clicar no botão a mensagem não será exibida na Label.
Porquê ?
Se você definir um breakpoint no comando definido na ViewModel irá constatar que a mensagem esta sendo montada mas não esta sendo exibida.
O motivo disso é que a view não foi notificada da alteração da mensagem, ou seja, a propriedade Mensagem foi alterada mas a view não foi notificada.
Precisamos de alguma forma notificar a view das alterações que ocorrerem nas propriedades definidas na ViewModel.
Para cumprir esse papel precisamos implementar a interface INotifyPropertyChanged em nossa ViewModel e alterar a definição da propriedade Mensagem para que ela notifique a view de qualquer alteração feita.
Vamos então fazer isso alterando o código da nossa ViewModel conforme mostrado a seguir:
public class SaudacaoViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void Notificar([CallerMemberName] string prop = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop)); } //propriedade para o nome //propriedade para a mensagem public ICommand SaudacaoCommand { get; private set; } public SaudacaoViewModel() void SaudacaoCmd() |
Agora, qualquer alteração na propriedade Mensagem irá disparar o evento para notificar a View que irá exibir a mensagem.
Executando o projeto iremos obter:
Agora, após a implementação da interface INotifyPropertyChanged, a nossa view esta sendo notificada da alteração da propriedade Mensagem e exibe a mensagem na Label- lblMensagem.
Na próxima parte do artigo veremos como passar parâmetros para métodos na ViewModel.
Pegue o código das aqui: MauiBoasVindas.zip (sem as referências)
"Mas agora, morrendo para aquilo que antes nos prendia,
fomos libertados da lei, para que sirvamos conforme o novo modo do Espírito,
e não segundo a velha forma da lei escrita."
Romanos 7:6
Referências: