Freigeben über


Übersicht über die Anwendungsverwaltung

Dieses Thema bietet eine Übersicht über die Windows Presentation Foundation (WPF)-Dienste zum Erstellen und Verwalten von Anwendungen. Der Kernel einer WPF-Anwendung ist die Application-Klasse, die eine Vielzahl von Kernanwendungsdiensten unterstützt. Dieses Thema enthält eine Einführung in die wichtigsten dieser Dienste.

Dieses Thema enthält folgende Abschnitte.

  • Die Anwendungsklasse
  • Die Anwendungsdefinition
  • Abrufen der aktuellen Anwendung
  • Lebensdauer der Anwendung
  • Andere Anwendungsdienste
  • Verwandte Abschnitte

Die Anwendungsklasse

Eine Anwendung besteht aus vielen anwendungsspezifischen Elementen, einschließlich user interface (UI), Geschäftslogik, Datenzugriffslogik, Steuerelemente und Daten. Diese Elemente unterscheiden sich normalerweise zwischen Anwendungen. Alle Anwendungen verwenden aber in der Regel eine Reihe von Funktionen gemeinsam, was die Implementierung und Verwaltung von Anwendungen erleichtert. InWPF sind diese allgemeinen anwendungsspezifischen Funktionen durch die Application-Klasse gekapselt, die folgende Dienste bereitstellt:

  • Erstellen und Verwalten einer allgemeinen Anwendungsinfrastruktur

  • Verfolgen und Beeinflussen der Lebensdauer einer Anwendung

  • Abrufen und Verarbeiten von Befehlszeilenparametern

  • Freigeben anwendungsspezifischer Eigenschaften und Ressourcen

  • Erkennen von und Reagieren auf nicht behandelte Ausnahmen

  • Zurückgeben von Exitcodes

  • Verwalten von Fenstern in eigenständigen Anwendungen (siehe Übersicht über WPF-Fenster)

  • Verfolgen und Verwalten der Navigation (siehe Übersicht über die Navigation)

Wenn Sie diese Dienste in Ihrer Anwendung einsetzen möchten, müssen Sie die Application-Klasse zum Implementieren einer Anwendungsdefinition verwenden.

Die Anwendungsdefinition

Bei einer WPF-Anwendungsdefinition handelt es sich um eine Klasse, die von Application abgeleitet wird und mit einer speziellen Microsoft build engine (MSBuild)-Einstellung konfiguriert wurde.

Implementieren einer Anwendungsdefinition

Eine typische WPF-Anwendungsdefinition wird sowohl mit Markup als auch mit Code-Behind implementiert. Dies ermöglicht Ihnen die Verwendung von Markup zum deklarativen Festlegen der Eigenschaften und Ressourcen von Anwendungen sowie zum Registrieren von Ereignissen, während im Code-Behind die Ereignisbehandlung erfolgt und anwendungsspezifisches Verhalten implementiert wird.

Im folgenden Beispiel wird gezeigt, wie Sie eine Anwendungsdefinition sowohl mit Markup als auch mit Code-Behind implementieren:

<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 { }
}

