Freigeben über


Übersicht über WPF-Fenster

Benutzer interagieren über Fenster mit eigenständigen Windows Presentation Foundation (WPF)-Anwendungen. Die Hauptaufgabe eines Fensters besteht darin, Inhalt zu hosten, der Daten visuell darstellen kann und Benutzern die Interaktion mit Daten ermöglicht. Eigenständige WPF-Anwendungen stellen mithilfe der Window-Klasse eigene Fenster bereit. In diesem Thema wird Window vorgestellt, bevor die Grundlagen der Erstellung und Verwaltung von Fenstern in eigenständigen Anwendungen behandelt werden.

HinweisHinweis

Im Browser gehostete WPF-Anwendungen, einschließlich XAML browser applications (XBAPs) und Loose Extensible Application Markup Language (XAML)-Seiten, stellen keine eigenen Fenster zur Verfügung.Stattdessen werden sie in von Windows Internet Explorer bereitgestellten Fenstern gehostet.Weitere Informationen finden Sie unter Übersicht über WPF-XAML-Browseranwendungen.

Dieses Thema enthält folgende Abschnitte.

  • Die Fensterklasse
  • Implementieren eines Fensters
  • Konfigurieren einer Fensterdefinition für MSBuild
  • Fensterlebensdauer
  • Fensterposition
  • Fenstergröße
  • Rangfolge der Größeneigenschaften
  • Fensterzustand
  • Fensterdarstellung
  • Sicherheitsüberlegungen
  • Andere Fenstertypen
  • Verwandte Abschnitte

Die Fensterklasse

In der folgenden Abbildung werden die Bestandteile eines Fensters dargestellt.

Fensterelemente

Ein Fenster wird in zwei Bereiche geteilt: der Nicht-Clientbereich und der Clientbereich.

Der Nicht-Clientbereich eines Fensters wird mit WPF implementiert und enthält die Teile eines Fenster, die den meisten Fenstern gemeinsam sind, einschließlich:

  • Rahmen

  • Titelleiste

  • Symbol

  • Schaltflächen zum Minimieren, Maximieren und Wiederherstellen

  • Schaltfläche Schließen

  • Ein Systemmenü mit Menüelementen, mit denen Benutzer ein Fenster minimieren, maximieren, wiederherstellen, verschieben, schließen und dessen Größe ändern können.

Der Clientbereich eines Fensters befindet sich im Nicht-Clientbereich eines Fensters und wird von Entwicklern dazu verwendet, anwendungsspezifischen Inhalt hinzuzufügen, z. B. Menüleisten, Symbolleisten und Steuerelemente.

In WPF wird ein Fenster von der Window-Klasse gekapselt, die Sie für folgende Aufgaben verwenden:

  • Anzeigen eines Fensters

  • Konfigurieren der Größe, Position und Darstellung eines Fensters

  • Hosten von anwendungsspezifischem Inhalt

  • Verwalten der Lebensdauer eines Fensters

Implementieren eines Fensters

Die Implementierung eines typischen Fensters umfasst die Darstellung und das Verhalten. Dabei definiert die Darstellung, wie ein Fenster einem Benutzer angezeigt wird und das Verhalten die Funktionsweise eines Fensters bei der Interaktion mit Benutzern. In WPF können Sie die Darstellung und das Verhalten eines Fensters entweder mit Code oder mit XAML-Markup implementieren.

Im Allgemeinen wird die Darstellung eines Fenster jedoch mit XAML-Markup und dessen Verhalten mit Code-Behind implementiert, wie im folgenden Beispiel gezeigt.

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

  <!-- Client area (for content) -->

</Window>

Imports System.Windows ' Window

Namespace SDKSample
    Partial Public Class MarkupAndCodeBehindWindow
        Inherits Window
        Public Sub New()
            InitializeComponent()
        End Sub
    End Class
End Namespace
using System.Windows; // Window

namespace SDKSample
{
    public partial class MarkupAndCodeBehindWindow : Window
    {
        public MarkupAndCodeBehindWindow()
        {
            InitializeComponent();
        }
    }
}

