Resumo do Capítulo 18. MVVM
Observação
Este livro foi publicado na primavera de 2016 e não foi atualizado desde então. Há muito no livro que permanece valioso, mas parte do material está desatualizado e alguns tópicos não estão mais totalmente corretos ou completos.
Uma das melhores maneiras de arquitetar um aplicativo é separando a interface do usuário do código subjacente, que às vezes é chamado de lógica de negócios. Existem várias técnicas, mas aquela que é adaptada para ambientes baseados em XAML é conhecida como Model-View-ViewModel ou MVVM.
Inter-relações MVVM
Um aplicativo MVVM tem três camadas:
- O modelo fornece dados subjacentes, às vezes por meio de arquivos ou acessos à Web
- O Modo de Exibição é a interface do usuário ou a camada de apresentação, geralmente implementada em XAML
- O ViewModel conecta o Model e o View
O Model ignora o ViewModel e o ViewModel ignora o View. Essas três camadas geralmente se conectam umas às outras usando os seguintes mecanismos:
Em muitos programas menores (e até maiores), muitas vezes o Model está ausente ou sua funcionalidade é integrada ao ViewModel.
ViewModels e vinculação de dados
Para se envolver em associações de dados, um ViewModel deve ser capaz de notificar o View quando uma propriedade do ViewModel for alterada. O ViewModel faz isso implementando a INotifyPropertyChanged
System.ComponentModel
interface no namespace. Isso faz parte do .NET em vez Xamarin.Formsde . (Geralmente, os ViewModels tentam manter a independência da plataforma.)
A INotifyPropertyChanged
interface declara um único evento chamado PropertyChanged
que indica a propriedade que foi alterada.
Um relógio ViewModel
A DateTimeViewModel
biblioteca Book.ToolkitXamarin.Forms define uma propriedade do tipo DateTime
que é alterada com base em um temporizador. A classe implementa INotifyPropertyChanged
e dispara o PropertyChanged
evento sempre que a DateTime
propriedade é alterada.
O exemplo MvvmClock instancia esse ViewModel e usa associações de dados para o ViewModel para exibir informações atualizadas de data e hora.
Propriedades interativas em um ViewModel
As propriedades em um ViewModel podem ser mais interativas, conforme demonstrado pela SimpleMultiplierViewModel
classe, que faz parte do exemplo SimpleMultiplier. As ligações de dados fornecem valores multiplicando e multiplicando de dois Slider
elementos e exibem o produto com um Label
. No entanto, você pode fazer alterações extensivas nessa interface do usuário em XAML sem alterações consequentes no ViewModel ou no arquivo code-behind.
Um ViewModel de Cor
A ColorViewModel
biblioteca Book.Toolkit integra Xamarin.Formsos modelos de cores RGB e HSL. Ele é demonstrado no exemplo HslSliders:
Simplificando o ViewModel
O código em ViewModels pode ser simplificado definindo um OnPropertyChanged
método usando o CallerMemberName
atributo, que obtém o nome da propriedade de chamada automaticamente. A ViewModelBase
classe na Xamarin.Formsbiblioteca Book.Toolkit faz isso e fornece uma classe base para ViewModels.
A interface de comando
O MVVM funciona com associações de dados e as associações de dados funcionam com propriedades, portanto, o MVVM parece ser deficiente quando se trata de lidar com um Clicked
evento de um Button
ou um Tapped
evento de um TapGestureRecognizer
. Para permitir que ViewModels manipulem esses eventos, o oferece Xamarin.Forms suporte à interface de comando.
A interface de comando se manifesta Button
no com duas propriedades públicas:
Command
do tipoICommand
(definido noSystem.Windows.Input
namespace)CommandParameter
do tipoObject
Para dar suporte à interface de comando, um ViewModel deve definir uma propriedade do tipo ICommand
que é então associada a Command
dados à propriedade do Button
. A ICommand
interface declara dois métodos e um evento:
- Um
Execute
método com um argumento do tipoobject
- Um
CanExecute
método com um argumento do tipoobject
que retornabool
- Um
CanExecuteChanged
evento
Internamente, um ViewModel define cada propriedade do tipo ICommand
como uma instância de uma classe que implementa a ICommand
interface. Por meio da vinculação de dados, o Button
inicialmente chama o CanExecute
método e se desabilita se o método retornar false
. Ele também define um manipulador para o CanExecuteChanged
evento e chama CanExecute
sempre que esse evento é disparado. Se o Button
estiver habilitado, ele chamará o Execute
método sempre que for Button
clicado.
Você pode ter alguns ViewModels anteriores Xamarin.Formsao , e eles já podem oferecer suporte à interface de comando. Para novos ViewModels destinados a serem usados apenas com Xamarin.Forms, fornece uma Command
classe e uma Command<T>
classe que implementam a ICommand
interface. Xamarin.Forms O tipo genérico é o tipo do argumento para os Execute
métodos and CanExecute
.
Execuções de métodos simples
O exemplo PowersOfThree demonstra como usar a interface de comando em um ViewModel. A PowersViewModel
classe define duas propriedades do tipo ICommand
e também define duas propriedades privadas que ela passa para o construtor mais Command
simples. O programa contém associações de dados desse ViewModel para as Command
propriedades de dois Button
elementos.
Os Button
elementos podem ser facilmente substituídos por TapGestureRecognizer
objetos em XAML sem alterações de código.
Uma calculadora, quase
O exemplo AddingMachine usa os Execute
métodos e CanExecute
de ICommand
. Ele usa uma AdderViewModel
classe na Xamarin.Formsbiblioteca Book.Toolkit. O ViewModel contém seis propriedades do tipo ICommand
. Eles são inicializados a partir do construtor e Command
do Command
construtor de Command
e do Command<T>
construtor de .Command<T>
As chaves numéricas da máquina de adição são todas vinculadas à propriedade inicializada com Command<T>
, e um string
argumento identifica Execute
a CanExecute
chave específica.
ViewModels e o ciclo de vida do aplicativo
O AdderViewModel
usado no exemplo AddingMachine também define dois métodos chamados SaveState
e RestoreState
. Esses métodos são chamados do aplicativo quando ele entra no modo de suspensão e quando é iniciado novamente.