Condividi tramite


Cenni preliminari sulla gestione di applicazioni

In questo argomento viene fornita una panoramica dei servizi Windows Presentation Foundation (WPF) per la creazione e gestione di applicazioni. Il kernel di un'applicazione WPF è la classe Application, che supporta diversi servizi di base dell'applicazione. Nell'argomento viene fornita un'introduzione ai servizi più importanti.

Nel presente argomento sono contenute le seguenti sezioni.

  • Classe Application
  • Definizione di applicazione
  • Ottenere l'applicazione corrente
  • Durata dell'applicazione
  • Altri servizi dell'applicazione
  • Argomenti correlati

Classe Application

Un'applicazione è costituita da diversi elementi specifici della stessa, inclusi user interface (UI), regola business, logica di accesso ai dati, controlli e dati. In genere questi elementi differiscono da un'applicazione all'altra. Tuttavia, tutte le applicazioni tendono a condividere un insieme comune di funzionalità che ne facilita l'implementazione e la gestione. In WPF queste funzionalità comuni con ambito di applicazione vengono incapsulate dalla classe Application, che fornisce i seguenti servizi:

  • Creazione e gestione dell'infrastruttura di applicazioni comuni.

  • Controllo della durata di un'applicazione e interazione con la stessa.

  • Recupero ed elaborazione dei parametri della riga di comando.

  • Condivisione di proprietà e risorse con ambito di applicazione.

  • Rilevamento e risposta a eccezioni non gestite.

  • Restituzione di codici di uscita.

  • Gestione di finestre in applicazioni autonome (vedere Cenni preliminari sulle finestre WPF).

  • Rilevamento e gestione dello spostamento (vedere Cenni preliminari sulla navigazione).

Per utilizzare questi servizi nell'applicazione, è necessario utilizzare la classe Application per implementare una definizione di applicazione.

Definizione di applicazione

Una definizione di applicazione WPFè una classe che deriva da Application ed è configurata con un'impostazione Microsoft build engine (MSBuild) speciale.

Implementazione di una definizione di applicazione

Una definizione di applicazione WPF tipica viene implementata mediante markup e code-behind. In questo modo è possibile utilizzare il markup per impostare in modo dichiarativo le proprietà dell'applicazione, le risorse e registrare gli eventi, gestendo al contempo gli eventi e implementando il comportamento specifico dell'applicazione nel code-behind.

Nell'esempio seguente viene illustrato come implementare una definizione di applicazione tramite markup e code-behind:

<Application 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" 
  x:Class="SDKSample.App" />

Imports Microsoft.VisualBasic
Imports System.Windows ' Application

Namespace SDKSample
    Partial Public Class App
        Inherits Application
    End Class
End Namespace
using System.Windows;  // Application

namespace SDKSample
{
    public partial class App : Application { }
}

