MVVM - Eventos
Un evento es una construcción de programación que reacciona a un cambio de estado, notificando cualquier punto final que se haya registrado para notificación. Principalmente, los eventos se utilizan para informar la entrada de un usuario a través del mouse y el teclado, pero su utilidad no se limita a eso. Siempre que se detecta un cambio de estado, tal vez cuando se ha cargado o inicializado un objeto, se puede disparar un evento para alertar a los terceros interesados.
En una aplicación WPF que usa el patrón de diseño MVVM (Model-View-ViewModel), el modelo de vista es el componente responsable de manejar la lógica y el estado de presentación de la aplicación.
El archivo de código subyacente de la vista no debe contener código para manejar eventos que se generen desde cualquier elemento de la interfaz de usuario (UI), como un botón o un cuadro combinado, ni debe contener ninguna lógica específica de dominio.
Idealmente, el código subyacente de una vista contiene solo un constructor que llama al método InitializeComponent y quizás algún código adicional para controlar o interactuar con la capa de vista que es difícil o ineficiente de expresar en XAML, por ejemplo, animaciones complejas.
Echemos un vistazo a un ejemplo simple de eventos de clic de botón en nuestra aplicación. A continuación se muestra el código XAML del archivo MainWindow.xaml en el que verá dos botones.
<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>
Puede ver que la propiedad Click del botón no se usa en el archivo XAML anterior, pero las propiedades Command y CommandParameter se usan para cargar diferentes vistas cuando se presiona el botón. Ahora necesita definir la implementación de los comandos en el archivo MainWindowViewModel.cs pero no en el archivo Ver. A continuación se muestra la implementación 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 sus ViewModels de la clase BindableBase. Cuando se compile y ejecute el código anterior, verá el siguiente resultado.
Como puede ver, hemos agregado solo dos botones y un CurrentViewModel en nuestra MainWindow. Ahora, si hace clic en cualquier botón, navegará a esa Vista en particular. Hagamos clic en el botón Clientes y verá que se muestra CustomerListView.
Le recomendamos que ejecute el ejemplo anterior en un método paso a paso para una mejor comprensión.