Architettura Model-View-ViewModel in un'applicazione WPF
di Cristian Civera, in Windows Presentation Foundatio, 24 febbraio 2009
Command pattern
Ogni applicazione ha solitamente un'interazione con l'utente e per farlo si usano i controlli presenti in WPF che reagiscono a mouse, stylus e tastiera. In WPF è presente un'interfaccia ICommand il cui scopo è rappresentare un comando, restituire la possibilità di eseguirlo e eseguire effettivamente l'operazione, ed è così definita:
public interface ICommand { event EventHandler CanExecuteChanged; bool CanExecute(object parameter); void Execute(object parameter); }
Inoltre, tramite l'interfaccia ICommandSource, i controlli presenti in WPF possono essere associati ai comandi, abilitarsi o meno in funzione di CanExecute ed eseguire il metodo Execute sul loro evento predefinito. Questi controlli sono Button, MenuItem, CheckBox, RadioButton, HyperLink, KeyBinding e MouseBinding e sebbene in parte limitati sulla possibilità di eseguire il comando solo nel loro evento predefinito (esempio: il click su Button), permettono di separare il codice dall'interfaccia, di avere un comportamento automatico di posso o non posso eseguire, e di testare il comando stesso senza provare l'interfaccia.
L'idea applicata al ViewModel quindi, è quella di esporre tramite esso una serie di comandi di competenza così da poter essere sfruttati una o più volte all'interno della View. Ad esempio, il comando per il refresh dei thread, può essere esposto tramite una proprietà RefreshCommand inizializzata nel costruttore:
private ICommand _refreshCommand; public MainWindowViewModel() { _refreshCommand = new RelayCommand(p => RefreshAsync(), p => !this.IsLoading); } public ICommand RefreshCommand { get { return _refreshCommand; } }
La classe RelayCommand è creata appositamente e riceve un delegate da chiamare per l'esecuzione del comando e un delegate da chiamare per conoscere se è possibile chiamare il comando. In questo caso si valuta la proprietà IsLoading così da non eseguire il refresh se è già in corso tale operazione. Diversamente da quanto si può essere abituati, non si usano i RoutedCommand o i RoutedUICommand poiché questi si affidano ai CommandBinding e richiedono che dal markup si debba specificare i delegate da eseguire, inquinando l'approccio MVVM. Ecco come è definita la classe RelayCommand:
public class RelayCommand : ICommand { readonly Action<Object> _execute; readonly Predicate<Object> _canExecute; public RelayCommand(Action<Object> execute, Predicate<Object> canExecute) { if (execute == null) throw new ArgumentNullException("execute"); _execute = execute; _canExecute = canExecute; } [DebuggerStepThrough] public bool CanExecute(object parameter) { return _canExecute == null ? true : _canExecute(parameter); } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } public void Execute(object parameter) { _execute(parameter); } }
Interessante l'evento RequerySuggested della classe statica CommandManager che permette di conoscere quando il motore di gestione dei comandi invalida lo stato di essi e rivaluta tutte le proprietà CanExecute. In questo modo tutti gli elementi dell'interfaccia cambiano e, per esempio, un pulsante si disabilita se non è possibile eseguire il comando ad esso associato. La rivalutazione di tale proprietà avviene in automatico ogni qual volta l'applicazione riceve un input da tastiera, la pressione del mouse, perde o riceve il focus. Qualora la si voglia forzare è possibile chiamare CommandManager.InvalidateRequerySuggested.
Nella View infine il comando può essere sfruttato una o più volte semplicemente con un'espressione di Binding.
<ToolBarTray DockPanel.Dock="Top"> <ToolBar> <Button Command="{Binding RefreshCommand}">Refresh</Button> </ToolBar> </ToolBarTray>
Attenzione: Questo articolo contiene un allegato
Contenuti dell'articolo
- Pagina 1
- Pagina 2
- Pagina 3
- Pagina 4
- Pagina 5
- Pagina 6
- Pagina 7
Sullo stesso argomento
-
#117 - Effettuare stampe con System.Printing
-
Entity Framework e la generazione di codice POCO
-
Mostrare la WebCam in Silverlight
-
Costruire una chat per Silverlight con il PollingDuplexHttpBinding
-
Realizzare applicazioni web on the cloud con Microsoft Windows Azure
-
#161 - Clonare e manipolare Message in WCF
-
Windows Server AppFabric va in beta 2
-
#40 - Animazione di un oggetto con traiettoria ellittica in Silverlight 2.0
-
Disinstallare la beta 2 prima di installare la RC di VS 2010
-
MetadataDiffViewer: aggiornato al .NET Framework 4.0, Silverlight 4.0 e Sharepoint 2010
-
#139 - Invocare servizi in asincrono con WCF
-
Architettura del software: l'object model per le applicazioni web

















Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.