Per consentire il funzionamento congiunto di un file di markup e un file code-behind, è necessario soddisfare le seguenti condizioni:

  • Nel markup, l'elemento Application deve includere l'attributo x:Class. Quando l'applicazione viene compilata, la presenza di x:Class nel file di markup fa sì che MSBuild crei una classe partial derivante da Application e avente il nome specificato dall'attributo x:Class. Questo richiede l'aggiunta di una dichiarazione dello spazio dei nomi XML per lo schema XAML (xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml").

  • Nel code-behind, la classe deve essere una classe partial con lo stesso nome specificato dall'attributo x:Class nel markup e deve derivare da Application. In questo modo il file code-behind può essere associato alla classe partial generata per il file di markup durante la compilazione dell'applicazione (vedere Compilazione di un'applicazione WPF (WPF)).

NotaNota

Quando si crea un nuovo progetto di applicazione WPF o di applicazione browser WPF utilizzando Microsoft Visual Studio, una definizione di applicazione viene inclusa per impostazione predefinita e definita tramite markup e code-behind.

Questo codice è il requisito minimo necessario per implementare una definizione di applicazione. È tuttavia necessario creare una configurazione MSBuild aggiuntiva per la definizione di applicazione prima di compilare ed eseguire l'applicazione.

Configurazione della definizione di applicazione per MSBuild

L'esecuzione delle applicazioni autonome e delle XAML browser applications (XBAPs) richiede l'implementazione di un determinato livello di infrastruttura. La parte più importante di questa infrastruttura è il punto di ingresso. Quando un'applicazione viene avviata da un utente, il sistema operativo chiama il punto di ingresso, una funzione nota per l'avvio di applicazioni.

In precedenza, occorreva che gli sviluppatori scrivessero personalmente l'intero codice o parte di esso, a seconda della tecnologia. WPF genera invece questo codice quando il file di markup della definizione di applicazione viene configurato come elemento ApplicationDefinition MSBuild, come illustrato nel seguente file di progetto MSBuild:

<Project 
  DefaultTargets="Build"
  xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
  ...
  <ApplicationDefinition Include="App.xaml" />
  <Compile Include="App.xaml.cs" />
  ...
</Project>

Poiché il file code-behind contiene codice, viene contrassegnato come elemento Compile MSBuild, come vuole la prassi.

L'applicazione di queste configurazioni MSBuild ai file di markup e code-behind di una definizione di applicazione fa sì che MSBuild generi codice analogo a quello riportato di seguito:


Imports Microsoft.VisualBasic
Imports System ' STAThread
Imports System.Windows ' Application

Namespace SDKSample
    Public Class App
        Inherits Application
        Public Sub New()
        End Sub
        <STAThread>
        Public Shared Sub Main()
            ' Create new instance of application subclass
            Dim app As New App()

            ' Code to register events and set properties that were
            ' defined in XAML in the application definition
            app.InitializeComponent()

            ' Start running the application
            app.Run()
        End Sub

        Public Sub InitializeComponent()


...


        End Sub
    End Class
End Namespace
using System; // STAThread
using System.Windows; // Application

namespace SDKSample
{
    public class App : Application
    {
        public App() { }
        [STAThread]
        public static void Main()
        {
            // Create new instance of application subclass
            App app = new App();

            // Code to register events and set properties that were
            // defined in XAML in the application definition
            app.InitializeComponent();

            // Start running the application
            app.Run();
        }

        public void InitializeComponent()
        {


...


        }
    }
}

Il codice risultante integra la definizione di applicazione con un codice di infrastruttura aggiuntivo, il quale include il metodo del punto di ingresso Main. L'attributo STAThreadAttribute viene applicato al metodo Main per indicare che il thread principale dell'UI per l'applicazione WPF è un thread STA, necessario nel caso di applicazioni WPF. Quando viene chiamato, Main crea una nuova istanza di App prima di chiamare il metodo InitializeComponent per registrare gli eventi e impostare le proprietà implementate nel markup. Poiché InitializeComponent viene generato da WPF, non sarà necessario chiamarlo in modo esplicito da una definizione di applicazione, come avviene invece per le implementazioni di Page e Window. Infine viene chiamato il metodo Run per avviare l'applicazione.

Ottenere l'applicazione corrente

Poiché i servizi della classe Application vengono condivisi nell'ambito di un'applicazione, può esistere un'unica istanza della suddetta classe per AppDomain. Per fare in modo che questo accada, la classe Application viene implementata come classe Singleton (vedere Implementing Singleton in C# - informazioni in lingua inglese), la quale crea un'unica istanza di se stessa e ne fornisce l'accesso condiviso mediante la proprietà Current static.

Nel codice riportato di seguito viene illustrato come acquisire un riferimento all'oggetto Application per AppDomain corrente.

            ' Get current application
            Dim current As Application = App.Current
// Get current application
Application current = App.Current;

Current restituisce un riferimento a un'istanza della classe Application. Per ottenere un riferimento alla classe derivata Application è necessario eseguire il cast del valore della proprietà Current, come illustrato nell'esempio che segue.

            ' Get strongly-typed current application
            Dim appCurrent As App = CType(App.Current, App)
// Get strongly-typed current application
App app = (App)App.Current;

Il valore di Current può essere controllato in qualsiasi momento nel corso della durata di un oggetto Application. Tuttavia, è necessario prestare attenzione. Una volta creata un'istanza della classe Application, lo stato dell'oggetto Application diventa incoerente per un determinato periodo di tempo. Durante questo periodo, Application esegue le varie attività di inizializzazione richieste dal codice per l'esecuzione, incluso stabilire l'infrastruttura dell'applicazione, impostare le proprietà e registrare gli eventi. Se si tenta di utilizzare l'oggetto Application durante questo periodo, il codice potrebbe avere risultati imprevisti, in particolare se dipende dalle varie proprietà di Application impostate.

Nel momento in cui Application completa le operazioni di inizializzazione, ha inizio la reale durata.

Durata dell'applicazione

La durata di un'applicazione WPF è segnata da diversi eventi generati da Application, grazie ai quali è possibile sapere quando l'applicazione è stata avviata, attivata e disattivata, nonché chiusa.

Nella presente sezione sono contenute le seguenti sottosezioni.

  • Schermata iniziale
  • Avvio di un'applicazione
  • Visualizzazione di un'interfaccia utente
  • Elaborazione degli argomenti della riga di comando
  • Attivazione e disattivazione di un'applicazione
  • Chiusura di un'applicazione
  • Eccezioni non gestite
  • Eventi di durata dell'applicazione

Schermata iniziale

A partire da .NET Framework 3.5 SP1, è possibile specificare un'immagine da utilizzare in una finestra di avvio o schermata iniziale. La classe SplashScreen agevola la visualizzazione di una finestra di avvio mentre l'applicazione viene caricata. La finestra SplashScreen viene creata e visualizzata prima che venga chiamato Run. Per ulteriori informazioni, vedere Tempo di avvio delle applicazioni e Procedura: aggiungere una schermata iniziale in un'applicazione WPF.

Avvio di un'applicazione

Una volta chiamato Run e inizializzata l'applicazione, questa è pronta per essere eseguita. Questo momento corrisponde al momento in cui viene generato l'evento Startup:


Imports Microsoft.VisualBasic
Imports System.Windows ' Application, StartupEventArgs, WindowState

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
            ' Application is running


...


        End Sub
    End Class
End Namespace
using System.Windows; // Application, StartupEventArgs, WindowState

namespace SDKSample
{
    public partial class App : Application
    {
        void App_Startup(object sender, StartupEventArgs e)
        {
            // Application is running


...


        }
    }
}

A questo punto della durata di un'applicazione, l'operazione più comune da eseguire è la visualizzazione di un'UI.

Visualizzazione di un'interfaccia utente

Gran parte delle applicazioni Windows autonome aprono un oggetto Window una volta iniziata l'esecuzione. Il gestore eventi Startup è uno dei percorsi da cui è possibile eseguire questa operazione, come illustrato nel codice che segue.

<Application
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.App" 
  Startup="App_Startup" />

Imports Microsoft.VisualBasic
Imports System.Windows ' Application, StartupEventArgs

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
            ' Open a window
            Dim window As New MainWindow()
            window.Show()
        End Sub
    End Class
End Namespace
using System.Windows; // Application, StartupEventArgs

namespace SDKSample
{
    public partial class App : Application
    {
        void App_Startup(object sender, StartupEventArgs e)
        {
            // Open a window
            MainWindow window = new MainWindow();
            window.Show();
        }
    }
}
NotaNota

Per impostazione predefinita, il primo oggetto Window di cui viene creata un'istanza in un'applicazione autonoma diventa la finestra principale dell'applicazione.A questo oggetto Window fa riferimento la proprietà Application.MainWindow.Il valore della proprietà MainWindow può essere modificato a livello di codice se si desidera che la finestra principale sia una finestra diversa dal primo oggetto Window di cui è stata creata un'istanza.

Al primo avvio di un'applicazione XBAP, è probabile che si verifichi uno spostamento su un oggetto Page, come illustrato nel codice che segue.

<Application 
  x:Class="SDKSample.App"
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  Startup="App_Startup" />

Imports System ' Uri, UriKind, EventArgs, Console
Imports System.Windows ' Application, StartupEventArgs
Imports System.Windows.Navigation ' NavigationWindow

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
            CType(Me.MainWindow, NavigationWindow).Navigate(New Uri("HomePage.xaml", UriKind.Relative))
        End Sub
    End Class
End Namespace
using System; // Uri, UriKind, EventArgs, Console
using System.Windows; // Application, StartupEventArgs
using System.Windows.Navigation; // NavigationWindow

namespace SDKSample
{
    public partial class App : Application
    {        
        void App_Startup(object sender, StartupEventArgs e)
        {
            ((NavigationWindow)this.MainWindow).Navigate(new Uri("HomePage.xaml", UriKind.Relative));
        }
    }
}

Se Startup viene gestito per la sola apertura di un oggetto Window o lo spostamento su un oggetto Page, è possibile impostare l'attributo StartupUri nel markup.

Nell'esempio seguente viene illustrato come utilizzare StartupUri da un'applicazione autonoma per aprire un oggetto Window.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="MainWindow.xaml" />

Nell'esempio seguente viene illustrato come utilizzare StartupUri da un'applicazione XBAP per spostarsi su un oggetto Page.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="HomePage.xaml" />

Questo markup ha lo stesso effetto del codice precedente per l'apertura di una finestra.

NotaNota

Per ulteriori informazioni sullo spostamento, vedere Cenni preliminari sulla navigazione.

L'evento Startup deve essere gestito per l'apertura di un oggetto Window nei seguenti casi: se è necessario crearne un'istanza tramite un costruttore non predefinito, se è necessario impostarne le proprietà o sottoscriverne gli eventi prima di visualizzarlo oppure se occorre elaborare gli argomenti della riga di comando forniti in fase di avvio dell'applicazione.

Elaborazione degli argomenti della riga di comando

In Windows, le applicazioni autonome possono essere avviate da un prompt dei comandi oppure dal desktop. In entrambi i casi, gli argomenti della riga di comando possono essere passati all'applicazione. Nell'esempio che segue viene illustrata un'applicazione avviata con un unico argomento della riga di comando, "/StartMinimized":

wpfapplication.exe /StartMinimized

Durante l'inizializzazione dell'applicazione, WPF recupera gli argomenti della riga di comando dal sistema operativo e li passa al gestore eventi Startup tramite la proprietà Args del parametro StartupEventArgs. Gli argomenti della riga di comando possono essere recuperati e archiviati tramite codice analogo a quello riportato di seguito.

<Application
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.App"
  Startup="App_Startup" />

Imports Microsoft.VisualBasic
Imports System.Windows ' Application, StartupEventArgs, WindowState

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
            ' Application is running
            ' Process command line args
            Dim startMinimized As Boolean = False
            Dim i As Integer = 0
            Do While i <> e.Args.Length
                If e.Args(i) = "/StartMinimized" Then
                    startMinimized = True
                End If
                i += 1
            Loop

            ' Create main application window, starting minimized if specified
            Dim mainWindow As New MainWindow()
            If startMinimized Then
                mainWindow.WindowState = WindowState.Minimized
            End If
            mainWindow.Show()
        End Sub
    End Class
End Namespace
using System.Windows; // Application, StartupEventArgs, WindowState

namespace SDKSample
{
    public partial class App : Application
    {
        void App_Startup(object sender, StartupEventArgs e)
        {
            // Application is running
            // Process command line args
            bool startMinimized = false;
            for (int i = 0; i != e.Args.Length; ++i)
            {
                if (e.Args[i] == "/StartMinimized")
                {
                    startMinimized = true;
                }
            }

            // Create main application window, starting minimized if specified
            MainWindow mainWindow = new MainWindow();
            if (startMinimized)
            {
                mainWindow.WindowState = WindowState.Minimized;
            }
            mainWindow.Show();
        }
    }
}

Il codice gestisce Startup per controllare se l'argomento della riga di comando /StartMinimized è stato fornito; in caso affermativo, apre la finestra principale con WindowState equivalente a Minimized. Poiché la proprietà WindowState deve essere impostata a livello di codice, l'oggetto Window principale deve essere esplicitamente aperto nel codice.

Le applicazioni XBAPs non possono recuperare ed elaborare gli argomenti della riga di comando poiché vengono avviate mediante distribuzione ClickOnce (vedere Distribuzione di un'applicazione WPF (WPF)). Tuttavia sono in grado di recuperare ed elaborare i parametri delle stringhe di query dagli URL utilizzati per l'avvio.

Attivazione e disattivazione di un'applicazione

Windows consente agli utenti di passare da un'applicazione all'altra. Il metodo più comune consiste nell'utilizzo della combinazione di tasti ALT+TAB. Per passare a un'applicazione, occorre che questa disponga di un oggetto Window visibile e selezionabile da parte di un utente. L'oggetto Window attualmente selezionato rappresenta la finestra attiva, nota anche come finestra in primo piano, ed è l'oggetto Window che riceve l'input dall'utente. L'applicazione alla quale appartiene la finestra attiva è definita applicazione attiva o applicazione in primo piano. Di seguito vengono riportati i casi in cui un'applicazione diventa l'applicazione attiva:

  • Viene avviata e visualizza un oggetto Window.

  • Un utente passa da un'altra applicazione a quella in questione selezionando un oggetto Window nella stessa.

È possibile rilevare quando un'applicazione diventa attiva mediante gestione dell'evento Application.Activated.

Allo stesso modo, un'applicazione diventa inattiva nei seguenti casi:

  • Un utente passa dall'applicazione corrente a un'altra applicazione.

  • L'applicazione viene chiusa.

È possibile rilevare quando un'applicazione diventa inattiva mediante gestione dell'evento Application.Deactivated.

Nel codice seguente viene illustrato come gestire gli eventi Activated e Deactivated per determinare se un'applicazione è attiva o meno.

<Application 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.App"
  StartupUri="MainWindow.xaml"
  Activated="App_Activated" 
  Deactivated="App_Deactivated" />

Imports Microsoft.VisualBasic
Imports System ' EventArgs
Imports System.Windows ' Application

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private isApplicationActive As Boolean

        Private Sub App_Activated(ByVal sender As Object, ByVal e As EventArgs)
            ' Application activated
            Me.isApplicationActive = True
        End Sub

        Private Sub App_Deactivated(ByVal sender As Object, ByVal e As EventArgs)
            ' Application deactivated
            Me.isApplicationActive = False
        End Sub
    End Class
End Namespace
using System; // EventArgs
using System.Windows; // Application

namespace SDKSample
{
    public partial class App : Application
    {
        bool isApplicationActive;

        void App_Activated(object sender, EventArgs e)
        {
            // Application activated
            this.isApplicationActive = true;
        }

        void App_Deactivated(object sender, EventArgs e)
        {
            // Application deactivated
            this.isApplicationActive = false;
        }
    }
}

Anche Window può essere attivato e disattivato. Per ulteriori informazioni, vedere Window.Activated e Window.Deactivated.

NotaNota

Per quanto riguarda le applicazioni XBAPs, Application.Activated e Application.Deactivated non vengono generati.

Chiusura di un'applicazione

La durata di un'applicazione termina quando questa viene chiusa per uno dei seguenti motivi:

  • Un utente chiude tutti gli oggetti Window.

  • Un utente chiude l'oggetto Window principale.

  • Un utente termina la sessione di Windows mediante disconnessione o spegnimento del computer.

  • È stata soddisfatta una condizione specifica dell'applicazione.

Per facilitare la gestione della chiusura di un'applicazione, Application fornisce il metodo Shutdown, la proprietà ShutdownMode e gli eventi SessionEnding ed Exit.

NotaNota

Shutdown può essere chiamato unicamente da applicazioni dotate di UIPermission.Le applicazioni WPF autonome possiedono sempre questa autorizzazione.Le applicazioni XBAPs in esecuzione nella sandbox di sicurezza con attendibilità parziale dell'area Internet non dispongono invece di tale autorizzazione.

Modalità di chiusura

La maggior parte delle applicazioni vengono chiuse in seguito a chiusura di tutte le finestre o della finestra principale. Talvolta però la chiusura di un'applicazione viene determinata da altre condizioni specifiche della stessa. Tali condizioni possono essere specificate impostando ShutdownMode con uno dei valori di enumerazione ShutdownMode seguenti:

Il valore predefinito di ShutdownMode è OnLastWindowClose, il quale determina la chiusura automatica di un'applicazione quando l'ultima finestra di questa viene chiusa dall'utente. Tuttavia è anche possibile fare in modo che l'applicazione venga chiusa quando si chiude la finestra principale. WPF esegue automaticamente tale operazione se si imposta ShutdownMode su OnMainWindowClose, come illustrato nell'esempio che segue.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App"
    ShutdownMode="OnMainWindowClose" />

In presenza di condizioni di chiusura specifiche dell'applicazione, impostare ShutdownMode su OnExplicitShutdown. In questo caso, per chiudere un'applicazione sarà necessario chiamare in modo esplicito il metodo Shutdown; in caso contrario, l'applicazione continuerà a essere eseguita anche se tutte le finestre sono chiuse. Shutdown viene chiamato in modo implicito quando ShutdownMode è impostato su OnLastWindowClose o OnMainWindowClose.

NotaNota

Se si imposta ShutdownMode da un'applicazione XBAP, tale impostazione verrà ignorata. Un'applicazione XBAP viene sempre chiusa in caso di spostamento dalla stessa in un browser oppure quando il browser che la ospita viene chiuso.Per ulteriori informazioni, vedere Cenni preliminari sulla navigazione.

Fine della sessione

Le condizioni di chiusura descritte dalla proprietà ShutdownMode sono specifiche di un'applicazione. In alcuni casi, tuttavia, è possibile che un'applicazione venga chiusa in seguito a una condizione esterna. La condizione esterna più comune si verifica quando un utente termina la sessione di Windows mediante le seguenti azioni:

  • Disconnessione

  • Spegnimento

  • Riavvio

  • Ibernazione

Per rilevare la fine di una sessione di Windows, è possibile gestire l'evento SessionEnding, come illustrato nell'esempio che segue.

<Application 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App"
    StartupUri="MainWindow.xaml"
    SessionEnding="App_SessionEnding" />

Imports Microsoft.VisualBasic
Imports System.Windows ' Application, SessionEndingCancelEventArgs, MessageBox, MessageBoxResult, MessageBoxButton

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_SessionEnding(ByVal sender As Object, ByVal e As SessionEndingCancelEventArgs)
            ' Ask the user if they want to allow the session to end
            Dim msg As String = String.Format("{0}. End session?", e.ReasonSessionEnding)
            Dim result As MessageBoxResult = MessageBox.Show(msg, "Session Ending", MessageBoxButton.YesNo)

            ' End session, if specified
            If result = MessageBoxResult.No Then
                e.Cancel = True
            End If
        End Sub
    End Class
End Namespace
using System.Windows; // Application, SessionEndingCancelEventArgs, MessageBox, MessageBoxResult, MessageBoxButton

namespace SDKSample
{
    public partial class App : Application
    {
        void App_SessionEnding(object sender, SessionEndingCancelEventArgs e)
        {
            // Ask the user if they want to allow the session to end
            string msg = string.Format("{0}. End session?", e.ReasonSessionEnding);
            MessageBoxResult result = MessageBox.Show(msg, "Session Ending", MessageBoxButton.YesNo);

            // End session, if specified
            if (result == MessageBoxResult.No)
            {
                e.Cancel = true;
            }
        }
    }
}

In questo esempio, il codice controlla la proprietà ReasonSessionEnding per stabilire come viene terminata la sessione di Windows. Utilizza quindi questo valore per visualizzare un messaggio di conferma per l'utente. Se l'utente decide che la sessione non deve terminare, il codice imposta Cancel su true per impedire la fine della sessione di Windows.

NotaNota

SessionEnding non viene generato per le applicazioni XBAPs.

Exit

Quando un'applicazione viene chiusa, è possibile che debba eseguire alcune operazioni di elaborazione finale, ad esempio mantenere lo stato dell'applicazione. In questi casi è possibile gestire l'evento Exit.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App"
    StartupUri="MainWindow.xaml" 
    Startup="App_Startup" 
    Exit="App_Exit">


...


</Application>
Imports System.IO ' StreamReader, FileMode
Imports System.IO.IsolatedStorage ' IsolatedStorageFile, IsolatedStorageFileStream

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private filename As String = "App.txt"



...


        Private Sub App_Exit(ByVal sender As Object, ByVal e As ExitEventArgs)
            ' Persist application-scope property to isolated storage
            Dim storage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForDomain()
            Using stream As New IsolatedStorageFileStream(filename, FileMode.Create, storage)
            Using writer As New StreamWriter(stream)
                ' Persist each application-scope property individually
                For Each key As String In Me.Properties.Keys
                    writer.WriteLine("{0},{1}", key, Me.Properties(key))
                Next key
            End Using
            End Using
        End Sub
    End Class
End Namespace
using System.Windows; // Application, StartupEventArgs
using System.IO; // StreamReader, FileMode
using System.IO.IsolatedStorage; // IsolatedStorageFile, IsolatedStorageFileStream

namespace SDKSample
{
    public partial class App : Application
    {
        string filename = "App.txt";



...


        private void App_Exit(object sender, ExitEventArgs e)
        {
            // Persist application-scope property to isolated storage
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForDomain();
            using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filename, FileMode.Create, storage))
            using (StreamWriter writer = new StreamWriter(stream))
            {
                // Persist each application-scope property individually
                foreach (string key in this.Properties.Keys)
                {
                    writer.WriteLine("{0},{1}", key, this.Properties[key]);
                }
            }
        }
    }
}