Damit Markup- und Code-Behind-Datei zusammenarbeiten können, müssen folgende Voraussetzungen erfüllt sein:

  • Im Markup muss das Application-Element das x:Class-Attribut enthalten. Beim Erstellen der Anwendung führt das Vorhandensein von x:Class in der Markupdatei dazu, dass MSBuild eine partial-Klasse erstellt, die aus Application abgeleitet wird und den durch das x:Class-Attribut festgelegten Namen hat. Dies erfordert das Hinzufügen einer XML-Namespacedeklaration für das XAML-Schema (xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml").

  • Im Code-Behind muss die Klasse eine partial-Klasse mit demselben Namen sein, der im Markup durch das x:Class-Attribut angegeben ist, und sie muss von Application abgeleitet werden. Auf diese Weise kann die Code-Behind-Datei mit der partial-Klasse verknüpft werden, die beim Erstellen der Anwendung (siehe Erstellen einer WPF-Anwendung (WPF)) für die Markupdatei generiert wird.

HinweisHinweis

Wenn Sie mithilfe von Microsoft Visual Studio ein neues WPF-Anwendungsprojekt oder ein WPF-Browseranwendungsprojekt erstellen, ist standardmäßig eine Anwendungsdefinition enthalten, und die Definition erfolgt sowohl mit Markup als auch mit Code-Behind.

Dieser Code stellt die Mindestanforderung zum Implementieren einer Anwendungsdefinition dar. Bevor die Anwendung erstellt und ausgeführt werden kann, muss in der Anwendungsdefinition jedoch eine zusätzliche MSBuild-Konfiguration vorgenommen werden.

Konfigurieren der Anwendungsdefinition für MSBuild

Eigenständige Anwendungen und XAML browser applications (XBAPs) erfordern die Implementierung einer bestimmten Infrastrukturebene, bevor sie ausgeführt werden können. Der wichtigste Teil dieser Infrastruktur ist der Einstiegspunkt. Wenn eine Anwendung von einem Benutzer gestartet wird, ruft das Betriebssystem den Einstiegspunkt auf. Diese Funktion ist bekannt für das Starten von Anwendungen.

Bisher mussten Entwickler diesen Code zum Teil oder auch komplett selbst schreiben, je nach Technologie. In WPF wird dieser Code jedoch für Sie generiert, wenn die Markupdatei Ihrer Anwendungsdefinition als ApplicationDefinition-Element von MSBuild konfiguriert ist, wie in der folgenden Projektdatei von MSBuild veranschaulicht:

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

Da die Code-Behind-Datei Code enthält, wird sie ganz normal als ein Compile-Element von MSBuild gekennzeichnet.

Werden diese MSBuild-Konfigurationen auf die Markup- und Code-Behind-Dateien einer Anwendungsdefinition angewendet, generiert MSBuild Code, der dem folgenden ähnelt:


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()
        {


...


        }
    }
}

Durch den resultierenden Code wird die Anwendungsdefinition um zusätzlichen Infrastrukturcode erweitert, darunter die Einstiegspunktmethode Main. Das STAThreadAttribute-Attribut wird auf die Main-Methode angewendet. Damit wird angegeben, dass der Hauptthread der UI für die WPF-Anwendung ein STA-Thread ist, der für WPF-Anwendungen erforderlich ist. Beim Aufrufen erstellt Main eine neue Instanz von App, bevor die InitializeComponent-Methode aufgerufen wird, um die Ereignisse zu registrieren und die im Markup implementierten Eigenschaften festzulegen. Da InitializeComponent automatisch für Sie generiert wird, müssen Sie InitializeComponent nicht explizit aus einer Anwendungsdefinition aufrufen, wie es bei einer Page-Implementierung und Window-Implementierung der Fall ist. Abschließend wird die Run-Methode zum Starten der Anwendung aufgerufen.

Abrufen der aktuellen Anwendung