Folgende Voraussetzungen müssen erfüllt sein, damit die XAML-Markupdatei und die Code-Behind-Datei zusammenarbeiten:

  • Im Markup muss das Window-Element das x:Class-Attribut enthalten. Beim Erstellen der Anwendung führt das Vorhandensein von x:Class in der Markupdatei dazu, dass Microsoft build engine (MSBuild) eine partial-Klasse erstellt, die von Window abgeleitet wird und den durch das x:Class-Attribut festgelegten Namen erhält. Dies erfordert das Hinzufügen einer XML-Namespacedeklaration für das XAML-Schema (xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"). Die generierte partial-Klasse implementiert die InitializeComponent-Methode, die zum Registrieren der Ereignisse und Festlegen der Eigenschaften aufgerufen wird, die im Markup implementiert werden.

  • Bei 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 Window 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.

  • Bei Code-Behind muss die Window-Klasse einen Konstruktor implementieren, der die InitializeComponent-Methode aufruft. InitializeComponent wird durch die generierte partial-Klasse der Markupdatei implementiert, um Ereignisse zu registrieren und im Markup definierte Eigenschaften festzulegen.

HinweisHinweis

Wenn Sie Ihrem Projekt ein neues Window mithilfe von Microsoft Visual Studio hinzufügen, wird Window unter Verwendung von Markup und Code-Behind implementiert. Außerdem wird eine Konfiguration eingefügt, die zum Erstellen der Verknüpfung zwischen Markup- und Code-Behind-Dateien, wie hier beschrieben, benötigt wird.

Mit dieser Konfiguration können Sie den Fokus auf das Definieren der Fensterdarstellung in XAML-Markup richten und das Fensterverhalten in Code-Behind implementieren. Im folgenden Beispiel wird ein Fenster mit einer Schaltfläche gezeigt, das in XAML-Markup implementiert wurde, sowie ein Ereignishandler für das Click-Ereignis der Schaltfläche, der in Code-Behind implementiert wurde.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.MarkupAndCodeBehindWindow">
  <!-- Client area (for content) -->
  <Button Click="button_Click">Click This Button</Button>
</Window>

Imports System.Windows

Namespace SDKSample
    Partial Public Class MarkupAndCodeBehindWindow
        Inherits Window
        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            MessageBox.Show("Button was clicked.")
        End Sub
    End Class
End Namespace
using System.Windows;

namespace SDKSample
{
    public partial class MarkupAndCodeBehindWindow : Window
    {
        public MarkupAndCodeBehindWindow()
        {
            InitializeComponent();
        }

        void button_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Button was clicked.");
        }
    }
}

Konfigurieren einer Fensterdefinition für MSBuild

Die Implementierung des Fensters bestimmt dessen Konfiguration für MSBuild. Für ein Fenster, das sowohl mit XAML-Markup als auch mit Code-Behind definiert ist:

  • XAML-Markup-Dateien werden als MSBuild Page-Elemente konfiguriert.

  • Code-Behind-Dateien werden als MSBuild Compile-Elemente konfiguriert.

Dies wird in der folgenden MSBuild-Projektdatei veranschaulicht.

<Project ... xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
    ...
    <Page Include="MarkupAndCodeBehindWindow.xaml" />
    <Compile Include=" MarkupAndCodeBehindWindow.xaml.cs" />
    ...
</Project>

Weitere Informationen zum Erstellen von WPF-Anwendungen finden Sie unter Erstellen einer WPF-Anwendung (WPF).

Fensterlebensdauer

Wie alle Klassen hat auch ein Fenster eine Lebensdauer, die mit dem erstmaligen Instanziieren beginnt. Anschließend wird es geöffnet, aktiviert, deaktiviert und schließlich geschlossen.

Dieser Abschnitt enthält folgende Unterabschnitte.

  • Öffnen eines Fensters
  • Aktivieren von Fenstern
  • Schließen eines Fensters
  • Ereignisse in der Lebensdauer eines Fensters

Öffnen eines Fensters

Wenn Sie ein Fenster öffnen möchten, müssen Sie zuerst eine Instanz davon erstellen. Dies wird im folgenden Beispiel veranschaulicht.

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

Imports System.Windows

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub app_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
            ' Create a window
            Dim window As New MarkupAndCodeBehindWindow()

            ' Open a window
            window.Show()
        End Sub
    End Class
End Namespace
using System.Windows;
namespace SDKSample
{
    public partial class App : Application
    {
        void app_Startup(object sender, StartupEventArgs e)
        {
            // Create a window
            MarkupAndCodeBehindWindow window = new MarkupAndCodeBehindWindow();

            // Open a window
            window.Show();
        }
    }
}

In diesem Beispiel wird MarkupAndCodeBehindWindow beim Starten der Anwendung instanziiert, was beim Auslösen des Startup-Ereignisses erfolgt.

Wird ein Fenster instanziiert, wird einer Liste der vom Application-Objekt verwalteten Fenster automatisch ein Verweis darauf hinzugefügt (siehe Application.Windows). Zusätzlich wird das erste zu instanziierende Fenster standardmäßig von Application als Hauptanwendungsfenster festgelegt (siehe Application.MainWindow).

Schließlich wird das Fenster durch Aufrufen der Show-Methode geöffnet. Das Ergebnis wird in der folgenden Abbildung dargestellt.

Ein durch den Aufruf von Window.Show geöffnetes Fenster

Ein durch Aufrufen von Show geöffnetes Fenster wird als nicht modales Fenster bezeichnet. Das bedeutet, dass die Anwendung in einem Modus ausgeführt wird, in dem Benutzer weitere Fenster in derselben Anwendung öffnen können.

HinweisHinweis

ShowDialog wird aufgerufen, um Fenster, z. B. Dialogfelder, modal aufzurufen.Weitere Informationen finden Sie unter Übersicht über Dialogfelder.