Per l'esempio completo, vedere Procedura: salvare in modo permanente e ripristinare le proprietà con ambito applicazione tra le sessioni di un'applicazione.

Exit può essere gestito sia da applicazioni autonome che da applicazioni XBAPs. Per quanto concerne le applicazioni XBAPs, Exit viene generato nei seguenti casi:

  • L'utente si sposta da un'applicazione XBAP.

  • In Internet Explorer 7, la scheda che ospita l'applicazione XBAP viene chiusa.

  • Il browser viene chiuso.

Codice di uscita

Nella maggior parte dei casi le applicazioni vengono avviate dal sistema operativo in risposta a una richiesta dell'utente. Tuttavia è possibile che un'applicazione venga avviata da un'altra applicazione per eseguire un'attività specifica. Quando l'applicazione avviata viene chiusa, è possibile che l'altra applicazione voglia conoscere la condizione che ne ha determinato la chiusura. In questi casi, Windows consente alle applicazioni di restituire un codice di uscita al momento della chiusura. Per impostazione predefinita, le applicazioni WPF restituiscono un codice di uscita con valore pari a 0.

NotaNota

Quando si esegue il debug da Visual Studio, il codice di uscita viene visualizzato nella finestra Output alla chiusura dell'applicazione, in un messaggio analogo a quello riportato di seguito:

