Cenni preliminari sulla gestione di applicazioni
Tutte le applicazioni tendono a condividere un set comune di funzionalità relative all'implementazione e alla gestione di applicazioni. In questo argomento viene fornita una panoramica delle funzionalità della classe per la Application creazione e la gestione delle applicazioni.
classe Application
In WPF, la funzionalità comune con ambito applicazione è incapsulata nella Application classe . La Application classe include le funzionalità seguenti:
Interazione con il ciclo di vita dell'applicazione e relativa verifica.
Recupero ed elaborazione di parametri della riga di comando.
Rilevamento delle eccezioni non gestite e riposta a tali eccezioni.
Condivisione di proprietà con ambito di applicazione e risorse dell'.
Gestione delle finestre in applicazioni autonome.
Verifica e gestione della navigazione.
Come eseguire attività comuni con la classe Application
Se non si è interessati a tutti i dettagli della Application classe, la tabella seguente elenca alcune delle attività comuni per Application e come eseguirle. Visualizzando l'API e gli argomenti correlati, è possibile trovare altre informazioni e il codice di esempio.
Attività | Approccio |
---|---|
Ottenere un oggetto che rappresenta l'applicazione corrente | Usare la proprietà Application.Current. |
Aggiungere una schermata di avvio a un'applicazione | Vedere Aggiungere una schermata iniziale in un'applicazione WPF. |
Avviare un'applicazione | Usare il metodo Application.Run. |
Arrestare un'applicazione | Utilizzare il Shutdown metodo dell'oggetto Application.Current . |
Ottenere argomenti dalla riga di comando | Gestire l'evento Application.Startup e usare la StartupEventArgs.Args proprietà . Per un esempio, vedere l'evento Application.Startup . |
Ottenere e impostare il codice di uscita dell'applicazione | Impostare la ExitEventArgs.ApplicationExitCode proprietà nel Application.Exit gestore eventi o chiamare il Shutdown metodo e passare un numero intero. |
Rilevare eccezioni non gestite e rispondervi | Gestire l'evento DispatcherUnhandledException . |
Ottenere e impostare le risorse con ambito di applicazione | Usare la proprietà Application.Resources. |
Usare un dizionario risorse con ambito di applicazione | Vedere Utilizzare un dizionario risorse relativo all'ambito dell'applicazione. |
Ottenere e impostare proprietà con ambito di applicazione | Usare la proprietà Application.Properties. |
Ottenere e salvare lo stato di un'applicazione | Vedere Salvare in modo permanente e ripristinare le proprietà con ambito applicazione tra le sessioni di un'applicazione. |
Gestire file di dati non di codice, tra cui file di risorse, file di contenuto e file del sito di origine. | Vedere File di dati e di risorse dell'applicazione WPF. |
Gestire le finestre in applicazioni autonome | Vedere Cenni preliminari sulle finestre WPF. |
Verificare e gestire la navigazione | Vedere Cenni preliminari sulla navigazione. |
Definizione dell'applicazione
Per usare la funzionalità della Application classe , è necessario implementare una definizione dell'applicazione. Una definizione di applicazione WPF è una classe che deriva da Application e viene configurata con un'impostazione speciale di MSBuild.
Implementazione di una definizione di applicazione
Una tipica definizione di applicazione WPF viene implementata usando sia markup che code-behind. Questo approccio permette di usare il markup per impostare in modo dichiarativo proprietà e risorse dell'applicazione e registrare eventi, gestendo gli eventi e implementando il comportamento specifico dell'applicazione nel code-behind.
L'esempio seguente mostra come implementare una definizione di applicazione tramite markup e 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 poter usare un file di markup e un file code-behind insieme, devono verificarsi le condizioni seguenti:
Nel markup l'elemento
Application
deve includere l'attributox:Class
. Quando l'applicazione viene compilata, l'esistenza di nel file dix:Class
markup fa sì che MSBuild crei unapartial
classe che deriva da Application e abbia il nome specificato dall'attributox:Class
. Questa operazione richiede l'aggiunta di 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
partial
classe 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 allapartial
classe 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 è quello 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 di una definizione di 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 ben nota per l'avvio delle applicazioni.
Avviso
I file XBAP richiedono il funzionamento di browser legacy, ad esempio 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 ospitate dal browser WPF (XBAP).
Tradizionalmente, gli sviluppatori hanno sempre dovuto scrivere personalmente questo codice, interamente o in parte, a seconda della tecnologia. Tuttavia, WPF genera automaticamente questo codice quando il file di markup della definizione dell'applicazione è configurato come elemento MSBuild, come illustrato nel file di progetto MSBuild ApplicationDefinition
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 MSBuild Compile
, 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 aggiunge alla definizione di applicazione altro codice dell'infrastruttura, che include il metodo del punto di ingresso Main
. L'attributo STAThreadAttribute viene applicato al Main
metodo per indicare che il thread principale dell'interfaccia utente per l'applicazione WPF è un thread STA, necessario per le applicazioni WPF. Quando viene chiamato, Main
crea una nuova istanza di prima di App
chiamare il InitializeComponent
metodo per registrare gli eventi e impostare le proprietà implementate nel markup. Poiché InitializeComponent
viene generato automaticamente, non è necessario chiamare InitializeComponent
in modo esplicito da una definizione di applicazione come per Page le implementazioni e Window . Infine, viene chiamato il Run metodo per avviare l'applicazione.
Recupero dell'applicazione corrente
Poiché la funzionalità della Application classe viene condivisa in un'applicazione, può essere presente una sola istanza della Application classe per AppDomain. Per applicare questa operazione, la Application classe viene implementata come classe singleton (vedere Implementazione di Singleton in C#), che crea una singola istanza di se stessa e fornisce l'accesso condiviso con la static
Current proprietà .
Nel codice seguente viene illustrato come acquisire un riferimento all'oggetto per l'oggetto Application 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 Application classe . Se si desidera un riferimento alla Application classe derivata, è necessario eseguire il cast del valore della Current proprietà, 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 Application oggetto. Tuttavia, è bene fare attenzione. Dopo aver creato un'istanza della Application classe, è presente 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 Application proprietà impostate.
Quando Application completa il lavoro di inizializzazione, inizia veramente la sua durata.
Ciclo di vita dell'applicazione
La durata di un'applicazione WPF è contrassegnata da diversi eventi generati da Application per comunicare quando l'applicazione è stata avviata, è stata attivata e disattivata ed è stata arrestata.
Schermata iniziale
A partire da .NET Framework 3.5 SP1, è possibile specificare un'immagine da usare in una finestra di avvio o nella schermata iniziale. La SplashScreen classe semplifica la visualizzazione di una finestra di avvio durante il caricamento dell'applicazione. La SplashScreen finestra viene creata e visualizzata prima Run di essere chiamata. Per altre informazioni, vedere Tempo di avvio delle applicazioni e Aggiungere una schermata iniziale in un'applicazione WPF.
Avvio di un'applicazione
Dopo Run la chiamata 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 apre un oggetto Window all'avvio dell'esecuzione. Il Startup gestore eventi è 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 oggetto di cui creare un'istanza in un'applicazione autonoma diventa la finestra principale dell'applicazione per impostazione predefinita. Questo Window oggetto fa riferimento alla Application.MainWindow proprietà . Il valore della proprietà può essere modificato a livello di MainWindow codice se una finestra diversa dalla prima istanza Window deve essere la finestra principale.
All'avvio di un XBAP, è molto probabile che passi a un oggetto Page. Questo comportamento viene mostrato 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 si gestisce Startup di aprire solo un Window oggetto o passare a , Pageè possibile impostare l'attributo StartupUri
nel markup.
Nell'esempio seguente viene illustrato come usare da StartupUri un'applicazione autonoma per aprire un oggetto 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 oggetto 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 altre informazioni sulla navigazione, vedere Cenni preliminari sulla navigazione.
È necessario gestire l'evento Startup per aprire un Window oggetto se è necessario crearne un'istanza usando un costruttore senza parametri oppure impostare le relative 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 della riga di comando
In Windows le applicazioni autonome possono essere avviate da un prompt dei comandi o dal desktop. In entrambi i casi, è possibile passare argomenti della riga di comando all'applicazione. L'esempio seguente mostra un'applicazione 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 Startup gestore eventi tramite la Args proprietà del StartupEventArgs parametro . È possibile recuperare e archiviare gli argomenti della riga di comando usando un frammento di 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 gestisce Startup per verificare se è stato specificato l'argomento della riga di comando /StartMinimized. In tal caso, apre la finestra principale con un WindowState oggetto .Minimized Si noti che poiché la WindowState proprietà deve essere impostata a livello di codice, il main Window 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 parametri della stringa di query dagli URL usati per avviarle.
Attivazione e disattivazione dell'applicazione
Windows consente agli utenti di passare da un'applicazione all'altra. A questo scopo, il modo più comune consiste nell'usare la combinazione di tasti ALT+TAB. Un'applicazione può essere attivata solo se dispone di un oggetto visibile Window che un utente può selezionare. L'oggetto attualmente selezionato Window è la finestra attiva (nota anche come finestra in primo piano) ed è l'oggetto Window che riceve l'input dell'utente. L'applicazione con la finestra attiva è l'applicazione attiva, o applicazione in primo piano. Un'applicazione diventa l'applicazione attiva nei casi seguenti:
Viene avviato e mostra un oggetto Window.
Un utente passa da un'altra applicazione selezionando un Window oggetto nell'applicazione.
È possibile rilevare quando un'applicazione diventa attiva gestendo l'evento Application.Activated .
Analogamente, un'applicazione può diventare inattiva nei casi seguenti:
Un utente passa a un'altra applicazione da quella corrente.
L'applicazione viene arrestata.
È possibile rilevare quando un'applicazione diventa inattiva gestendo l'evento Application.Deactivated .
Il codice seguente illustra come gestire gli Activated eventi 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 oggetto può anche essere attivato e disattivato. Per altre informazioni, vedere Window.Activated e Window.Deactivated.
Nota
Né Application.Activated né Application.Deactivated viene generato per XBAP.
Arresto dell'applicazione
Il ciclo di vita di un'applicazione termina all'arresto dell'applicazione, che può essere dovuto ai motivi seguenti:
Un utente chiude ogni Windowoggetto .
Un utente chiude l'oggetto principale Window.
Un utente termina la sessione di Windows disconnettendosi o arrestando.
È stata soddisfatta una condizione specifica dell'applicazione.
Per gestire l'arresto dell'applicazione, Application fornisce il Shutdown metodo , la ShutdownMode proprietà e gli SessionEnding eventi 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 parzialmente attendibile dell'area Internet non lo fanno.
Modalità di arresto
La maggior parte delle applicazioni viene arrestata quando vengono chiuse tutte le finestre o quando viene chiusa la finestra principale. A volte, tuttavia, l'arresto può essere determinato da altre condizioni specifiche dell'applicazione. È possibile specificare le condizioni in cui l'applicazione verrà arrestata impostando ShutdownMode uno dei valori di enumerazione seguenti ShutdownMode :
Il valore predefinito di ShutdownMode è OnLastWindowClose, il che significa che un'applicazione si arresta 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 impostata su ShutdownMode OnMainWindowClose. 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"
ShutdownMode="OnMainWindowClose" />
Quando sono presenti condizioni di arresto specifiche dell'applicazione, impostare su ShutdownMode OnExplicitShutdown. In questo caso, è responsabilità dell'utente arrestare un'applicazione chiamando in modo esplicito il Shutdown metodo. In caso contrario, l'applicazione continuerà a essere in esecuzione anche se tutte le finestre vengono chiuse. Si noti che Shutdown viene chiamato in modo implicito quando ShutdownMode è OnLastWindowClose o OnMainWindowClose.
Nota
ShutdownMode può essere impostato da un XBAP, ma viene ignorato; un XBAP viene sempre arrestato quando viene spostato da un browser o quando il browser che ospita l'XBAP viene chiuso. Per altre informazioni, vedere Cenni preliminari sulla navigazione.
Fine della sessione
Le condizioni di arresto descritte dalla ShutdownMode proprietà sono specifiche di un'applicazione. In alcuni casi, tuttavia, un'applicazione può essere arrestata come conseguenza di una condizione esterna. La condizione esterna più comune si verifica quando un utente termina la sessione di Windows tramite le azioni seguenti:
Disconnessione
Arresto
Riavvio
Ibernazione
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 ReasonSessionEnding proprietà per determinare come termina la sessione di Windows. Il codice usa quindi questo valore per visualizzare un messaggio di conferma all'utente. Se l'utente non vuole che la sessione termini, il codice imposta Cancel per true
impedire la fine della sessione di Windows.
Nota
SessionEnding non viene generato per XBAP.
Esci
Quando un'applicazione viene arrestata, potrebbe dover eseguire alcune attività di elaborazione, come il salvataggio permanente dello stato dell'applicazione. Per queste situazioni, è possibile gestire l'evento Exit , come fa il App_Exit
gestore eventi nell'esempio seguente. Viene definito come gestore 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 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 XBAP. Per gli XBAP, Exit viene generato quando nelle circostanze seguenti:
Un XBAP viene spostato da.
In Internet Explorer, quando la scheda che ospita l'XBAP viene chiusa.
Viene chiuso il browser.
Codice di chiusura
Nella maggior parte dei casi, le applicazioni vengono avviate dal sistema operativo in risposta a una richiesta dell'utente. Tuttavia, un'applicazione può essere avviata da un'altra applicazione per l'esecuzione di alcune attività specifiche. Quando l'applicazione avviata viene arrestata, l'applicazione che ne esegue l'avvio potrebbe voler identificare la condizione in base alla quale è stata arrestata l'applicazione avviata. 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 quando l'applicazione viene arrestata, in un messaggio simile al seguente:
The program '[5340] AWPFApp.vshost.exe: Managed' has exited with code 0 (0x0).
Aprire la finestra Output facendo clic su Output dal menu Visualizza .
Per modificare il codice di uscita, è possibile chiamare l'overload Shutdown(Int32) , che 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 il valore del codice di uscita e modificarlo gestendo l'evento Exit . Il Exit gestore eventi viene passato a un oggetto ExitEventArgs che fornisce l'accesso al codice di uscita con la ApplicationExitCode proprietà . Per ulteriori 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ò essere arrestata in base a 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. Prima che l'applicazione venga chiusa, viene visualizzata una notifica simile a quella mostrata nella figura seguente.
Dal punto di vista dell'esperienza utente, è preferibile per un'applicazione evitare il comportamento predefinito eseguendo alcune o tutte le operazioni seguenti:
Visualizzare informazioni descrittive.
Tentare di mantenere in esecuzione un'applicazione.
Registrazione di informazioni dettagliate sulle eccezioni descrittive per gli sviluppatori nel registro eventi di Windows.
L'implementazione di questo supporto dipende dalla possibilità di rilevare eccezioni non gestite, ovvero l'evento 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 DispatcherUnhandledException gestore eventi viene passato un DispatcherUnhandledExceptionEventArgs parametro che contiene informazioni contestuali relative all'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 DispatcherUnhandledExceptionEventArgs.Handled proprietà 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 l'evento viene gestito e Handled viene impostato su false
, l'applicazione viene arrestata immediatamente. Inoltre, non vengono generati altri Application eventi. Di conseguenza, è necessario gestire DispatcherUnhandledException se l'applicazione dispone di codice che deve essere eseguito prima dell'arresto dell'applicazione.
Benché un'applicazione possa essere arrestata come conseguenza di un'eccezione non gestita, in genere viene arrestata in risposta a una richiesta dell'utente, come descritto nella prossima sezione.
Eventi del ciclo di vita dell'applicazione
Le applicazioni autonome e gli XBAP non hanno esattamente le stesse durate. La figura seguente mostra gli eventi principali nel ciclo di vita di un'applicazione autonoma, nella sequenza in cui vengono generati.
Analogamente, la figura seguente illustra gli eventi chiave nella durata di un XBAP e mostra la sequenza in cui vengono generati.
Vedi anche
.NET Desktop feedback