Wenn Show aufgerufen wird, führt ein Fenster die Initialisierung aus, bevor es zum Festlegen der Infrastruktur angezeigt wird, durch die es Benutzereingaben empfangen kann. Wenn das Fenster initialisiert wird, wird das SourceInitialized-Ereignis ausgelöst, und das Fenster wird angezeigt.

Als Arbeitserleichterung kann StartupUri so festgelegt werden, dass er das Fenster angibt, das beim Starten der Anwendung automatisch geöffnet wird.

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

Wenn die Anwendung gestartet wird, wird das durch den Wert von StartupUri angegebene Fenster im nicht modalen Modus geöffnet. Intern wird das Fenster durch Aufrufen der Show-Methode geöffnet.

Besitz von Fenstern

Zwischen dem mit der Show-Methode geöffneten Fenster und dem Fenster, von dem es erstellt wurde, besteht keine implizite Beziehung. Benutzer können mit dem jeweiligen Fenster unabhängig interagieren. Infolgedessen kann jedes Fenster folgende Aufgaben ausführen:

  • Das andere Fenster überdecken (es sei denn, die Topmost-Eigenschaft eines der Fenster ist auf true festgelegt).

  • Es wird minimiert, maximiert und wiederhergestellt, ohne das andere zu beeinflussen.

Bei einigen Fenstern ist eine Beziehung zu dem Fenster erforderlich, durch das es geöffnet wird. Eine Integrated Development Environment (IDE)-Anwendung kann beispielsweise Eigenschaftenfenster und Toolfenster öffnen, deren typisches Verhalten es ist, das Fenster zu überdecken, von dem es erstellt wurde. Darüber hinaus sollten solche Fenster stets mit den Fenstern geschlossen, minimiert, maximiert und wiederhergestellt werden, durch die sie erstellt wurden. Eine solche Beziehung lässt sich herstellen, indem festgelegt wird, dass ein Fenster das andere besitzt. Dazu legen Sie die Owner-Eigenschaft von zum Besitzer gehöriges Fenster mit einem Verweis auf Besitzerfenster fest. Dies wird im folgenden Beispiel gezeigt.

' Create a window and make this window its owner
Dim ownedWindow As New Window()
ownedWindow.Owner = Me
ownedWindow.Show()
// Create a window and make this window its owner
Window ownedWindow = new Window();
ownedWindow.Owner = this;
ownedWindow.Show();

Nach Einrichten des Besitzes:

  • Das zum Besitzer gehörige Fenster kann auf sein Besitzerfenster verweisen, indem der Wert der Owner-Eigenschaft überprüft wird.

  • Das Besitzerfenster kann alle ihm gehörenden Fenster durch Überprüfen des Wertes der OwnedWindows-Eigenschaft ermitteln.

Verhindern der Fensteraktivierung

Es gibt Szenarien, in denen angezeigte Fenster nicht aktiviert werden sollten, z. B. Unterhaltungsfenster einer Internet-Messenger-Anwendung oder Benachrichtigungsfenster einer E-Mail-Anwendung.

Falls Ihre Anwendung ein Fenster bereitstellt, das nicht aktiviert werden sollte, wenn Sie es anzeigen, können Sie die ShowActivated-Eigenschaft auf false festlegen, bevor Sie die Show-Methode zum ersten Mal ausführen. Daraus folgt:

  • Das Fenster wird nicht aktiviert.

  • Das Activated-Ereignis des Fensters wird nicht ausgelöst.

  • Das momentan aktivierte Fenster bleibt aktiviert.

Das Fenster wird jedoch aktiviert, sobald der Benutzer es durch Klicken auf den Client- oder Nicht-Clientbereich aktiviert. In diesem Fall gilt Folgendes:

  • Das Fenster wird aktiviert.

  • Das Activated-Ereignis des Fensters wird ausgelöst.

  • Das zuvor aktivierte Fenster wird deaktiviert.

  • Die Ereignisse Deactivated und Activated des Fensters werden anschließend als Reaktion auf Benutzeraktionen wie erwartet ausgelöst.

Aktivieren von Fenstern

Wenn ein Fenster zum ersten Mal geöffnet wird, wird es zum aktiven Fenster (es sei denn, ShowActivated ist auf false festgelegt). Das aktive Fenster ist das Fenster, das gegenwärtig Benutzereingaben annimmt, z. B. Tastenanschläge und Mausklicks. Wird ein Fenster aktiv, löst es das Activated-Ereignis aus.

HinweisHinweis

Beim ersten Öffnen eines Fensters, werden das Loaded-Ereignis und das ContentRendered-Ereignis erst ausgelöst, nachdem das Activated-Ereignis ausgelöst wurde.Vor diesem Hintergrund gilt ein Fenster als tatsächlich geöffnet, nachdem ContentRendered ausgelöst wurde.

Nachdem ein Fenster aktiv geworden ist, kann ein Benutzer ein weiteres Fenster in derselben Anwendung oder eine andere Anwendung aktivieren. In diesem Fall wird das derzeit aktive Fenster deaktiviert, und es löst das Deactivated-Ereignis aus. Wenn der Benutzer ein derzeit deaktiviertes Fenster auswählt, wird das Fenster entsprechend neu aktiviert, und Activated wird ausgelöst.

Ein häufiger Grund für das Behandeln von Activated und Deactivated ist das Aktivieren und Deaktivieren der Funktionalität, die nur bei einem aktiven Fenster ausgeführt werden kann. In einigen Fenstern wird beispielsweise interaktiver Inhalt angezeigt, der andauernde Benutzereingaben oder Aufmerksamkeit erfordert, wie beispielsweise Spiele und Videoplayer. Im folgenden Beispiel wird durch einen vereinfachten Videoplayer veranschaulicht, wie Activated und Deactivated behandelt wird, um dieses Verhalten zu implementieren.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.CustomMediaPlayerWindow"
    Activated="window_Activated"
    Deactivated="window_Deactivated">

    <!-- Media Player -->
    <MediaElement 
      Name="mediaElement" 
      Stretch="Fill" 
      LoadedBehavior="Manual" 
      Source="numbers.wmv" />

</Window>

Imports System ' EventArgs
Imports System.Windows ' Window

Namespace SDKSample
    Partial Public Class CustomMediaPlayerWindow
        Inherits Window
        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub window_Activated(ByVal sender As Object, ByVal e As EventArgs)
            ' Recommence playing media if window is activated
            Me.mediaElement.Play()
        End Sub

        Private Sub window_Deactivated(ByVal sender As Object, ByVal e As EventArgs)
            ' Pause playing if media is being played and window is deactivated
            Me.mediaElement.Pause()
        End Sub
    End Class
End Namespace
using System; // EventArgs
using System.Windows; // Window

namespace SDKSample
{
    public partial class CustomMediaPlayerWindow : Window
    {
        public CustomMediaPlayerWindow()
        {
            InitializeComponent();
        }

        void window_Activated(object sender, EventArgs e)
        {
            // Recommence playing media if window is activated
            this.mediaElement.Play();
        }

        void window_Deactivated(object sender, EventArgs e)
        {
            // Pause playing if media is being played and window is deactivated
            this.mediaElement.Pause();
        }
    }
}

Andere Anwendungstypen führen im Hintergrund möglicherweise weiterhin Code aus, nachdem ein Fenster deaktiviert wurde. Ein E-Mail-Client kann z. B. weiterhin den E-Mail-Server abrufen, während der Benutzer andere Anwendungen verwendet. Während das Hauptfenster deaktiviert ist, stellen derartige Anwendungen häufig zusätzliches oder anderes Verhalten zur Verfügung. Im Hinblick auf das E-Mail-Programm kann das sowohl das Hinzufügen des neuen E-Mail-Elements zum Posteingang als auch eines Benachrichtigungssymbol in die Taskleiste bedeuten. Ein Benachrichtigungssymbol muss nur angezeigt werden, wenn das E-Mail-Fenster nicht aktiv ist. Dies lässt sich durch Überprüfen der IsActive-Eigenschaft feststellen.

Nach Ausführen einer Hintergrundtask benachrichtigt ein Fenster den Benutzer etwas dringlicher, indem die Activate-Methode aufgerufen wird. Wenn der Benutzer mit einer anderen Anwendung interagiert, die durch Aufrufen von Activate gestartet wird, blinkt die Taskleistenschaltfläche des Fensters. Interagiert der Benutzer mit der aktuellen Anwendung, wird das Fenster durch Aufrufen von Activate in den Vordergrund gestellt.

HinweisHinweis

Sie können die Aktivierung für den Anwendungsbereich durch Verwenden des Application.Activated-Ereignisses und des Application.Deactivated-Ereignisses behandeln.

Schließen eines Fensters

Die Lebensdauer eines Fensters endet, wenn der Benutzer das Fenster schließt. Ein Fenster kann mithilfe der Elemente im Nicht-Clientbereich geschlossen werden, z. B. mit den folgenden:

  • Das Element Schließen im Menü System.

  • Drücken von ALT+F4.

  • Klicken auf die Schaltfläche Schließen.

Zum Schließen eines Fensters können Sie dem Clientbereich weitere Mechanismen hinzufügen. Zu den gebräuchlichsten zählen:

  • Das Element Beenden im Menü Datei, i. d. R. für Hauptanwendungsfenster.

  • Das Element Schließen im Menü Datei, i. d. R. in einem sekundären Anwendungsfenster.

  • Das Element Abbrechen, i. d. R. in einem modalen Dialogfeld.

  • Das Element Schließen, i. d. R. in einem nicht modalen Dialogfeld.

Sie müssen die Close-Methode aufrufen, um ein Fenster mit einem der benutzerdefinierten Mechanismen zu schließen. Im folgenden Beispiel wird die Fähigkeit implementiert, ein Fenster mithilfe von Beenden im Menü Datei zu schließen.

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

  <Menu>
    <MenuItem Header="_File">
      <MenuItem Header="E_xit" Click="fileExitMenuItem_Click" />
    </MenuItem>
  </Menu>