The program '[5340] AWPFApp.vshost.exe: Managed' has exited with code 0 (0x0).

Per aprire la finestra Output, scegliere Output dal menu Visualizza.

Per modificare il codice di uscita è possibile chiamare l'overload di Shutdown(Int32), il quale accetta un argomento integer come codice di uscita:

' Shutdown and return a non-default exit code
Application.Current.Shutdown(-1)
// Shutdown and return a non-default exit code
Application.Current.Shutdown(-1);

È possibile rilevare e modificare il valore del codice di uscita mediante gestione dell'evento Exit. Al gestore eventi Exit viene passato un oggetto ExitEventArgs che consente di accedere al codice di uscita con la proprietà ApplicationExitCode. Per ulteriori informazioni, vedere Exit.

NotaNota

Il codice di uscita può essere impostato sia nelle applicazioni autonome che nelle applicazioni XBAPs.Tuttavia, nel caso delle applicazioni XBAPs il valore del codice viene ignorato.

Eccezioni non gestite

Talvolta un'applicazione può essere chiusa in condizioni anomale, ad esempio in seguito alla generazione di un'eccezione imprevista. In questo caso, è possibile che l'applicazione non disponga del codice necessario a rilevare ed elaborare l'eccezione. Si avrà quindi un'eccezione non gestita e, prima della chiusura dell'applicazione, verrà visualizzata una notifica simile a quella riportata nella figura che segue.

Notifica di eccezione non gestita

Dal punto di vista dell'esperienza utente, è preferibile evitare questo comportamento predefinito dell'applicazione nei modi che seguono:

  • Visualizzando informazioni di facile comprensione.

  • Tentando di mantenere in esecuzione un'applicazione.

  • Registrando informazioni sull'eccezione dettagliate e facilmente comprensibili per lo sviluppatore nel registro eventi di Windows.

L'implementazione di questo supporto dipende dalla possibilità di rilevare o meno le eccezioni non gestite, motivo per cui viene generato l'evento DispatcherUnhandledException.

<Application
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.App"
  StartupUri="MainWindow.xaml"
  DispatcherUnhandledException="App_DispatcherUnhandledException" />

Imports Microsoft.VisualBasic
Imports System.Windows ' Application
Imports System.Windows.Threading ' DispatcherUnhandledExceptionEventArgs

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_DispatcherUnhandledException(ByVal sender As Object, ByVal e As DispatcherUnhandledExceptionEventArgs)
            ' Process unhandled exception


...


            ' Prevent default unhandled exception processing
            e.Handled = True
        End Sub
    End Class
End Namespace
using System.Windows; // Application
using System.Windows.Threading; // DispatcherUnhandledExceptionEventArgs

namespace SDKSample
{
    public partial class App : Application
    {
        void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            // Process unhandled exception


...


            // Prevent default unhandled exception processing
            e.Handled = true;
        }
    }
}

Al gestore eventi DispatcherUnhandledException viene passato un parametro DispatcherUnhandledExceptionEventArgs contenente informazioni contestuali riguardo l'eccezione non gestita, inclusa l'eccezione stessa (DispatcherUnhandledExceptionEventArgs.Exception). È possibile utilizzare queste informazioni per stabilire come gestire l'eccezione.

Quando si gestisce DispatcherUnhandledException, è necessario impostare la proprietà DispatcherUnhandledExceptionEventArgs.Handled su true; in caso contrario, WPF continua a considerare l'eccezione come non gestita e ripristina il comportamento predefinito descritto in precedenza. Se viene generata un'eccezione non gestita e l'evento DispatcherUnhandledException non è gestito oppure l'evento è gestito e Handled è impostato su false, l'applicazione viene immediatamente chiusa. Inoltre, non vengono generati altri eventi Application. Di conseguenza, è necessario gestire DispatcherUnhandledException nel caso in cui l'applicazione possieda un codice da eseguire prima della chiusura.

Benché possa essere determinata da un'eccezione non gestita, in genere la chiusura di un'applicazione avviene in risposta a una richiesta dell'utente, come illustrato nella sezione che segue.

Eventi di durata dell'applicazione

