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 a 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 View é a interface do usuário ou a camada de apresentação, geralmente implementada em XAML
- O ViewModel conecta o Model e o View
O Modelo 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 Modelo está ausente ou sua funcionalidade é integrada ao ViewModel.
ViewModels e vinculação de dados
Para participar de 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
interface no System.ComponentModel
namespace. Isso faz parte do .NET e não Xamarin.Formsdo . (Geralmente, 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 muda 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, como demonstrado pela SimpleMultiplierViewModel
classe, que faz parte do exemplo SimpleMultiplier . As associações de dados fornecem valores multiplicadores e multiplicadores de dois Slider
elementos e exibem o produto com um Label
arquivo . No entanto, você pode fazer alterações extensas nessa interface do usuário em XAML sem alterações consequentes 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. Isso é 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 trabalha com associações de dados, e as ligaçõ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 oferece 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 oferecer suporte à interface de comando, um ViewModel deve definir uma propriedade do tipo ICommand
que é, em seguida, dados vinculados à 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 é acionado. Se o Button
estiver habilitado, ele chamará o Execute
método sempre que o Button
for 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 somente 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 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 ele passa para o construtor mais Command
simples. O programa contém ligações de dados deste 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 faz uso dos Execute
métodos e CanExecute
do ICommand
. Ele usa uma AdderViewModel
classe na Xamarin.Formsbiblioteca Book.Toolkit. O ViewModel contém seis propriedades do tipo ICommand
. Estes são inicializados a partir do Command
construtor e Command
construtor de Command
e o 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 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 a partir do aplicativo quando ele entra em repouso e quando ele inicia novamente.