Share via


Übersicht über WPF-Fenster

Benutzer interagieren mit eigenständigen Windows Presentation Foundation (WPF)-Anwendungen über Fenster. 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 ihre eigenen Fenster mithilfe der Window-Klasse zur Verfügung. In diesem Thema wird Window vorgestellt, bevor die Grundlagen der Erstellung und Verwaltung von Fenstern in eigenständigen Anwendungen behandelt werden.

Hinweis

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

Die Fensterklasse

In der folgenden Abbildung werden die Bestandteile eines Fensters dargestellt:

Screenshot that shows window elements.

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 sowohl die Darstellung als auch das Verhalten, in denen die Darstellung definiert wird, wie ein Fenster einem Benutzer angezeigt wird und das Verhalten die Funktionsweise eines Fensters bei der Interaktion mit Benutzern definiert. 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="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.MarkupAndCodeBehindWindow">
  
  <!-- Client area (for content) -->
  
</Window>
using System.Windows;

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

Imports System.Windows

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

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, die von einer Microsoft Build Engine (MSBuild) erstellt wird, dazu, dass eine partial-Klasse erstellt wird, 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="http://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:Classs-Attribut angegeben ist, und sie muss von Window abgeleitet werden. Auf diese Weise kann die CodeBehind-Datei mit der partial-Klasse verknüpft werden, die beim Erstellen der Anwendung (siehe Erstellen einer WPF-Anwendung) 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.

Hinweis

Wenn Sie Ihrem Projekt ein neues Window mithilfe von 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 im XAML-Markup implementiert wurde, sowie ein Ereignishandler für das Click-Ereignis der Schaltfläche, der in Code-Behind implementiert wurde.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.MarkupAndCodeBehindWindow">
  <!-- Client area (for content) -->
  <Button Click="button_Click">Click This Button</Button>
</Window>
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.");
        }
    }
}

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

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-Markupdateien 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="http://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.

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.

Ö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="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App"
    Startup="app_Startup">
</Application>
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 ein Verweis darauf automatisch zu einer Liste von Fenstern hinzugefügt, die vom Application-Objekt verwaltet wird (siehe Application.Windows). Das erste zu instanziierte Fenster wird zusätzlich automatisch von Application als Hauptanwendungsfenster festgelegt (siehe Application.MainWindow).

Das Fenster wird schließlich durch den Aufruf der Show-Methode geöffnet, wie im folgenden Bild gezeigt.

A Window Opened by calling Window.Show

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

Hinweis

ShowDialog wird aufgerufen, um Fenster so wie modale Dialogfelder zu öffnen. 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 hervorgerufen und das Fenster wird angezeigt.

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

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