La durata delle applicazioni autonome e delle applicazioni XBAPs non è esattamente la stessa. Nella figura che segue vengono illustrati gli eventi principali nella durata di un'applicazione autonoma con la relativa sequenza di generazione.

Applicazione autonoma - Eventi dell'oggetto Application

Allo stesso modo, vengono illustrati anche gli eventi principali nella durata di un'applicazione XBAP con la relativa sequenza di generazione.

XBAP - Eventi dell'oggetto Application

Altri servizi dell'applicazione

Oltre a gestire la durata di un'applicazione, Application fornisce servizi aggiuntivi tra cui:

  • Proprietà con ambito di applicazione condivise.

  • Risorse con ambito di applicazione condivise.

  • File di risorse, file di dati e file del sito di origine dell'applicazione.

  • Gestione delle finestre.

  • Gestione dello spostamento.

Proprietà con ambito di applicazione condivise

L'applicazione fornisce la proprietà Properties per esporre uno stato condivisibile nell'ambito dell'intera applicazione. Di seguito viene riportato un esempio dell'utilizzo di Properties:

      ' Set an application-scope property with a custom type
      Dim customType As New CustomType()
      Application.Current.Properties("CustomType") = customType


...


      ' Get an application-scope property
      ' NOTE: Need to convert since Application.Properties is a dictionary of System.Object
      Dim customType As CustomType = CType(Application.Current.Properties("CustomType"), CustomType)