Da die Dienste der Application-Klasse innerhalb einer Anwendung gemeinsam verwendet werden, kann es nur eine Instanz der Application-Klasse pro AppDomain geben. Um dies zu erzwingen, wird die Application-Klasse als Singletonklasse implementiert (siehe Implementing Singleton in C#). Diese erstellt eine einzelne Instanz von sich selbst und ermöglicht den gemeinsamen Zugriff mit der static Current-Eigenschaft.

Der folgende Code zeigt, wie ein Verweis auf das Application-Objekt für die aktuelle AppDomain abgerufen wird.

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

Current gibt einen Verweis auf eine Instanz der Application-Klasse zurück. Wenn Sie einen Verweis auf die abgeleitete Application-Klasse benötigen, müssen Sie den Wert der Current-Eigenschaft umwandeln, wie im folgenden Beispiel gezeigt.

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

Sie können den Wert von Current zu jedem Zeitpunkt in der Lebensdauer eines Application-Objekts überprüfen. Gehen Sie dabei vorsichtig vor. Nachdem die Application-Klasse instanziiert wurde, tritt ein Zeitraum auf, in dem der Zustand des Application-Objekts inkonsistent ist. Während dieses Zeitraums führt Application die verschiedenen Initialisierungsaufgaben durch, die zum Ausführen des Codes erforderlich sind. Dazu gehören das Einrichten der Anwendungsinfrastruktur, das Festlegen von Eigenschaften und das Registrieren von Ereignissen. Wenn Sie während dieses Zeitraums versuchen, das Application-Objekt zu verwenden, gibt der Code möglicherweise unerwartete Ergebnisse zurück, insbesondere dann, wenn er von den verschiedenen festgelegten Application-Eigenschaften abhängt.

Wenn Application die Initialisierung abgeschlossen hat, beginnt die eigentliche Lebensdauer.

Lebensdauer der Anwendung

Die Lebensdauer einer WPF-Anwendung ist durch verschiedene Ereignisse gekennzeichnet, die von Application ausgelöst werden. Sie informieren darüber, wann die Anwendung gestartet, aktiviert und deaktiviert sowie heruntergefahren wurde.

Dieser Abschnitt enthält folgende Unterabschnitte.

  • Begrüßungsbildschirm
  • Starten einer Anwendung
  • Anzeigen einer Benutzeroberfläche
  • Verarbeiten von Befehlszeilenargumenten
  • Aktivieren und Deaktivieren von Anwendungen
  • Herunterfahren einer Anwendung
  • Nicht behandelte Ausnahmen
  • Lebensdauerereignisse der Anwendung

Begrüßungsbildschirm

Wenn Sie in .NET Framework 3.5 SP1 starten, können Sie ein Bild angeben, das in einem Startfenster oder im Begrüßungsbildschirm verwendet werden soll. Mit der SplashScreen-Klasse ist es einfach, ein Startfenster anzuzeigen, während die Anwendung geladen wird. Das Fenster SplashScreen wird erstellt und angezeigt, bevor Run aufgerufen wird. Weitere Informationen finden Sie unter Startzeit der Anwendung und unter Gewusst wie: Hinzufügen eines Begrüßungsbildschirms zu einer WPF-Anwendung.

Starten einer Anwendung

Nach dem Aufrufen von Run und dem Initialisieren der Anwendung kann sie ausgeführt werden. Dieser Zeitpunkt wird durch Auslösen des Startup-Ereignisses angezeigt:


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


...


        }
    }
}

Wenn dieser Zeitpunkt in der Lebensdauer einer Anwendung gekommen ist, wird in der Regel eine UI angezeigt.

Anzeigen einer Benutzeroberfläche

In den meisten eigenständigen Windows-Anwendungen wird Window geöffnet, wenn ihre Ausführung beginnt. Wie im folgenden Code veranschaulicht, stellt der Startup-Ereignishandler einen geeigneten Ausgangspunkt dafür dar.

<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();
        }
    }
}
HinweisHinweis

Das erste Window, das in einer eigenständigen Anwendung instanziiert werden soll, wird standardmäßig zum Hauptanwendungsfenster.Auf dieses Window-Objekt wird von der Application.MainWindow-Eigenschaft verwiesen.Der Wert der MainWindow-Eigenschaft kann programmgesteuert geändert werden, wenn ein anderes Fenster als das zuerst instanziierte Window das Hauptfenster sein soll.

Wenn zuerst eine XBAP gestartet wird, navigiert diese wahrscheinlich zu einer Page. Dies wird im folgenden Code veranschaulicht.

<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));
        }
    }
}

Wenn Sie Startup so behandeln, dass nur ein Window geöffnet oder zu einer Page navigiert wird, können Sie stattdessen das StartupUri-Attribut im Markup festlegen.

Im folgenden Beispiel wird gezeigt, wie Sie die StartupUri einer eigenständigen Anwendung verwenden, um ein Window zu öffnen.

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

Im folgenden Beispiel wird gezeigt, wie Sie unter Verwendung von StartupUri von einer XBAP zu einer Page navigieren können.

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

Dieses Markup hat denselben Effekt wie der vorherige Code zum Öffnen eines Fensters.

HinweisHinweis

Weitere Informationen zur Navigation finden Sie unter Übersicht über die Navigation.

Sie müssen das Startup-Ereignis behandeln, um ein Window zu öffnen, wenn Sie es mithilfe eines nicht standardmäßigen Konstruktors instanziieren müssen. Oder Sie müssen die Eigenschaften festlegen bzw. Ereignisse abonnieren, bevor Sie das Fenster anzeigen. Sie können aber auch alle Befehlszeilenargumente verarbeiten, die beim Starten der Anwendung bereitgestellt wurden.

Verarbeiten von Befehlszeilenargumenten

In Windows können eigenständige Anwendungen über eine Eingabeaufforderung oder auf dem Desktop gestartet werden. In beiden Fällen können Befehlszeilenargumente an die Anwendung übergeben werden. Im folgenden Beispiel sehen Sie eine Anwendung, die mit nur einem Befehlszeilenargument ("/StartMinimized") gestartet wird:

wpfapplication.exe /StartMinimized

Während der Anwendungsinitialisierung ruft WPF die Befehlszeilenargumente vom Betriebssystem ab und übergibt sie über die Args-Eigenschaft des StartupEventArgs-Parameters an den Startup-Ereignishandler. Mit Code wie dem folgenden können Sie Befehlszeilenargumente abrufen und speichern.

<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();
        }
    }
}

Der Code behandelt Startup, um zu überprüfen, ob das /StartMinimized-Befehlszeilenargument angegeben wurde. Ist das der Fall, wird das Hauptfenster mit der WindowState-Eigenschaft Minimized geöffnet. Da die WindowState-Eigenschaft programmgesteuert festgelegt sein muss, ist es erforderlich, das Haupt-Window explizit im Code zu öffnen.

XBAPs können keine Befehlszeilenargumente abrufen und verarbeiten, da sie mit ClickOnce-Bereitstellung gestartet werden (siehe Bereitstellen von WPF-Anwendungen (WPF)). Von den zum Starten verwendeten URLs können jedoch Abfragezeichenfolgenparameter abgerufen und verarbeitet werden.

Aktivieren und Deaktivieren von Anwendungen

Windows ermöglicht es Benutzern, zwischen Anwendungen zu wechseln. Meistens wird dazu die Tastenkombination ALT+TAB verwendet. Es kann nur dann zu einer Anwendung gewechselt werden, wenn sie über ein sichtbares Window verfügt, das ein Benutzer auswählen kann. Das derzeit ausgewählte Window ist das aktive Fenster (oder Vordergrundfenster) und das Window, das Benutzereingaben empfängt. Die Anwendung mit dem aktiven Fenster ist die aktive Anwendung (oder Vordergrundanwendung). Eine Anwendung wird unter folgenden Umständen zur aktiven Anwendung:

  • Sie wird gestartet und zeigt ein Window an.

  • Ein Benutzer wechselt von einer anderen Anwendung, indem er in der Anwendung ein Window auswählt.

Sie können erkennen, wann eine Anwendung aktiv wird, indem Sie das Application.Activated-Ereignis behandeln.

Auf ähnliche Weise kann eine Anwendung unter folgenden Umständen inaktiv werden:

  • Ein Benutzer wechselt von der aktuellen zu einer anderen Anwendung.

  • Wenn die Anwendung heruntergefahren wird.

Sie können erkennen, wann eine Anwendung inaktiv wird, indem Sie das Application.Deactivated-Ereignis behandeln.

Der folgende Code veranschaulicht, wie Sie das Activated-Ereignis und das Deactivated-Ereignis behandeln, um zu ermitteln, ob eine Anwendung aktiv ist.

<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;
        }
    }
}

Ein Window kann auch aktiviert und deaktiviert werden. Weitere Informationen finden Sie unter Window.Activated und Window.Deactivated.

HinweisHinweis

Weder Application.Activated noch Application.Deactivated werden für XBAPs ausgelöst.

Herunterfahren einer Anwendung

Die Lebensdauer einer Anwendung endet mit dem Herunterfahren, das aus folgenden Gründen erfolgen kann:

  • Ein Benutzer schließt die einzelnen Window.

  • Ein Benutzer schließt das Haupt-Window.

  • Der Benutzer beendet die Windows-Sitzung, indem er sich abmeldet oder die Anwendung herunterfährt.

  • Eine anwendungsspezifische Bedingung wurde erfüllt.

Um Sie bei der Verwaltung des Herunterfahrens von Anwendungen zu unterstützen, stellt Application die Shutdown-Methode, die ShutdownMode-Eigenschaft und das SessionEnding-Ereignis sowie das Exit-Ereignis bereit.