</Window>

Imports System.Windows ' window, RoutedEventArgs

Namespace SDKSample
    Partial Public Class WindowWithFileExit
        Inherits System.Windows.Window
        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub fileExitMenuItem_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            ' Close this window
            Me.Close()
        End Sub
    End Class
End Namespace
using System.Windows; // window, RoutedEventArgs

namespace SDKSample
{
    public partial class WindowWithFileExit : System.Windows.Window
    {
        public WindowWithFileExit()
        {
            InitializeComponent();
        }

        void fileExitMenuItem_Click(object sender, RoutedEventArgs e)
        {
            // Close this window
            this.Close();
        }
    }
}

Wenn ein Fenster geschlossen wird, löst es zwei Ereignisse aus: Closing und Closed.

Closing wird ausgelöst, bevor das Fenster geschlossen wird. Zusätzlich werden Mechanismen bereitgestellt, mit deren Hilfe das Schließen des Fensters verhindert werden kann. Der häufigste Grund, um das Schließen eines Fensters zu verhindern, liegt darin, dass Fensterinhalt geänderte Daten enthält. In diesem Fall kann das Closing-Ereignis behandelt werden, um festzustellen, ob Daten geändert wurden und um in diesem Fall den Benutzer zu fragen, ob er mit dem Schließen des Fensters fortfahren oder den Vorgang abbrechen möchte. Im folgenden Beispiel werden die wichtigsten Aspekte bei der Behandlung von Closing verdeutlicht.


Imports System ' EventArgs
Imports System.ComponentModel ' CancelEventArgs
Imports System.Windows ' window

Namespace VisualBasic
    Partial Public Class DataWindow
        Inherits Window
        ' Is data dirty
        Private isDataDirty As Boolean = False


...


        Private Sub DataWindow_Closing(ByVal sender As Object, ByVal e As CancelEventArgs)
            MessageBox.Show("Closing called")

            ' If data is dirty, notify user and ask for a response
            If Me.isDataDirty Then
                Dim msg As String = "Data is dirty. Close without saving?"
                Dim result As MessageBoxResult = MessageBox.Show(msg, "Data App", MessageBoxButton.YesNo, MessageBoxImage.Warning)
                If result = MessageBoxResult.No Then
                    ' If user doesn't want to close, cancel closure
                    e.Cancel = True
                End If
            End If
        End Sub
    End Class
End Namespace
using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // window

namespace CSharp
{
    public partial class DataWindow : Window
    {
        // Is data dirty
        bool isDataDirty = false;


...


        void DataWindow_Closing(object sender, CancelEventArgs e)
        {
            MessageBox.Show("Closing called");

            // If data is dirty, notify user and ask for a response
            if (this.isDataDirty)
            {
                string msg = "Data is dirty. Close without saving?";
                MessageBoxResult result = 
                  MessageBox.Show(
                    msg, 
                    "Data App", 
                    MessageBoxButton.YesNo, 
                    MessageBoxImage.Warning);
                if (result == MessageBoxResult.No)
                {
                    // If user doesn't want to close, cancel closure
                    e.Cancel = true;
                }
            }
        }
    }
}

Der Closing-Ereignishandler wird an CancelEventArgs übergeben, das die Boolean Cancel-Eigenschaft implementiert, die Sie auf true festlegen, um das Schließen eines Fensters zu verhindern.

Wenn Closing nicht behandelt bzw. behandelt, aber nicht abgebrochen wird, wird das Fenster geschlossen. Unmittelbar vor dem eigentlichen Schließen des Fensters wird Closed ausgelöst. An dieser Stelle kann das Schließen des Fensters nicht verhindert werden.

HinweisHinweis

Eine Anwendung kann so konfiguriert werden, dass sie automatisch beendet wird, wenn entweder das Hauptanwendungsfenster (siehe MainWindow) oder das letzte Fenster geschlossen wird.Ausführliche Informationen finden Sie unter ShutdownMode.

Während ein Fenster über die im Nicht-Clientbereich und im Clientbereich bereitgestellten Mechanismen explizit geschlossen werden kann, ist es auch möglich, dass es infolge des Verhaltens in anderen Bereichen der Anwendung oder Windows implizit geschlossen wird, z. B.:

  • Ein Benutzer meldet sich ab oder schließt Windows.

  • Der Besitzer eines Fensters schließt (siehe Owner).

  • Das Hauptanwendungsfenster wird geschlossen, und ShutdownMode ist OnMainWindowClose.

  • Shutdown wird aufgerufen.

HinweisHinweis

Ein Fenster kann nicht erneut geöffnet werden, nachdem es geschlossen wurde.

Ereignisse in der Lebensdauer eines Fensters

In der folgenden Darstellung wird die Abfolge der wichtigsten Ereignisse in der Lebensdauer eines Fensters gezeigt.

Fensterlebensdauer

In der folgenden Abbildung wird die Abfolge der wichtigsten Ereignisse in der Lebensdauer eines Fensters, das ohne Aktivierung angezeigt wird, dargestellt (ShowActivated ist auf false festgelegt, bevor das Fenster angezeigt wird).

Fensterlebensdauer (Window.ShowActivated = False)

Fensterposition

Solange ein Fenster geöffnet ist, befindet sich dessen Position in der x- und y-Dimension relativ zum Desktop. Diese Position kann durch Überprüfen der Left-Eigenschaft und der Top-Eigenschaft festgestellt werden. Sie können diese Eigenschaften festlegen, um die Position des Fensters zu ändern.

Sie können auch die ursprüngliche Position von Window angeben, wenn es zum ersten Mal angezeigt wird. Dazu legen Sie die WindowStartupLocation-Eigenschaft auf einen der folgenden WindowStartupLocation-Enumerationswerte fest:

Wird die Startposition als Manual angegeben und wurden die Left-Eigenschaft und die Top-Eigenschaft nicht festgelegt, fragt Window Windows nach einer Position, an der es angezeigt werden soll.

Oberstes Fenster und Z-Reihenfolge

Neben der X- und Y-Position verfügt das Fenster auch über eine Position in der Z-Dimension, die dessen vertikale Position im Verhältnis zu anderen Fenstern bestimmt. Dies wird als Z-Reihenfolge des Fensters bezeichnet. Davon gibt es zwei Typen: die normale Z-Reihenfolge und die oberste Z-Reihenfolge. Die Position eines Fensters in der normalen Z-Reihenfolge hängt davon ab, ob das Fenster derzeit aktiv ist. Standardmäßig befindet sich ein Fenster in der normalen Z-Reihenfolge. Die Position eines Fensters in der obersten Z-Reihenfolge hängt ebenfalls davon ab, ob das Fenster derzeit aktiv ist. Darüber hinaus befinden sich Fenster in der obersten Z-Reihenfolge stets über den Fenstern in der normalen Z-Reihenfolge. Ein Fenster wird in der oberste Z-Reihenfolge platziert, indem dessen Topmost-Eigenschaft auf true festgelegt wird.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    Topmost="True">


...


</Window>

Innerhalb jeder Z-Reihenfolge wird das aktuell aktive Fenster über allen anderen Fenstern derselben Z-Reihenfolge angezeigt.

Fenstergröße

Abgesehen von der Position auf dem Desktop verfügt ein Fenster über eine Größe, die durch mehrere Eigenschaften bestimmt wird, beispielsweise die Eigenschaften für Breite, Höhe und SizeToContent.

MinWidth, Width und MaxWidth werden zum Verwalten des Bereichs von Breiten verwendet, die ein Fenster während seiner Lebensdauer haben kann. Sie werden wie im folgenden Beispiel gezeigt konfiguriert.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    MinWidth="300" Width="400" MaxWidth="500">


...


</Window>

Die Fensterhöhe wird von MinHeight, Height und MaxHeight verwaltet und wie im folgenden Beispiel konfiguriert.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    MinHeight="300" Height="400" MaxHeight="500">


...


</Window>

Da die verschiedenen Werte für die Breite und für die Höhe jeweils einen Bereich angeben, kann die Breite und Höhe eines in der Größe veränderbaren Fensters irgendwo innerhalb des angegebenen Bereichs für die entsprechende Dimension liegen. Wenn Sie die aktuelle Breite und Höhe des Fensters ermitteln möchten, überprüfen Sie ActualWidth bzw. ActualHeight.

Wenn Sie möchten, dass die Breite und Höhe des Fensters der Größe des Fensterinhalts entspricht, können Sie die SizeToContent-Eigenschaft verwenden, die über folgende Werte verfügt:

  • Manual. Keine Auswirkung (Standard).

  • Width. Das Anpassen an die Breite des Inhalts hat dieselbe Auswirkung wie das Festlegen sowohl von MinWidth als auch von MaxWidth auf die Breite des Inhalts.

  • Height. Das Anpassen an die Höhe des Inhalts hat dieselbe Auswirkung wie das Festlegen sowohl von MinHeight als auch von MaxHeight auf die Höhe des Inhalts.

  • WidthAndHeight. Das Anpassen an die Breite und Höhe des Inhalts hat dieselbe Auswirkung wie das Festlegen sowohl von MinHeight als auch von MaxHeight auf die Höhe des Inhalts sowie das Festlegen sowohl von MinWidth als auch von MaxWidth auf die Breite des Inhalts.

Im folgenden Code wird ein Fenster gezeigt, dessen Größe sich beim ersten Anzeigen sowohl vertikal als auch horizontal automatisch an den Inhalt anpasst.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    SizeToContent="WidthAndHeight">


...


</Window>

Rangfolge der Größeneigenschaften

Im Wesentlichen werden die verschiedenen Größeneigenschaften eines Fensters kombiniert, um den Bereich der Breite und der Höhe für ein in der Größe veränderbares Fenster zu definieren. Um sicherzustellen, dass ein gültiger Bereich beibehalten wird, wertet Window die Werte der Größeneigenschaften anhand der folgenden Rangfolgen aus.

Für Höheneigenschaften:

  1. FrameworkElement.MinHeight >

  2. FrameworkElement.MaxHeight >

  3. SizeToContent.Height/SizeToContent.WidthAndHeight >

  4. FrameworkElement.Height

Für Breiteneigenschaften:

  1. FrameworkElement.MinWidth >

  2. FrameworkElement.MaxWidth >

  3. SizeToContent.Width/SizeToContent.WidthAndHeight >

  4. FrameworkElement.Width

Durch die Rangfolge kann beim Maximieren eines Fensters auch dessen Größe festgelegt werden. Dies wird von der WindowState-Eigenschaft verwaltet.

Fensterzustand

Während der Lebensdauer eines in der Größe veränderbaren Fenster kann dieses über drei Zustände verfügen: normal, minimiert und maximiert. Ein Fenster mit einem normalen Zustand ist der Standardzustand eines Fensters. Ein Benutzer kann ein Fenster mit diesem Zustand verschieben und dessen Größe ändern, indem er den Ziehpunkt zur Größenänderung oder den Rahmen verwendet, sofern er in der Größe veränderbar ist.

Ein Fenster mit einem minimierten Zustand wird auf seine Taskleistenschaltfläche reduziert, wenn ShowInTaskbar auf true festgelegt ist. Andernfalls wird es auf die kleinste mögliche Größe reduziert und in der linken unteren Ecke des Desktops angezeigt. Keiner der minimierten Fenstertypen kann mithilfe des Ziehpunkts zur Größenreduzierung oder mit dem Rahmen in der Größe verändert werden. Allerdings kann ein minimiertes Fenster, das nicht in der Taskleiste angezeigt wird, auf dem Desktop hin und her verschoben werden.

Ein Fenster mit einem maximierten Zustand wird auf die maximal mögliche Größe erweitert, die von den Eigenschaften MaxWidth, MaxHeight und SizeToContent abhängen. Wie ein minimiertes Fenster kann auch ein maximiertes Fenster nicht mithilfe des Ziehpunkts zur Größenänderung oder durch Ziehen des Rahmens in seiner Größe verändert werden.

HinweisHinweis

Die Werte der Eigenschaften Top, Left, Width und Height eines Fensters stellen immer die Werte für den normalen Zustand dar, auch wenn das Fenster gerade maximiert oder minimiert wird.

Der Zustand eines Fensters kann durch Festlegen der WindowState-Eigenschaft konfiguriert werden, die einen der folgenden WindowState-Enumerationswerte aufweisen kann:

Im folgenden Beispiel wird veranschaulicht, wie Sie ein Fenster erstellen, das beim Öffnen als maximiert angezeigt wird.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    WindowState="Maximized">


...


</Window>

Im Allgemeinen sollten Sie WindowState so festlegen, dass der Ausgangszustand eines Fensters konfiguriert wird. Wenn ein in der Größe veränderbares Fenster angezeigt wird, können die Benutzer die Schaltflächen zum Minimieren, Maximieren oder Wiederherstellen auf der Titelleiste des Fensters aktivieren, um den Fensterzustand zu ändern.

Fensterdarstellung

Sie ändern die Darstellung des Clientbereichs eines Fensters, indem Sie fensterspezifischen Inhalt hinzufügen, z. B. Schaltflächen, Bezeichnungen und Textfelder. Zum Konfigurieren des Nicht-Clientbereichs stellt Window mehrere Eigenschaften bereit, darunter Icon, um das Symbol eines Fensters festzulegen und Title, um den Fenstertitel festzulegen.

Außerdem können Sie die Darstellung und das Verhalten des Rahmens im Nicht-Clientbereich ändern, indem Sie den Größenänderungsmodus, den Fensterstil und die Tatsache konfigurieren, ob es als Schaltfläche in der Desktoptaskleiste angezeigt wird.

Dieser Abschnitt enthält folgende Unterabschnitte.

  • Größenänderungsmodus
  • Fensterstil
  • Vorhandensein der Taskleiste

Größenänderungsmodus

Abhängig von der WindowStyle-Eigenschaft können Sie steuern, wie (und ob) Benutzer die Größe des Fensters ändern können. Die Auswahl des Fensterstils bestimmt, ob ein Benutzer die Fenstergröße durch Ziehen des Rahmens mit der Maus ändern kann, ob die Schaltflächen Minimieren, Maximieren und Größe ändern im Nicht-Clientbereich angezeigt werden und ob sie aktiviert sind, falls sie angezeigt werden.

Sie können die Größenänderung eines Fensters konfigurieren, indem Sie die ResizeMode-Eigenschaft festlegen, die einen der folgenden ResizeMode-Enumerationswerte aufweisen kann:

