MVVM - Eventos
Um evento é uma construção de programação que reage a uma mudança de estado, notificando quaisquer terminais que tenham se registrado para notificação. Principalmente, os eventos são usados para informar a entrada do usuário por meio do mouse e do teclado, mas sua utilidade não se limita a isso. Sempre que uma mudança de estado é detectada, talvez quando um objeto foi carregado ou inicializado, um evento pode ser disparado para alertar quaisquer terceiros interessados.
Em um aplicativo WPF que usa o padrão de design MVVM (Model-View-ViewModel), o modelo de exibição é o componente responsável por manipular a lógica de apresentação e o estado do aplicativo.
O arquivo code-behind da visualização não deve conter nenhum código para manipular eventos que são gerados a partir de qualquer elemento da interface do usuário (UI), como um botão ou um ComboBox, nem deve conter nenhuma lógica específica de domínio.
Idealmente, o code-behind de uma View contém apenas um construtor que chama o método InitializeComponent e talvez algum código adicional para controlar ou interagir com a camada de view que é difícil ou ineficiente de expressar em XAML, por exemplo, animações complexas.
Vamos dar uma olhada em um exemplo simples de eventos de clique de botão em nosso aplicativo. A seguir está o código XAML do arquivo MainWindow.xaml no qual você verá dois botões.
<Window x:Class = "MVVMHierarchiesDemo.MainWindow"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local = "clr-namespace:MVVMHierarchiesDemo"
xmlns:views = "clr-namespace:MVVMHierarchiesDemo.Views"
xmlns:viewModels = "clr-namespace:MVVMHierarchiesDemo.ViewModel"
mc:Ignorable = "d"
Title = "MainWindow" Height = "350" Width = "525">
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Window.Resources>
<DataTemplate DataType = "{x:Type viewModels:CustomerListViewModel}">
<views:CustomerListView/>
</DataTemplate>
<DataTemplate DataType = "{x:Type viewModels:OrderViewModel}">
<views:OrderView/>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height = "Auto" />
<RowDefinition Height = "*" />
</Grid.RowDefinitions>
<Grid x:Name = "NavBar">
<Grid.ColumnDefinitions>
<ColumnDefinition Width = "*" />
<ColumnDefinition Width = "*" />
<ColumnDefinition Width = "*" />
</Grid.ColumnDefinitions>
<Button Content = "Customers"
Command = "{Binding NavCommand}"
CommandParameter = "customers"
Grid.Column = "0" />
<Button Content = "Order"
Command = "{Binding NavCommand}"
CommandParameter = "orders"
Grid.Column = "2" />
</Grid>
<Grid x:Name = "MainContent" Grid.Row = "1">
<ContentControl Content = "{Binding CurrentViewModel}" />
</Grid>
</Grid>
</Window>
Você pode ver que a propriedade Click do botão não é usada no arquivo XAML acima, mas as propriedades Command e CommandParameter são usadas para carregar diferentes exibições quando o botão é pressionado. Agora você precisa definir a implementação dos comandos no arquivo MainWindowViewModel.cs, mas não no arquivo View. A seguir está a implementação completa de MainWindowViewModel.
using MVVMHierarchiesDemo.ViewModel;
using MVVMHierarchiesDemo.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MVVMHierarchiesDemo {
class MainWindowViewModel : BindableBase {
public MainWindowViewModel() {
NavCommand = new MyICommand<string>(OnNav);
}
private CustomerListViewModel custListViewModel = new CustomerListViewModel();
private OrderViewModel orderViewModelModel = new OrderViewModel();
private BindableBase _CurrentViewModel;
public BindableBase CurrentViewModel {
get { return _CurrentViewModel; }
set { SetProperty(ref _CurrentViewModel, value); }
}
public MyICommand<string> NavCommand { get; private set; }
private void OnNav(string destination) {
switch (destination) {
case "orders":
CurrentViewModel = orderViewModelModel;
break;
case "customers":
default:
CurrentViewModel = custListViewModel;
break;
}
}
}
}
Derive todos os seus ViewModels da classe BindableBase. Quando o código acima for compilado e executado, você verá a seguinte saída.
Como você pode ver, adicionamos apenas dois botões e um CurrentViewModel em nossa MainWindow. Agora, se você clicar em qualquer botão, ele navegará para aquela Visualização específica. Vamos clicar no botão Clientes e você verá que a CustomerListView é exibida.
Recomendamos que você execute o exemplo acima em um método passo a passo para melhor compreensão.