HinweisHinweis

Shutdown kann nur von Anwendungen aufgerufen werden, die über UIPermission verfügen.Eigenständige WPF-Anwendungen verfügen immer über diese Berechtigung.Dies ist bei XBAPs, die im teilweise vertrauenswürdigen Sicherheitsbereich (Sandbox) der Internetzone ausgeführt werden, nicht der Fall.

Modus für das Herunterfahren

Anwendungen werden in der Regel entweder heruntergefahren, wenn alle Fenster geschlossen werden, oder wenn das Hauptfenster geschlossen wird. Manchmal kann jedoch auch durch andere anwendungsspezifische Bedingungen bestimmt werden, wann eine Anwendung heruntergefahren wird. Sie können die Bedingungen, unter denen eine Anwendung heruntergefahren werden soll, dadurch angeben, dass Sie ShutdownMode mit einem der folgenden ShutdownMode-Enumerationswerte festlegen:

Der Standardwert von ShutdownMode ist OnLastWindowClose, was bedeutet, dass eine Anwendung automatisch heruntergefahren wird, sobald das letzte Fenster in der Anwendung vom Benutzer geschlossen wird. Ein Herunterfahren der Anwendung beim Schließen des Hauptfensters wird von WPF automatisch ausgeführt, wenn Sie ShutdownMode auf OnMainWindowClose festlegen. Dies wird im folgenden Beispiel gezeigt.

<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" />

Liegen anwendungsspezifische Bedingungen zum Herunterfahren vor, legen Sie ShutdownMode auf OnExplicitShutdown fest. In diesem Fall müssen Sie sicherstellen, dass Sie eine Anwendung herunterfahren, indem Sie explizit die Shutdown-Methode aufrufen. Andernfalls wird die Anwendung weiterhin ausgeführt, auch wenn alle Fenster geschlossen sind. Beachten Sie, dass Shutdown implizit aufgerufen wird, wenn ShutdownMode entweder OnLastWindowClose oder OnMainWindowClose ist.

HinweisHinweis

ShutdownMode kann von einer XBAP festgelegt werden, wird aber ignoriert. Eine XBAP wird immer heruntergefahren, wenn in einem Browser von ihr weg navigiert wird oder wenn der Browser, der die XBAP hostet, geschlossen wird.Weitere Informationen finden Sie unter Übersicht über die Navigation.

Beenden einer Sitzung

Die durch die ShutdownMode-Eigenschaft beschriebenen Bedingungen zum Herunterfahren sind spezifisch für eine Anwendung. In einigen Fällen kann eine Anwendung aber auch als Ergebnis einer externen Bedingung heruntergefahren werden. Die gängigste externe Bedingung tritt auf, wenn ein Benutzer die Windows-Sitzung durch die folgenden Aktionen beendet:

  • Abmelden

  • Herunterfahren

  • Neustarten

  • Wechseln in den Ruhezustand

Um zu erkennen, wann eine Windows-Sitzung endet, können Sie das SessionEnding-Ereignis behandeln, wie in folgendem Beispiel gezeigt.

<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 diesem Beispiel überprüft der Code die ReasonSessionEnding-Eigenschaft, um festzustellen, wie die Windows-Sitzung beendet wird. Dieser Wert wird verwendet, um dem Benutzer eine Bestätigungsmeldung anzuzeigen. Wenn der Benutzer das Beenden der Sitzung verhindern möchte, wird Cancel durch den Code auf true festgelegt. Dann wird die Windows-Sitzung nicht beendet.

HinweisHinweis

SessionEnding wird für XBAPs nicht ausgelöst.

Exit

Beim Herunterfahren einer Anwendung werden evtl. abschließende Verarbeitungsaufgaben ausgeführt, z. B. Beibehalten des Anwendungszustands. In diesen Situationen können Sie das Exit-Ereignis behandeln.

<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]);
                }
            }
        }
    }
}

Das vollständige Beispiel finden Sie unter Gewusst wie: Beibehalten und Wiederherstellen von Eigenschaften für den Anwendungsbereich über mehrere Anwendungssitzungen.

