Architettura Model-View-ViewModel in un'applicazione WPF
di Cristian Civera, in Windows Presentation Foundatio, 24 febbraio 2009
Asynchronous Pattern
Il comando di refresh descritto nel paragrafo precedente si appoggia sulla proprietà IsLoading, perché si vuole ipotizzare che l'esecuzione dell'eventuali query o chiamatal servizio, possano impiegare qualche secondo e non si vuole rendere bloccante l'interfaccia. Nel metodo RefreshAsync occorre quindi invocare in asincrono ForumManager.GetAllThreads, per esempio attraverso il ThreadPool e cambiare IsLoading ad inizio e a fine operazione. La lista dei thread ottenuta deve essere poi convertita in ThreadPostViewModel e popolare la proprietà Threads così da poter permette la visualizzazione e l'adozione di una vista per ogni thread. Tale proprietà è di tipo ObservableCollection
Tutto questo automatismo comporta però un problema dovuto alla gestione dell'interfaccia grafica. Ogni modifica agli elementi dell'interfaccia, va effetuata sul thread UI attraverso il Dispatcher che ha il compito di gestire la coda di operazioni da eseguire per il disegno dell'interfaccia, le animazioni ecc. Per gli scopi che il pattern MVVM si propone però, sfruttare direttamente il Dispatcher e porsi questa problematica in realtà vanno in conflitto con esso.
In aiuto vengono alcune classi introdotte con il .NET Framework 2.0 e in particolare con il tipo AsyncOperationManager che attraverso il metodo CreateOperation permette di rappresentare un'operazione e di notificare la sua conclusione attraverso un delegate che viene invocato attraverso il SynchronizationContext corrente. Quest'ultimo varia a seconda dell'ambiente in cui gira il codice e può assumere forma nel Dispatcher di WPF, di Silverlight o nella message pump delle WinForm, garantendo di poter scrivere un ModelView il più indipendente possibile.
Di seguito quindi il metodo RefreshAsync:
public void RefreshAsync() { // Notifico l'esecuzione asincrona this.IsLoading = true; // Creo un'operazione che rappresenta il refresh AsyncOperation refreshOperation = AsyncOperationManager.CreateOperation(null); // Invoco in asincrono ThreadPool.QueueUserWorkItem(delegate { try { IEnumerable<ThreadPost> threads = ForumManager.GetAllThreads(); // Invoco sul thread UI la funzione refreshOperation.PostOperationCompleted(OnRefreshAsyncCompleted, threads); } catch (Exception) { refreshOperation.PostOperationCompleted(OnRefreshAsyncFailed, null); } }, refreshOperation); }
Il metodo OnRefreshAsyncFailed, invocato sul threadUI in caso di errori, non fa altro che impostare IsLoading a false e invalidare lo stato dei comandi.
private void OnRefreshAsyncFailed(object arg) { this.IsLoading = false; CommandManager.InvalidateRequerySuggested(); }
Il metodo OnRefreshAsyncCompleted invece prepara i thread e reimposta lo stato:
private void OnRefreshAsyncCompleted(object arg) { this.IsLoading = false; CommandManager.InvalidateRequerySuggested(); // Preparo il ViewModel per i thread IEnumerable<ThreadPost> threads = (IEnumerable<ThreadPost>)arg; this.Threads.Clear(); foreach (ThreadPost tp in threads) this.Threads.Add(new ThreadPostViewModel(tp)); }
Eventualmente, è possibile oltre a PostOperationCompleted, invoicare solamente il metodo Post per non terminare l'operazione, ma semplicemente notificare il progresso di un'operazione, oppure esporre un evento RefreshAsyncCompleted da invocare sempre con Post o PostOperationCompleted per facilitare l'utilizzo di eventuali EventTrigger nella View.
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
-
ASPItalia.com su twitter: tutte le novità su #netfx, #aspnet, #silverlight in salsa breve. stay tuned! #aspitalia
-
Le problematiche più comuni di un'architettura M-V-VM con WPF
-
.NET Framework 4.0 Beta 2: ASP.NET MVC 2 Preview 2
-
#999 - Mostrare una finestra di dialogo popolata tramite AJAX utilizzando jQuery
-
Comunicazione TCP tra Silverlight e WPF
-
#1009 - Evitare attacchi basati su tampering dei dati in ASP.NET MVC
-
Enumeratori: flags and extensions
-
.NET Framework 4.0 beta 1: WPF 4.0
-
#146 - Simulare la clausola SQL Exists con il metodo Any in LINQ to Entities
-
#adonetdataservices v1.5 CTP 2 con supporto al #databinding per #wpf e #silverlight su http://u.aspitalia.com/ac
-
Mostrare la WebCam in Silverlight
-
#119 - Creare servizi WCF per applicazioni Silverlight

















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