Panoramica della gestione delle applicazioni
Tutte le applicazioni tendono a condividere un set comune di funzionalità che si applicano all'implementazione e alla gestione delle applicazioni. In questo argomento viene fornita una panoramica delle funzionalità della classe Application per la creazione e la gestione delle applicazioni.
La Classe Application
In WPF, la funzionalità comune a livello di applicazione viene incapsulata nella classe Application. La classe Application include le funzionalità seguenti:
Rilevamento e interazione con il ciclo di vita dell'applicazione.
Recupero ed elaborazione dei parametri della riga di comando.
Rilevamento e risposta a eccezioni non gestite.
Condivisione di proprietà e risorse dell'ambito dell'applicazione.
Gestione delle finestre nelle applicazioni autonome.
Rilevamento e gestione della navigazione.
Come eseguire attività comuni usando la classe application
Se non si è interessati a tutti i dettagli della classe Application, nella tabella seguente sono elencate alcune delle attività comuni per Application e come eseguirle. Visualizzando l'API e gli argomenti correlati, è possibile trovare altre informazioni e codice di esempio.
Compito | Avvicinarsi |
---|---|
Ottenere un oggetto che rappresenta l'applicazione corrente | Utilizzare la proprietà Application.Current. |
Aggiungere una schermata di avvio a un'applicazione | Vedere Aggiungere una schermata iniziale a un'applicazione WPF. |
Avviare un'applicazione | Usare il metodo Application.Run. |
Chiudere un'applicazione | Utilizzare il metodo Shutdown dell'oggetto Application.Current. |
Ottenere argomenti dalla riga di comando | Gestire l'evento Application.Startup e utilizzare la proprietà StartupEventArgs.Args. Per un esempio, vedi l'evento Application.Startup. |
Ottenere e impostare il codice di uscita dell'applicazione | Impostare la proprietà ExitEventArgs.ApplicationExitCode nel gestore eventi Application.Exit oppure chiamare il metodo Shutdown e passare un numero intero. |
Rilevare e rispondere a eccezioni non gestite | Gestire l'evento DispatcherUnhandledException. |
Ottenere e impostare risorse con ambito applicazione | Utilizzare la proprietà Application.Resources. |
Usare un dizionario risorse con ambito applicazione | Vedere Usare un dizionario risorse Application-Scope. |
Accedere e impostare le proprietà con ambito dell'applicazione | Utilizzare la proprietà Application.Properties. |
Ottenere e salvare lo stato di un'applicazione | Consulta Persistenza e ripristino delle proprietà Application-Scope nelle sessioni dell'applicazione. |
Gestire file di dati non di codice, inclusi file di risorse, file di contenuto e file di origine del sito. | Consulta la risorsa applicazione WPF, contenuto e file di dati . |
Gestire le finestre nelle applicazioni autonome | Consulta la panoramica di Windows WPF . |
Tenere traccia e gestire la navigazione | Consulta la panoramica della navigazione . |
Definizione dell'applicazione
Per usare la funzionalità della classe Application, è necessario implementare una definizione dell'applicazione. Una definizione di applicazione WPF è una classe che deriva da Application ed è configurata con un'impostazione msbuild speciale.
Implementazione di una definizione di applicazione
Una tipica definizione di applicazione WPF viene implementata usando sia markup che code-behind. In questo modo è possibile usare il markup per impostare in modo dichiarativo le proprietà, le risorse e registrare gli eventi, gestendo gli eventi e implementando un comportamento specifico dell'applicazione nel code-behind.
L'esempio seguente illustra come implementare una definizione di applicazione usando sia markup che code-behind:
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App" />
using System.Windows;
namespace SDKSample
{
public partial class App : Application { }
}
Imports System.Windows
Namespace SDKSample
Partial Public Class App
Inherits Application
End Class
End Namespace
Per consentire il funzionamento di un file di markup e di un file code-behind, è necessario eseguire le operazioni seguenti:
Nel markup, l'elemento
Application
deve includere l'attributox:Class
. Quando l'applicazione viene compilata, l'esistenza dix:Class
nel file di markup fa sì che MSBuild crei una classepartial
che deriva da Application e abbia il nome specificato dall'attributox:Class
. Ciò richiede di aggiungere una dichiarazione dello spazio dei nomi XML per lo schema XAML (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
).Nel code-behind, la classe deve essere una classe
partial
con lo stesso nome specificato dall'attributox:Class
nel markup e deve derivare da Application. In questo modo il file code-behind può essere associato alla classepartial
generata per il file di markup quando l'applicazione viene compilata (vedere Compilazione di un'applicazione WPF).
Nota
Quando si crea un nuovo progetto applicazione WPF o un progetto applicazione browser WPF con Visual Studio, per impostazione predefinita viene inclusa una definizione dell'applicazione e viene definita usando sia markup che code-behind.
Questo codice è il minimo necessario per implementare una definizione di applicazione. Tuttavia, è necessario creare una configurazione MSBuild aggiuntiva alla definizione dell'applicazione prima di compilare ed eseguire l'applicazione.
Configurazione della definizione dell'applicazione per MSBuild
Le applicazioni autonome e le applicazioni browser XAML (XBAP) richiedono l'implementazione di un determinato livello di infrastruttura prima che possano essere eseguite. 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, che è una funzione nota per l'avvio delle applicazioni.
Avvertimento
Per funzionare, gli XBAP richiedono browser legacy, come Internet Explorer e versioni precedenti di Firefox. Questi browser meno recenti sono in genere non supportati in Windows 10 e Windows 11. I browser moderni non supportano più la tecnologia necessaria per le app XBAP a causa di rischi per la sicurezza. I plug-in che abilitano XBAP non sono più supportati. Per altre informazioni, vedere domande frequenti sulle applicazioni WPF ospitate dal browser (XBAP).
Tradizionalmente, gli sviluppatori hanno bisogno di scrivere alcuni o tutto questo codice per se stessi, a seconda della tecnologia. Tuttavia, WPF genera automaticamente questo codice quando il file di markup della definizione dell'applicazione è configurato come elemento msbuild ApplicationDefinition
, come illustrato nel file di progetto MSBuild seguente:
<Project
DefaultTargets="Build"
xmlns="http://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 di consueto.
L'applicazione di queste configurazioni MSBuild ai file di markup e code-behind di una definizione di applicazione fa sì che MSBuild generi codice simile al seguente:
using System;
using System.Windows;
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()
{
// Initialization code goes here.
}
}
}
Imports System.Windows
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()
' Initialization code goes here.
End Sub
End Class
End Namespace
Il codice risultante arricchisce la definizione dell'applicazione con codice infrastrutturale aggiuntivo, che include il metodo entry-point Main
. L'attributo STAThreadAttribute viene applicato al metodo Main
per indicare che il thread dell'interfaccia utente principale per l'applicazione WPF è un thread STA, necessario per le 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 automaticamente, non è necessario chiamare in modo esplicito InitializeComponent
da una definizione di applicazione come per le implementazioni di Page e Window. Infine, viene chiamato il metodo Run per avviare l'applicazione.
Recupero dell'applicazione corrente
Poiché la funzionalità della classe Application viene condivisa in un'applicazione, può essere presente una sola istanza della classe Application per ogni AppDomain. Per farlo, la classe Application viene implementata come classe singleton (vedere Implementazione di Singleton in C#), creando una singola istanza di se stessa e fornendo un accesso condiviso con la proprietà static
Current.
Nel codice seguente viene illustrato come acquisire un riferimento all'oggetto Application per l'oggetto corrente AppDomain.
// Get current application
Application current = App.Current;
' Get current application
Dim current As Application = App.Current
Current restituisce un riferimento a un'istanza della classe Application. Se desideri un riferimento alla classe derivata Application, devi eseguire il cast del valore della proprietà Current, come illustrato nell'esempio seguente.
// Get strongly-typed current application
App app = (App)App.Current;
' Get strongly-typed current application
Dim appCurrent As App = CType(App.Current, App)
È possibile esaminare il valore di Current in qualsiasi momento della durata di un oggetto Application. Tuttavia, dovresti stare attento. Dopo la creazione di un'istanza della classe Application, si verifica un periodo durante il quale lo stato dell'oggetto Application è incoerente. Durante questo periodo, Application esegue le varie attività di inizializzazione richieste dal codice per l'esecuzione, tra cui la definizione dell'infrastruttura dell'applicazione, l'impostazione delle proprietà e la registrazione di eventi. Se si tenta di usare l'oggetto Application durante questo periodo, il codice potrebbe avere risultati imprevisti, in particolare se dipende dalle varie proprietà Application impostate.
Quando Application completa il lavoro di inizializzazione, la sua durata inizia davvero.
Durata dell'applicazione
Il ciclo di vita di un'applicazione WPF è contrassegnato da diversi eventi generati da Application per informarti quando l'applicazione è avviata, attivata, disattivata e arrestata.
Schermata iniziale
A partire da .NET Framework 3.5 SP1, è possibile specificare un'immagine da usare in una finestra di avvio o schermata iniziale. La classe SplashScreen semplifica la visualizzazione di una finestra di avvio durante il caricamento dell'applicazione. La finestra di SplashScreen viene creata e visualizzata prima di chiamare Run. Per altre informazioni, vedere ora di avvio dell'applicazione e Aggiungere una schermata iniziale a un'applicazione WPF.
Avvio di un'applicazione
Dopo che Run viene chiamato e l'applicazione viene inizializzata, l'applicazione è pronta per l'esecuzione. Questo momento è indicato quando viene generato l'evento Startup:
using System.Windows;
namespace SDKSample
{
public partial class App : Application
{
void App_Startup(object sender, StartupEventArgs e)
{
// Application is running
}
}
}
Namespace SDKSample
Partial Public Class App
Inherits Application
Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
' Application is running
'</SnippetStartupCODEBEHIND1>
End Class
End Namespace
'</SnippetStartupCODEBEHIND2>
A questo punto della durata di un'applicazione, la cosa più comune da eseguire consiste nello mostrare un'interfaccia utente.
Visualizzazione di un'interfaccia utente
La maggior parte delle applicazioni Windows autonome visualizza un Window quando iniziano a funzionare. Il gestore eventi Startup è una posizione da cui è possibile eseguire questa operazione, come illustrato nel codice seguente.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
Startup="App_Startup" />
using System.Windows;
namespace SDKSample
{
public partial class App : Application
{
void App_Startup(object sender, StartupEventArgs e)
{
// Open a window
MainWindow window = new MainWindow();
window.Show();
}
}
}
Imports System.Windows
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
Nota
Il primo Window creato in un'applicazione autonoma viene automaticamente impostato come finestra principale dell'applicazione per impostazione predefinita. Questo oggetto Window fa riferimento alla proprietà Application.MainWindow. Il valore della proprietà MainWindow può essere modificato a livello di codice se una finestra diversa dalla prima Window creata deve essere la finestra principale.
Quando un XBAP viene avviato, è molto probabile che venga reindirizzato a un Page. Questo è illustrato nel codice seguente.
<Application
x:Class="SDKSample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="App_Startup" />
using System;
using System.Windows;
using System.Windows.Navigation;
namespace SDKSample
{
public partial class App : Application
{
void App_Startup(object sender, StartupEventArgs e)
{
((NavigationWindow)this.MainWindow).Navigate(new Uri("HomePage.xaml", UriKind.Relative));
}
}
}
Imports System.Windows
Imports System.Windows.Navigation
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
Se gestisci Startup solo per aprire un Window o navigare a un Page, puoi impostare l'attributo StartupUri
direttamente nel markup.
Nell'esempio seguente viene illustrato come usare il StartupUri da un'applicazione autonoma per aprire un Window.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
StartupUri="MainWindow.xaml" />
Nell'esempio seguente viene illustrato come usare StartupUri da un XBAP per passare a un Page.
<Application
xmlns="http://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.
Nota
Per ulteriori informazioni sulla navigazione, vedere Panoramica della navigazione.
È necessario gestire l'evento Startup per aprire un Window se è necessario crearne un'istanza usando un costruttore senza parametri oppure è necessario impostarne le proprietà o sottoscrivere i relativi eventi prima di visualizzarlo oppure è necessario elaborare eventuali argomenti della riga di comando forniti al momento dell'avvio dell'applicazione.
Elaborazione di argomenti Command-Line
In Windows le applicazioni autonome possono essere avviate da un prompt dei comandi o dal desktop. In entrambi i casi, gli argomenti della riga di comando possono essere passati all'applicazione. L'esempio seguente mostra un'applicazione che viene avviata con un singolo 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. È possibile recuperare e archiviare gli argomenti della riga di comando usando codice simile al seguente.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
Startup="App_Startup" />
using System.Windows;
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();
}
}
}
Imports System.Windows
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
Il codice controlla Startup per verificare se il parametro della riga di comando /StartMinimized è presente; se presente, apre la finestra principale con un WindowState di Minimized. Si noti che poiché la proprietà WindowState deve essere impostata a livello di codice, il Window principale deve essere aperto in modo esplicito nel codice.
Gli XBAP non possono recuperare ed elaborare gli argomenti della riga di comando perché vengono avviati tramite la distribuzione ClickOnce (vedere Distribuzione di un'applicazione WPF). Tuttavia, possono recuperare ed elaborare i parametri della stringa di query dagli URL usati per avviarli.
Attivazione e disattivazione dell'applicazione
Windows consente agli utenti di passare da un'applicazione all'altra. Il modo più comune consiste nell'usare la combinazione di tasti ALT+TAB. Un'applicazione può essere cambiata solo se ha un Window visibile che un utente può selezionare. L'Window attualmente selezionata è la finestra attiva (nota anche come finestra di primo piano ) ed è il Window che riceve l'input dell'utente. L'applicazione con la finestra attiva è l'applicazione attiva (o l'applicazione in primo piano ). Un'applicazione diventa l'applicazione attiva nelle circostanze seguenti:
Viene avviato e mostra un Window.
Un utente passa da un'altra applicazione selezionando un Window nell'applicazione.
È possibile rilevare quando un'applicazione diventa attiva gestendo l'evento Application.Activated.
Analogamente, un'applicazione può diventare inattiva nelle circostanze seguenti:
Un utente passa a un'altra applicazione da quella corrente.
Quando l'applicazione viene arrestata.
È possibile rilevare quando un'applicazione diventa inattiva gestendo l'evento Application.Deactivated.
Il codice seguente illustra come gestire gli eventi Activated e Deactivated per determinare se un'applicazione è attiva.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
StartupUri="MainWindow.xaml"
Activated="App_Activated"
Deactivated="App_Deactivated" />
using System;
using System.Windows;
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;
}
}
}
Imports System.Windows
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
Un Window può anche essere attivato e disattivato. Per altre informazioni, vedere Window.Activated e Window.Deactivated.
Nota
Né Application.Activated né Application.Deactivated vengono generati per gli XBAP.
Arresto dell'applicazione
La durata di un'applicazione termina quando viene arrestata, che può verificarsi per i motivi seguenti:
Un utente chiude ogni Window.
Un utente chiude il Windowprincipale.
Un utente termina la sessione su Windows disconnettendosi o arrestando il sistema.
È stata soddisfatta una condizione specifica dell'applicazione.
Per gestire l'arresto dell'applicazione, Application fornisce il metodo Shutdown, la proprietà ShutdownMode e gli eventi SessionEnding e Exit.
Nota
Shutdown può essere chiamato solo dalle applicazioni con UIPermission. Le applicazioni WPF autonome hanno sempre questa autorizzazione. Tuttavia, gli XBAP in esecuzione nella sandbox di sicurezza a fiducia parziale nell'area Internet non lo fanno.
Modalità di spegnimento
La maggior parte delle applicazioni viene arrestata quando tutte le finestre vengono chiuse o quando la finestra principale viene chiusa. In alcuni casi, tuttavia, altre condizioni specifiche dell'applicazione possono determinare quando un'applicazione viene arrestata. È possibile specificare le condizioni in cui l'applicazione verrà arrestata impostando ShutdownMode con uno dei valori di enumerazione ShutdownMode seguenti:
Il valore predefinito di ShutdownMode è OnLastWindowClose, il che significa che un'applicazione viene arrestata automaticamente quando l'ultima finestra nell'applicazione viene chiusa dall'utente. Tuttavia, se l'applicazione deve essere arrestata quando la finestra principale viene chiusa, WPF esegue automaticamente questa operazione se si imposta ShutdownMode su OnMainWindowClose. Questo è illustrato nell'esempio seguente.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
ShutdownMode="OnMainWindowClose" />
Quando si dispone di condizioni di arresto specifiche dell'applicazione, si imposti ShutdownMode su OnExplicitShutdown. In questo caso, è responsabilità dell'utente arrestare un'applicazione chiamando in modo esplicito il metodo Shutdown; in caso contrario, l'applicazione continuerà a essere in esecuzione anche se tutte le finestre sono chiuse. Si noti che Shutdown viene chiamato in modo implicito quando il ShutdownMode è OnLastWindowClose o OnMainWindowClose.
Nota
ShutdownMode può essere impostato da un XBAP, ma viene ignorato; un XBAP viene sempre arrestato quando si naviga lontano da esso in un browser o quando il browser che ospita l'XBAP viene chiuso. Per ulteriori informazioni, vedere la panoramica sulla navigazione .
Fine della sessione
Le condizioni di arresto descritte dalla proprietà ShutdownMode sono specifiche per un'applicazione. In alcuni casi, tuttavia, un'applicazione può chiudersi in seguito a una condizione esterna. La condizione esterna più comune si verifica quando un utente termina la sessione di Windows tramite le azioni seguenti:
Disconnessione
Spegnimento
Riavviare
Letargo
Per rilevare quando termina una sessione di Windows, è possibile gestire l'evento SessionEnding, come illustrato nell'esempio seguente.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
StartupUri="MainWindow.xaml"
SessionEnding="App_SessionEnding" />
using System.Windows;
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;
}
}
}
}
Imports System.Windows
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
In questo esempio, il codice controlla la proprietà ReasonSessionEnding per determinare come termina la sessione di Windows. Usa questo valore per visualizzare un messaggio di conferma all'utente. Se l'utente non vuole che la sessione termini, il codice imposta Cancel su true
per impedire la fine della sessione di Windows.
Nota
SessionEnding non viene generato per gli XBAP.
Uscita
Quando un'applicazione viene arrestata, potrebbe essere necessario eseguire un'elaborazione finale, ad esempio per rendere persistente lo stato dell'applicazione. Per queste situazioni, puoi gestire l'evento Exit, come fa il gestore dell'evento App_Exit
nel seguente esempio. Viene definito come gestore di eventi nel file App.xaml. L'implementazione è evidenziata nei file App.xaml.cs e Application.xaml.vb.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
StartupUri="MainWindow.xaml"
Startup="App_Startup"
Exit="App_Exit">
<Application.Resources>
<SolidColorBrush x:Key="ApplicationScopeResource" Color="White"></SolidColorBrush>
</Application.Resources>
</Application>
using System.Windows;
using System.IO;
using System.IO.IsolatedStorage;
namespace SDKSample
{
public partial class App : Application
{
string filename = "App.txt";
public App()
{
// Initialize application-scope property
this.Properties["NumberOfAppSessions"] = 0;
}
private void App_Startup(object sender, StartupEventArgs e)
{
// Restore application-scope property from isolated storage
IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForDomain();
try
{
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filename, FileMode.Open, storage))
using (StreamReader reader = new StreamReader(stream))
{
// Restore each application-scope property individually
while (!reader.EndOfStream)
{
string[] keyValue = reader.ReadLine().Split(new char[] {','});
this.Properties[keyValue[0]] = keyValue[1];
}
}
}
catch (FileNotFoundException ex)
{
// Handle when file is not found in isolated storage:
// * When the first application session
// * When file has been deleted
}
}
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]);
}
}
}
}
}
Imports System.IO
Imports System.IO.IsolatedStorage
Namespace SDKSample
Partial Public Class App
Inherits Application
Private filename As String = "App.txt"
Public Sub New()
' Initialize application-scope property
Me.Properties("NumberOfAppSessions") = 0
End Sub
Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
' Restore application-scope property from isolated storage
Dim storage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForDomain()
Try
Using stream As New IsolatedStorageFileStream(filename, FileMode.Open, storage)
Using reader As New StreamReader(stream)
' Restore each application-scope property individually
Do While Not reader.EndOfStream
Dim keyValue() As String = reader.ReadLine().Split(New Char() {","c})
Me.Properties(keyValue(0)) = keyValue(1)
Loop
End Using
End Using
Catch ex As FileNotFoundException
' Handle when file is not found in isolated storage:
' * When the first application session
' * When file has been deleted
End Try
End Sub
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
Per l'esempio completo, vedere Conservare e ripristinare le proprietà Application-Scope attraverso le sessioni dell'applicazione.
Exit può essere gestito sia da applicazioni autonome che da XBAP. Per gli XBAP, Exit viene generato nelle seguenti circostanze:
Un XBAP viene spostato da.
In Internet Explorer, quando la scheda che ospita l'XBAP viene chiusa.
Quando il browser è chiuso.
Codice di uscita
Le applicazioni vengono avviate principalmente dal sistema operativo in risposta a una richiesta dell'utente. Tuttavia, un'applicazione può essere avviata da un'altra applicazione per eseguire alcune attività specifiche. Quando l'applicazione avviata viene arrestata, l'applicazione di avvio potrebbe voler conoscere la condizione in cui l'applicazione avviata viene arrestata. In queste situazioni, Windows consente alle applicazioni di restituire un codice di uscita dell'applicazione all'arresto. Per impostazione predefinita, le applicazioni WPF restituiscono un valore di codice di uscita pari a 0.
Nota
Quando si esegue il debug da Visual Studio, il codice di uscita dell'applicazione viene visualizzato nella finestra output
The program '[5340] AWPFApp.vshost.exe: Managed' has exited with code 0 (0x0).
Si apre la finestra Output facendo clic su Output nel menu Visualizza.
Per modificare il codice di uscita, puoi chiamare l'overload Shutdown(Int32), che accetta un argomento intero 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 il valore del codice di uscita e modificarlo gestendo l'evento Exit. Il gestore eventi Exit riceve un ExitEventArgs che fornisce l'accesso al codice di uscita tramite la proprietà ApplicationExitCode. Per altre informazioni, vedere Exit.
Nota
È possibile impostare il codice di uscita sia nelle applicazioni autonome che negli XBAP. Tuttavia, il valore del codice di uscita viene ignorato per gli XBAP.
Eccezioni non gestite
A volte un'applicazione può bloccarsi in condizioni anomale, ad esempio quando viene generata un'eccezione imprevista. In questo caso, l'applicazione potrebbe non avere il codice per rilevare ed elaborare l'eccezione. Questo tipo di eccezione è un'eccezione non gestita; Una notifica simile a quella illustrata nella figura seguente viene visualizzata prima che l'applicazione venga chiusa.
Dal punto di vista dell'esperienza utente, è preferibile per un'applicazione evitare questo comportamento predefinito eseguendo alcune o tutte le operazioni seguenti:
Visualizzazione di informazioni intuitive.
Tentativo di mantenere un'applicazione attiva.
Registrazione di informazioni dettagliate sulle eccezioni facilmente comprensibili per gli sviluppatori nel registro eventi di Windows.
L'implementazione di questo supporto dipende dalla possibilità di rilevare le eccezioni non gestite, ovvero ciò per cui viene generato l'evento DispatcherUnhandledException.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
StartupUri="MainWindow.xaml"
DispatcherUnhandledException="App_DispatcherUnhandledException" />
using System.Windows;
using System.Windows.Threading;
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;
}
}
}
Imports System.Windows
Imports System.Windows.Threading
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
Al gestore dell'evento DispatcherUnhandledException viene passato un parametro DispatcherUnhandledExceptionEventArgs che contiene informazioni contestuali sull'eccezione non gestita, inclusa l'eccezione stessa (DispatcherUnhandledExceptionEventArgs.Exception). È possibile usare queste informazioni per determinare come gestire l'eccezione.
Quando si gestisce DispatcherUnhandledException, è necessario impostare la proprietà DispatcherUnhandledExceptionEventArgs.Handled su true
; in caso contrario, WPF considera comunque l'eccezione non gestita e ripristina il comportamento predefinito descritto in precedenza. Se viene generata un'eccezione non gestita e l'evento DispatcherUnhandledException non viene gestito, oppure se l'evento è gestito e Handled è impostato su false
, l'applicazione viene arrestata immediatamente. Inoltre, non vengono generati altri eventi Application. Di conseguenza, è necessario gestire DispatcherUnhandledException se l'applicazione dispone di codice che deve essere eseguito prima dell'arresto dell'applicazione.
Sebbene un'applicazione possa essere arrestata in seguito a un'eccezione non gestita, un'applicazione viene in genere arrestata in risposta a una richiesta utente, come descritto nella sezione successiva.
Eventi del ciclo di vita dell'applicazione
Le applicazioni autonome e gli XBAP non hanno esattamente le stesse durate. La figura seguente illustra gli eventi chiave nella durata di un'applicazione autonoma e mostra la sequenza in cui vengono generati.
Applicazione autonoma
Analogamente, la figura seguente illustra gli eventi chiave nel ciclo di vita di un XBAP e mostra la sequenza in cui vengono generati.
Vedere anche
- Application
- Panoramica di WPF Windows
- panoramica navigazione
- File delle risorse, dei contenuti e dei dati dell'applicazione WPF
- URI Pack in WPF
- modello di applicazione : procedure
- sviluppo di applicazioni
.NET Desktop feedback