// Set an application-scope property with a custom type
CustomType customType = new CustomType();
Application.Current.Properties["CustomType"] = customType;


...


// Get an application-scope property
// NOTE: Need to convert since Application.Properties is a dictionary of System.Object
CustomType customType = (CustomType)Application.Current.Properties["CustomType"];

Per ulteriori informazioni, vedere i seguenti argomenti:

Risorse con ambito di applicazione condivise

L'applicazione fornisce la proprietà Resources che consente agli sviluppatori di condividere le risorse dell'UI nell'ambito dell'applicazione stessa. Di seguito viene riportato un esempio dell'utilizzo di Resources:

      ' Set an application-scope resource
      Application.Current.Resources("ApplicationScopeResource") = Brushes.White


...


      ' Get an application-scope resource
      Dim whiteBrush As Brush = CType(Application.Current.Resources("ApplicationScopeResource"), Brush)
// Set an application-scope resource
Application.Current.Resources["ApplicationScopeResource"] = Brushes.White;


...


// Get an application-scope resource
Brush whiteBrush = (Brush)Application.Current.Resources["ApplicationScopeResource"];

Per ulteriori informazioni, vedere i seguenti argomenti:

File di risorse, file di dati e file del sito di origine dell'applicazione

Le applicazioni WPF possono gestire vari tipi di file di dati diversi da codice, inclusi i file di risorse, i file di dati e i file del sito di origine. I metodi di supporto seguenti possono essere utilizzati per caricare questi tipi di file di dati:

Gestione finestre

Application e Window sono strettamente correlati. Come si è visto, la durata di un'applicazione può dipendere dalla durata delle relative finestre, come specificato dalla proprietà ShutdownMode. Application registra la finestra designata come finestra principale dell'applicazione (Application.MainWindow) e gestisce un elenco di finestre per le quali è stata attualmente creata un'istanza (Application.Windows).

Per ulteriori informazioni, vedere Cenni preliminari sulle finestre WPF.

Gestione dello spostamento

Nel caso delle applicazioni autonome con spostamento mediante NavigationWindow e Frame o delle applicazioni XBAPs, Application rileva gli spostamenti all'interno di un'applicazione e genera, in base alle necessità, i seguenti eventi:

Inoltre, Application offre ad applicazioni di qualsiasi tipo la possibilità di creare, salvare in modo permanente e recuperare cookie mediante l'utilizzo di GetCookie e SetCookie.

Per ulteriori informazioni, vedere Cenni preliminari sulla navigazione.

Vedere anche

Riferimenti

Application

Concetti

Cenni preliminari sulle finestre WPF

Cenni preliminari sulla navigazione

File di dati e di risorse dell'applicazione WPF.

URI di tipo pack in WPF

Sviluppo di applicazioni

Altre risorse

Procedure relative al modello dell'applicazione