Exit kann sowohl von eigenständigen Anwendungen als auch von XBAPs behandelt werden. Bei XBAPs wird Exit unter den folgenden Umständen ausgelöst:

  • Es wird von einer XBAP weg navigiert.

  • In Internet Explorer 7, wenn die Registerkarte geschlossen wird, die die XBAP hostet.

  • Wenn der Browser geschlossen wird.

Exitcode

Anwendungen werden meistens durch das Betriebssystem als Reaktion auf eine Benutzeranforderung gestartet. Eine Anwendung kann aber auch von einer anderen Anwendung gestartet werden, um eine bestimmte Aufgabe zu übernehmen. Wenn die gestartete Anwendung heruntergefahren wird, muss die startende Anwendung möglicherweise über die Bedingung informiert werden, unter der die gestartete Anwendung heruntergefahren wurde. In diesen Situationen ermöglicht Windows es Anwendungen, beim Herunterfahren einen Anwendungsexitcode zurückzugeben. Standardmäßig geben WPF-Anwendungen den Exitcodewert 0 (null) zurück.

HinweisHinweis

Wenn Sie aus Visual Studio debuggen, wird der Anwendungsexitcode beim Herunterfahren im Ausgabefenster angezeigt. Die entsprechende Meldung sieht ungefähr folgendermaßen aus:

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

Sie öffnen das Ausgabefenster, indem Sie im Menü Ansicht auf Ausgabe klicken.

Zum Ändern des Exitcodes können Sie die Shutdown(Int32)-Überladung aufrufen, die ein Ganzzahlargument als Exitcode akzeptiert:

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

Sie können den Wert des Exitcodes ermitteln und ändern, indem Sie das Exit-Ereignis behandeln. Der Exit-Ereignishandler wird an ExitEventArgs übergeben. Dadurch wird der Zugriff auf den Exitcode mit der ApplicationExitCode-Eigenschaft ermöglicht. Weitere Informationen finden Sie unter Exit.

HinweisHinweis

Sie können den Exitcode sowohl in eigenständigen Anwendungen als auch in XBAPs festlegen.Der Exitcodewert wird für XBAPs allerdings ignoriert.

Nicht behandelte Ausnahmen

Es kommt vor, dass eine Anwendung unter nicht ordnungsgemäßen Bedingungen heruntergefahren wird, z. B. wenn eine unerwartete Ausnahme ausgelöst wird. In diesem Fall verfügt die Anwendung möglicherweise nicht über den Code, der zum Erkennen und Verarbeiten der Ausnahme erforderlich ist. Eine solche Ausnahme wird als nicht behandelte Ausnahme bezeichnet. Vor dem Schließen der Anwendung wird eine Meldung angezeigt, die der folgenden ähnelt.

Benachrichtigung über Ausnahmefehler

Für die Benutzererfahrung ist es vorteilhafter, wenn eine Anwendung dieses Standardverhalten vermeidet. Dazu dienen mehrere oder alle der folgenden Aktionen:

  • Anzeigen von benutzerfreundlichen Informationen

  • Versuchen, eine Anwendung weiterhin auszuführen

  • Aufzeichnen ausführlicher, entwicklerfreundlicher Ausnahmeinformationen im Windows-Ereignisprotokoll

Die Implementierung dieser Unterstützung hängt von der Fähigkeit ab, nicht behandelte Ausnahmen zu erkennen, was der Grund für das Auslösen des DispatcherUnhandledException-Ereignisses ist.

<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;
        }
    }
}

An den DispatcherUnhandledException-Ereignishandler wird ein DispatcherUnhandledExceptionEventArgs-Parameter übergeben, der Kontextinformationen zur nicht behandelten Ausnahme enthält, darunter die Ausnahme selbst (DispatcherUnhandledExceptionEventArgs.Exception). Sie können anhand dieser Informationen feststellen, wie die Ausnahme behandelt werden soll.

Beim Behandeln von DispatcherUnhandledException sollten Sie die DispatcherUnhandledExceptionEventArgs.Handled-Eigenschaft auf true festlegen. Ansonsten betrachtet WPF die Ausnahme weiterhin als unbehandelt und stellt das zuvor beschriebene Standardverhalten wieder her. Wird eine nicht behandelte Ausnahme ausgelöst und das DispatcherUnhandledException-Ereignis nicht behandelt, oder es wird behandelt, während Handled auf false festgelegt ist, wird die Anwendung sofort heruntergefahren. Darüber hinaus werden keine anderen Application-Ereignisse ausgelöst. Folglich müssen Sie DispatcherUnhandledException behandeln, wenn die Anwendung über Code verfügt, der vor dem Herunterfahren ausgeführt werden muss.