Beim Öffnen der App wird das durch den Wert von StartupUri angegebene Fenster modelllos geöffnet, intern wird das Fenster durch Aufruf seiner Show-Methode aufgerufen.

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:

  • Decken Sie das andere (es sei denn, die Topmost-Eigenschaft eines der Fenster ist auf true eingestellt).

  • 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 integrierte Entwicklungsumgebung (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 dieOwner-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
Window ownedWindow = new Window();
ownedWindow.Owner = this;
ownedWindow.Show();
' Create a window and make this window its owner
Dim ownedWindow As New Window()
ownedWindow.Owner = Me
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, so wie Konversationsfenster einer Internet-Messenger-Anwendung oder Benachrichtigungsfenster einer E-Mail-Anwendung.

Falls Ihre Anwendung ein Fenster bereitstellt, das nicht aktiviert werden soll, können Sie dessen ShowActivated-Eigenschaft auf false festelegen, 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:

  • Das Fenster wird aktiviert.

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

  • Das zuvor aktivierte Fenster wird deaktiviert.

  • Die Deactivated- und Activated-Ereignisse des Fensters werden dann wie erwartet als Reaktion auf Anwenderaktionen ausgelöst.

Aktivieren von Fenstern

Wenn ein Fenster zum ersten Mal geöffnet wird, dann wird es das aktive Fenster (außer, es wird mit ShowActivated angepasst an false festgelegt). Das aktive Fenster ist das Fenster, das gegenwärtig Benutzereingaben annimmt, z. B. Tastenanschläge und Mausklicks. Wenn ein Fenster aktiv wird, löst es das Activated-Ereignis aus.

Hinweis

Beim erstmaligen Öffnen eines Fensters werden die Loaded- und ContentRendered-Ereignisse 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 die Handhabung von Activated und Deactivated ist das Aktivieren und Deaktivieren von Funktionen, die nur bei aktivem Fenster ausgeführt werden können. In einigen Fenstern wird beispielsweise interaktiver Inhalt angezeigt, der andauernde Benutzereingaben oder Aufmerksamkeit erfordert, wie beispielsweise Spiele und Videoplayer. Das folgende Beispiel ist ein vereinfachter Videoplayer, der zeigt, wie man Activated und Deactivated behandelt, um dieses Verhalten zu implementieren.

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://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>
using System;
using System.Windows;

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

Imports System.Windows

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

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, was durch Überprüfen der IsActive-Eigenschaft bestimmt wird.

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. Wenn ein Benutzer jedoch mit der aktuellen Anwendung interagiert, wird durch Aufrufen von Activate das Fenster in den Vordergrund gestellt.

Hinweis

Sie können die Aktivierung des Anwendungsbereichs mit den Application.Activated- und Application.Deactivated-Ereignissen 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="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.WindowWithFileExit">
  
  <Menu>
    <MenuItem Header="_File">
      <MenuItem Header="E_xit" Click="fileExitMenuItem_Click" />
    </MenuItem>
  </Menu>
  
</Window>
using System.Windows;

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

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

Imports System.Windows

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

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. Das folgende Beispiel zeigt die Schlüsselaspekte der Handhabung von Closing.

using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // window

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

        public DataWindow()
        {
            InitializeComponent();
        }

        void documentTextBox_TextChanged(object sender, EventArgs e)
        {
            this.isDataDirty = true;
        }

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

        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub documentTextBox_TextChanged(ByVal sender As Object, ByVal e As EventArgs)
            Me.isDataDirty = True
        End Sub

        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

Dem Closing-Ereignishandler wird ein CancelEventArgs übergeben, der die BooleanCancel-Eigenschaft implementiert, die Sie auf true festlegen, um zu verhindern, dass ein Fenster geschlossen wird.

Wenn Closing nicht behandelt wird oder es behandelt, aber nicht beendet wird, wird das Fenster geschlossen. Kurz bevor ein Fenster tatsächlich geschlossen wird, wird Closed erhoben. An dieser Stelle kann das Schließen des Fensters nicht verhindert werden.

Hinweis

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 des Fensters implizit geschlossen wird, z. B.:

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

  • Der Besitzer eines Fensters wird geschlossen (siehe Owner).

  • Das Hauptanwendungsfenster ist geschlossen und ShutdownMode ist OnMainWindowClose .

  • Shutdown wird aufgerufen.

Hinweis

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:

Diagram that shows events in a window's lifetime.

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):

Diagram that shows events in a window's lifetime without activation.

Fensterposition

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

Sie können auch den Anfangsspeicherort eines Window wenn es zum ersten Mal auftritt, indem Sie die WindowStartupLocation-Eigenschaft mit einer der folgenden WindowStartupLocation-Enumerationwrte einstellen:

Wenn der Startspeicherort als Manual angegeben wird und die Left- und Top -Eigenschaften nicht festgelegt worden sind, fragt Window Windows nach einem Speicherort, in dem 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 oder nicht. 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 oder nicht. Darüber hinaus befinden sich Fenster in der obersten Z-Reihenfolge stets über den Fenstern in der normalen Z-Reihenfolge. Ein Fenster befindet sich in der obersten Z-Reihenfolge, indem seine Topmost-Eigenschaft auf true festgelegt wird.

<Window 
    xmlns="http://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 verwendet, um den Breitenbereich zu verwalten, den ein Fenster während seiner Lebensdauer haben kann und konfiguriert ist, wie im folgenden Beispiel gezeigt.

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

Die Höhe des Fensters wird von MinHeight, Height und MaxHeight verwaltet und wird konfiguriert, wie im folgenden Beispiel gezeigt.

