MVVM - Eventi
Un evento è un costrutto di programmazione che reagisce a un cambiamento di stato, notificando gli endpoint che si sono registrati per la notifica. In primo luogo, gli eventi vengono utilizzati per informare un input dell'utente tramite il mouse e la tastiera, ma la loro utilità non è limitata a questo. Ogni volta che viene rilevato un cambiamento di stato, magari quando un oggetto è stato caricato o inizializzato, un evento può essere attivato per avvisare eventuali terze parti interessate.
In un'applicazione WPF che usa il modello di progettazione MVVM (Model-View-ViewModel), il modello di visualizzazione è il componente responsabile della gestione della logica e dello stato di presentazione dell'applicazione.
Il file code-behind della visualizzazione non deve contenere codice per gestire gli eventi generati da qualsiasi elemento dell'interfaccia utente (UI) come un pulsante o un controllo ComboBox né deve contenere alcuna logica specifica del dominio.
Idealmente, il code-behind di una vista contiene solo un costruttore che chiama il metodo InitializeComponent e forse un po 'di codice aggiuntivo per controllare o interagire con il livello di visualizzazione che è difficile o inefficiente da esprimere in XAML, ad esempio animazioni complesse.
Diamo un'occhiata a un semplice esempio di eventi di clic sui pulsanti nella nostra applicazione. Di seguito è riportato il codice XAML del file MainWindow.xaml in cui vedrai due pulsanti.
<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>
Puoi vedere che la proprietà Click del pulsante non viene utilizzata nel file XAML precedente, ma le proprietà Command e CommandParameter vengono utilizzate per caricare visualizzazioni diverse quando viene premuto il pulsante. Ora è necessario definire l'implementazione dei comandi nel file MainWindowViewModel.cs ma non nel file Visualizza. Di seguito è riportata l'implementazione completa di 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;
}
}
}
}
Deriva tutti i tuoi ViewModels dalla classe BindableBase. Quando il codice precedente viene compilato ed eseguito, vedrai il seguente output.
Come puoi vedere, abbiamo aggiunto solo due pulsanti e un CurrentViewModel sulla nostra MainWindow. Ora, se fai clic su qualsiasi pulsante, passerà a quella particolare vista. Facciamo clic sul pulsante Clienti e vedrai che viene visualizzato CustomerListView.
Ti consigliamo di eseguire l'esempio precedente in un metodo passo passo per una migliore comprensione.