Obwohl eine Anwendung wegen einer nicht behandelten Ausnahme heruntergefahren werden kann, erfolgt das Herunterfahren normalerweise als Reaktion auf eine Benutzeranforderung, wie im nächsten Abschnitt beschrieben.

Lebensdauerereignisse der Anwendung

Eigenständige Anwendungen und XBAPs haben nicht genau dieselbe Lebensdauer. Die folgende Abbildung veranschaulicht die wichtigsten Ereignisse in der Lebensdauer einer eigenständigen Anwendung und die Reihenfolge, in der sie ausgelöst werden.

Eigenständige Anwendung - Anwendungsobjektereignisse

Entsprechend veranschaulicht die folgende Abbildung die wichtigsten Ereignisse in der Lebensdauer einer XBAP und zeigt, in welcher Reihenfolge diese ausgelöst werden.

XBAP - Anwendungsobjektereignisse

Andere Anwendungsdienste

Zusätzlich zum Verwalten der Lebensdauer von Anwendungen stellt Application Dienste wie die folgenden bereit:

  • Freigegebene anwendungsspezifische Eigenschaften

  • Freigegebene anwendungsspezifische Ressourcen

  • Anwendungsressourcen-, Inhalts- und Ursprungssite-Datendateien

  • Fensterverwaltung

  • Navigationsverwaltung

Freigegebene anwendungsspezifische Eigenschaften

Eine Anwendung stellt die Properties-Eigenschaft bereit, um den Zustand verfügbar zu machen, der anwendungsübergreifend gemeinsam genutzt werden kann. Es folgt ein Beispiel für die Verwendung von 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"];

Nachfolgend erhalten Sie weitere Informationen:

Freigegebene anwendungsspezifische Ressourcen

Die Anwendung stellt die Resources-Eigenschaft bereit, damit Entwickler UI-Ressourcen anwendungsübergreifend gemeinsam nutzen können. Es folgt ein Beispiel für die Verwendung von 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"];

Nachfolgend erhalten Sie weitere Informationen:

Anwendungsressourcen-, Inhalts- und Ursprungssite-Datendateien

WPF-Anwendungen können mehrere Typen von Datendateien ohne Code verwalten, darunter Ressourcendateien, Inhaltsdateien und Dateien der Ursprungssite. Zum Laden dieser Datendateitypen können folgende Hilfsmethoden verwendet werden:

Fensterverwaltung

Application und Window stehen in enger Beziehung zueinander. Wie Sie gesehen haben, kann die Lebensdauer einer Anwendung von der Lebensdauer ihrer Fenster abhängen, wie durch die ShutdownMode-Eigenschaft angegeben. Application zeichnet auf, welches Fenster als Hauptanwendungsfenster gekennzeichnet ist (Application.MainWindow) und verwaltet eine Liste der zurzeit instanziierten Fenster (Application.Windows).

Weitere Informationen hierzu finden Sie unter Übersicht über WPF-Fenster.

Bei eigenständigen Anwendungen mit Navigation (unter Verwendung von NavigationWindow und Frame) oder bei XBAPs erkennt Application alle Navigationsvorgänge innerhalb einer Anwendung und löst ggf. die folgenden Ereignisse aus:

Darüber hinaus bietet Application die Möglichkeit für Anwendungen jedes Typs, Cookies zu erstellen, beizubehalten und abzurufen. Dies geschieht unter Verwendung von GetCookie und SetCookie

Weitere Informationen finden Sie unter Übersicht über die Navigation.

Siehe auch

Referenz

Application

Konzepte

Übersicht über WPF-Fenster

Übersicht über die Navigation

WPF-Anwendungsressource, Inhalts- und Datendateien

Paket-URI in WPF

Anwendungsentwicklung

Weitere Ressourcen

Anwendungsmodell: Gewusst wie-Themen