Wie bei WindowStyle ändert sich der Größenänderungsmodus eines Fensters während der Lebensdauer kaum. Folglich werden Sie diesen wahrscheinlich über das XAML-Markup festlegen.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ResizeMode="CanResizeWithGrip">


...


</Window>

Beachten Sie, dass Sie durch Überprüfen der WindowState-Eigenschaft ermitteln können, ob ein Fenster minimiert, maximiert oder wiederhergestellt ist.

Fensterstil

Der Rahmen, der vom Nicht-Clientbereich eines Fensters verfügbar gemacht wird, eignet sich für die meisten Anwendungen. Unter bestimmten Umständen werden je nach Fenstertyp dennoch andere Rahmentypen oder überhaupt keine Rahmen benötigt.

Um den Rahmentyp eines Fensters zu steuern, legen Sie die WindowStyle-Eigenschaft mit einem der folgenden WindowStyle-Enumerationswerte fest:

Die Auswirkung dieser Fensterstile wird in der folgenden Abbildung veranschaulicht.

Fensterstile

Sie können WindowStyle entweder mit XAML-Markup oder Code festlegen. Da es unwahrscheinlich ist, dass der Stil während der Lebensdauer eines Fensters geändert wird, werden Sie ihn wahrscheinlich mit dem XAML-Markup konfigurieren.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    WindowStyle="ToolWindow">


...


</Window>

Nicht rechteckiger Fensterstil

Es kann auch vorkommen, dass Ihnen die von WindowStyle bereitgestellten Rahmenstile nicht ausreichen. Sie möchten z. B. eine Anwendung mit einem nicht rechteckigen Rahmen erstellen, wie er von Microsoft Windows Media Player verwendet wird.

Betrachten Sie beispielsweise das Sprechblasenfenster in der folgenden Abbildung.

Nicht rechteckiges Fenster

Dieser Fenstertyp kann erstellt werden, indem die WindowStyle-Eigenschaft auf None festgelegt und die Unterstützung genutzt wird, die Window zur Transparenz bietet.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    WindowStyle="None"
    AllowsTransparency="True"
    Background="Transparent">


...


</Window>

Durch diese Kombination von Werten wird das Fenster angewiesen, ein vollkommen transparentes Rendering zu übernehmen. In diesem Zustand können die Zusatzelemente des Nicht-Clientbereichs des Fensters (das Menü Schließen, die Schaltflächen Minimieren, Maximieren und Wiederherstellen usw.) nicht verwendet werden. Folglich müssen Sie Ihre eigenen bereitstellen.

Vorhandensein der Taskleiste

Die Standarddarstellung eines Fensters umfasst eine Taskleistenschaltfläche wie in der folgenden Abbildung.

Fenster mit einer Taskleistenschaltfläche

Einige Fenstertypen verfügen über keine Taskleistenschaltfläche, z. B. Meldungsfelder und Dialogfelder (siehe Übersicht über Dialogfelder). Sie können steuern, ob die Taskleistenschaltfläche für ein Fenster angezeigt wird, indem Sie die ShowInTaskbar-Eigenschaft festlegen (standardmäßig true).

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ShowInTaskbar="False">


...


</Window>

Sicherheitsüberlegungen

Window benötigt die UnmanagedCode-Sicherheitsberechtigung, um instanziiert zu werden. Bei Anwendungen, die auf dem lokalen Computer installiert und gestartet werden, wird dies durch die Berechtigungen abgedeckt, die der Anwendung gewährt werden.

Allerdings gilt dies nicht für Berechtigungen, die Anwendungen gewährt wurden, die mit ClickOnce über das Internet oder die lokale Intranetzone gestartet werden. Infolgedessen erhalten Benutzer eine ClickOnce-Sicherheitswarnung. Außerdem müssen sie den Berechtigungssatz für die Anwendung auf volle Vertrauenswürdigkeit erhöhen.

Darüber hinaus kann XBAPs standardmäßig keine Fenster oder Dialogfelder anzeigen. Eine Erörterung von Sicherheitsüberlegungen für eigenständige Anwendungen finden Sie unter WPF-Sicherheitsstrategie – Plattformsicherheit.

Andere Fenstertypen

NavigationWindow ist ein Fenster, das zum Hosten von navigierbarem Inhalt konzipiert ist. Weitere Informationen finden Sie unter Übersicht über die Navigation.

Dialogfelder sind Fenster, die häufig zum Erfassen von Benutzerinformationen verwendet werden, um eine Funktion ausführen. Wenn ein Benutzer beispielsweise eine Datei öffnen möchte, wird normalerweise das Dialogfeld Datei öffnen von einer Anwendung angezeigt, um den Dateinamen vom Benutzer zu erhalten. Weitere Informationen finden Sie unter Übersicht über Dialogfelder.

Siehe auch

Referenz

Window

MessageBox

NavigationWindow

Application

Konzepte

Übersicht über Dialogfelder

Erstellen einer WPF-Anwendung (WPF)