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 concluídos.
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 a 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
- A exibição é a interface do usuário ou a camada de apresentação, geralmente implementada no XAML
- O ViewModel conecta o Modelo e o Modo de Exibição
O Modelo ignora o ViewModel e o ViewModel ignora a Exibição. Essas três camadas geralmente se conectam umas às outras usando os seguintes mecanismos:
Em muitos programas menores (e até mesmo maiores), muitas vezes o Modelo está ausente ou sua funcionalidade é integrada ao ViewModel.
ViewModels e associação de dados
Para se envolver em associações de dados, um ViewModel deve ser capaz de notificar o Modo de Exibição quando uma propriedade do ViewModel for alterada. O ViewModel faz isso implementando a INotifyPropertyChanged
interface no System.ComponentModel
namespace. Isso faz parte do .NET em vez de Xamarin.Forms. (Geralmente, o ViewModels tenta 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
O DateTimeViewModel
na Xamarin.Formsbiblioteca Book.Toolkit define uma propriedade do tipo DateTime
que é alterada com base em um temporizador. A classe implementa INotifyPropertyChanged
e aciona o PropertyChanged
evento sempre que a DateTime
propriedade é alterada.
O exemplo MvvmClock cria uma instância desse 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 associações de dados fornecem valores multiplicando e multiplicador de dois Slider
elementos e exibem o produto com um Label
. No entanto, você pode fazer alterações extensas nessa interface do usuário no XAML sem alterações conseqüentes no ViewModel ou no arquivo code-behind.
Um ViewModel de Cor
O ColorViewModel
na Xamarin.Formsbiblioteca Book.Toolkit integra os modelos de cores RGB e HSL. Ela é demonstrada 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 Command
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 manipule esses eventos, Xamarin.Forms dá suporte à interface de comando.
A interface de comando se manifesta no Button
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 aos dados à Command
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 associação de dados, o Button
inicialmente chama o CanExecute
método e desabilita-se 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 o Button
for clicado.
Você pode ter alguns ViewModels que antecedem Xamarin.Formse eles já podem dar 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
Xamarin.Forms interface. O tipo genérico é o tipo do argumento para os Execute
métodos e CanExecute
.
Execuções de método 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 simplesCommand
. O programa contém associações de dados deste ViewModel às 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 do Command
construtor e Command
do construtor de Command
e do Command<T>
construtor de Command<T>
. As chaves numéricas do computador de adição estão todas associadas à propriedade inicializada com Command<T>
e um string
argumento para Execute
e CanExecute
identifica a 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 em suspensão e quando ele é iniciado novamente.