<Window 
    xmlns="http://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. Um seine aktuelle Breite und Höhe zu ermitteln, prüfen Sie jeweilsActualWidth und 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. An die Breite des Inhalts anpassen, was den gleichen Effekt hat wie das Einstellen der beiden MinWidth und MaxWidth auf die Breite des Inhalts.

  • Height. An die Höhe des Inhalts anpassen, was den gleichen Effekt hat wie das Einstellen der beiden MinHeight und MaxHeight auf die Höhe des Inhalts.

  • WidthAndHeight. Passen Sie an die Breite und Höhe des Inhalts an. Dies hat den gleichen Effekt wie das Festlegen von MinHeightund MaxHeight auf die Höhe des Inhalts sowie das Festlegen von MinWidth und MaxWidth auf die Breite des Inhalts.

Im folgenden Beispiel wird ein Fenster dass die Größe automatisch an seinen Inhalt vertikal und horizontal an, wenn es zuerst angezeigt wird.

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

Im folgenden Beispiel wird gezeigt, wie die SizeToContent-Eigenschaft im Code festlegen, um anzugeben, wie ein Fenster angepasst wird, um seinen Inhalt anzupassen.


// Manually alter window height and width
this.SizeToContent = SizeToContent.Manual;

// Automatically resize width relative to content
this.SizeToContent = SizeToContent.Width;

// Automatically resize height relative to content
this.SizeToContent = SizeToContent.Height;

// Automatically resize height and width relative to content
this.SizeToContent = SizeToContent.WidthAndHeight;

' Manually alter window height and width
Me.SizeToContent = SizeToContent.Manual

' Automatically resize width relative to content
Me.SizeToContent = SizeToContent.Width

' Automatically resize height relative to content
Me.SizeToContent = SizeToContent.Height

' Automatically resize height and width relative to content
Me.SizeToContent = SizeToContent.WidthAndHeight

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, was von der WindowState-Eigenschaft verwaltet wird.

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 maximiertenZustand wird auf die maximal mögliche Größe erweitert, die nur so groß ist, wie es seineMaxWidth, MaxHeight, und SizeToContent-Eigenschaften vorgeben. 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.

Hinweis

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

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

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

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

Im Allgemeinen sollten Sie festlegen, WindowState um den Anfangszustand eines Fensters zu konfigurieren. 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. Zur Konfiguration des Nicht-Client-Bereichs Windowstehen mehrere Eigenschaften zur Verfügung, u. a. Icon zum Einstellen des Fenstersymbols Title und des Fenstertitels.

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.

Größenänderungsmodus

Abhängig von der WindowStyle-Eigenschaft können Sie steuern, ob (und wie) 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 konfigurieren, wie die Größe eines Fensters geändert wird, indem Sie dessen ResizeMode-Eigenschaft festlegen. Dies kann einer der folgenden ResizeMode Enumerationswerte sein:

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="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ResizeMode="CanResizeWithGrip">
</Window>

Beachten Sie, dass Sie erkennen können, ob ein Fenster maximiert, minimiert oder wiederhergestellt wird, indem Sie die WindowState-Eigenschaft überprüfen.

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 zu steuern, welchen Rahmentyp ein Fenster erhält, legen Sie dessen WindowStyle-Eigenschaft mit einem der folgenden Werte der -Enumeration WindowStyle fest:

Die Auswirkung dieser Fensterstile wird in der folgenden Abbildung veranschaulicht:

Illustration of window border styles.

Sie können WindowStyle entweder mit einem XAML-Markup oder einem 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="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    WindowStyle="ToolWindow">
</Window>

Nicht rechteckiger Fensterstil

Es gibt auch Situationen, in denen von WindowStyle erlaubte Rahmenstile nicht ausreichend sind. 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:

A speech bubble window that says Drag Me.

Dieser Fenstertyp kann, indem man den Parameter derWindowStyle-Eigenschaft aufNone einstellt, und durch die Verwendung einer speziellen Unterstützung, die Window für Transparenz hat.

<Window 
    xmlns="http://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:

Screenshot that shows a window with a taskbar button.

Einige Fenstertypen verfügen über keine Taskleistenschaltfläche, so wie 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, die standardmäßig festgelegt ist, einstellen (true als Standard).

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

Sicherheitsüberlegungen

WindowbenötigtUnmanagedCode die 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 mithilfe von ClickOnce über das Internet oder die lokale Intranetzone gestartet werden. Infolgedessen erhalten Benutzer eine ClickOnce-Sicherheitswarnung und müssen 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 zur Aufnahme von navigierbarem Inhalt bestimmt ist. Weitere Informationen finden Sie in der Ü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.

Weitere Informationen