venerdì 5 marzo 2010

Appunti di WPF – Sesta Puntata – Gestire l’applicazione

Un’applicazione WPF, in maniera analoga a quanto accade per un’applicazione Windows Forms, ha un ben determinato ciclo di vita.

Come già visto nei tutorial precedenti, in un progetto WPF troviamo un file denominato Application.xaml (e relativo code behind Application.xaml.vb). Questo file descrive la classe che incapsula il comportamento e le proprietà della nostra applicazione WPF.

In particolare in questo file xaml possono trovare posto quelle risorse che utilizzeremo all’interno dell’applicazione e nel file di code behind possiamo gestire quegli eventi caratteristici del ciclo di vita dell’applicazione.

Prima di analizzare in dettaglio quali sono gli eventi che abbiamo a disposizione nella nostra applicazione WPF, vediamo come è definito il codice XAML del file Application:

  1. <Application x:Class="Application"
  2.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.     StartupUri="MainWindow.xaml" >
  5.     <Application.Resources>
  6.         
  7.     </Application.Resources>
  8. </Application>

Possiamo vedere che :

· la nostra classe Application deriva dalla classe Application di WPF;

· è impostata la proprietà StartupUri con l’indicazione della finestra principale dell’applicazione;

· prevede una collezione di risorse (vuota nell’esempio riportato).

Vediamo, ora, cosa accade alla nostra classe Application nel momento in cui compiliamo. Se apriamo la cartella dei file obj del progetto WPF (visibile solo se abbiamo attivato l’opzione di visualizzazione di tutti i file di progetto), possiamo osservare la presenza di un file particolare denominato Application.g.vb.

WPF_06_Application_Fig1

Questo file è generato dall’ambiente di sviluppo e, in buona sostanza riporta il seguente codice:

  1. '''<summary>
  2. '''Application
  3. '''</summary>
  4. <System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")>  _
  5. Partial Public Class Application
  6.     Inherits System.Windows.Application
  7.     
  8.     '''<summary>
  9.     '''InitializeComponent
  10.     '''</summary>
  11.     <System.Diagnostics.DebuggerNonUserCodeAttribute()>  _
  12.     Public Sub InitializeComponent()
  13.         
  14.         #ExternalSource("..\..\..\Application.xaml",4)
  15.         Me.StartupUri = New System.Uri("MainWindow.xaml", System.UriKind.Relative)
  16.         
  17.         #End ExternalSource
  18.     End Sub
  19.     
  20.     '''<summary>
  21.     '''Application Entry Point.
  22.     '''</summary>
  23.     <System.STAThreadAttribute(),  _
  24.      System.Diagnostics.DebuggerNonUserCodeAttribute()>  _
  25.     Public Shared Sub Main()
  26.         Dim app As Application = New Application()
  27.         app.InitializeComponent
  28.         app.Run
  29.     End Sub
  30. End Class

Di fatto, questo codice fornisce l’entry point di avvio dell’applicazione (metodo statico Main) e il metodo nel quale si definisce quale è la finestra iniziale (InitializeComponent).

Inoltre possiamo osservare che la classe definita è di tipo parziale, infatti verrà fusa con la classe definita nel code behind Application.xaml.vb.

L’immagine seguente ci mostra quali sono i possibili eventi che possiamo gestire nella classe Application:

WPF_06_Application_Fig2

Tralasceremo, in questo contesto tutti gli eventi di navigazione (tipo Navigated, Navigating, etc., etc.) e ci concentreremo sui rimanenti, decisamente più interessanti in questa fase di apprendimento dell’infrastruttura applicativa:

· Activated : invocato quando una delle finestre dell’applicazione viene attivata, ad esempio se ci spostiamo da un’altra applicazione nella nostra;

· Deactivated : invocato quando, ad esempio, ci spostiamo su di un’altra applicazione facendo perdere il “focus” alla nostra;

· DisptacherUnhandledException : invocato quando una eccezione occorsa all’interno dell’applicazione non viene gestita. Utile per collezionare i dati delle eccezioni e, soprattutto, per non far terminare l’applicazione in maniera poco pulita;

· Exit : invocato nel momento in cui si chiude l’applicazione. Non è possibile, in questo evento annullare la chiusura dell’applicazione stessa ma possiamo scrivere il metodo Main per rilanciare (tramite il metodo Run della classe application) l’applicazione stessa. Nel gestore di questo evento possiamo impostare il codice di uscita dell’applicazione;

· SessionEnding : viene invocato nel momento in cui un utente di windows si disconnette dalla sessione (ad esempio per uno shutdown del sistema);

· Startup : viene invocato nel momento in cui viene eseguito il metodo Run della classe Application.

Per quanto riguarda la modalità con cui un applicazione può essere chiusa, abbiamo a disposizione la proprietà ShutdownMode della classe application che può assumere i seguenti valori:

· OnLastWindowClose : l’applicazione viene chiusa quando l’ultima finestra viene chiusa;

· OnMainWindowClose : l’applicazione viene chiusa quando la finestra principale viene chiusa (è l’impostazione di default);

· OnExplicitShutdown : la chiusura dell’applicazione deve essere effettuata tramite il metodo Shutdown della classe Application.

All’interno del nostro codice possiamo interagire con l’applicazione in esecuzione attraverso la proprietà statica (di sola lettura) Current della classe Application. Ad esempio, vogliamo recuperare la finestra principale dell’applicazione possiamo utilizzare la proprietà Application.Current.MainWindow.

Infine, per concludere, possiamo gestire, all’avvio della nostra applicazione, eventuali argomenti passati all’eseguibile. Gli argomenti sono contenuti nell’array di stringhe Args dell’oggetto StartupEventArgs passato nell’evento di startup dell’applicazione.


Scarica la versione PDF dell'articolo. Scarica la versione Amazon Kindle dell'articolo.

Nessun commento: