Freigeben über


Übersicht über WPF-Fenster

Benutzer interagieren mit eigenständigen Windows Presentation Foundation (WPF)-Anwendungen über Fenster. Der Hauptzweck eines Fensters ist das Hosten von Inhalten, die Daten visualisieren und Benutzern die Interaktion mit Daten ermöglichen. Eigenständige WPF-Anwendungen stellen ihre eigenen Fenster mithilfe der Window Klasse bereit. In diesem Thema wird Window vorgestellt, bevor die Grundlagen der Erstellung und Verwaltung von Fenstern in eigenständigen Anwendungen behandelt werden.

Anmerkung

Ü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 Fenstern gehostet, die von Windows Internet Explorer bereitgestellt werden. Weitere Informationen finden Sie unter Übersicht über WPF-XAML-Browseranwendungen.

Die Fensterklasse

Die folgende Abbildung veranschaulicht die Bestandteile eines Fensters:

Screenshot mit Fensterelementen.

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:

  • Eine Grenze.

  • Titelleiste

  • Ein Symbol.

  • Schaltflächen zum Minimieren, Maximieren und Wiederherstellen

  • Ein 'Schließen'-Button.

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

Der Clientbereich eines Fensters ist der Bereich innerhalb des Nicht-Clientbereichs eines Fensters und wird von Entwicklern verwendet, um anwendungsspezifische Inhalte wie Menüleisten, Symbolleisten und Steuerelemente hinzuzufügen.

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

  • Anzeigen eines Fensters

  • Konfigurieren Sie die 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 das Erscheinungsbild als auch das Verhalten, wobei Darstellung definiert, wie ein Fenster für Benutzer aussieht, und Verhalten definiert, wie ein Fenster funktioniert, wenn Benutzer damit interagieren. In WPF können Sie das Erscheinungsbild und Verhalten eines Fensters mithilfe von Code oder 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 attribut x:Class 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 aufgerufen wird, um die Ereignisse zu registrieren und die Eigenschaften festzulegen, die im Markup implementiert werden.

  • Bei CodeBehind 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 sein. 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.

Anmerkung

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

Wie Sie Das Fenster implementieren, bestimmt, wie es für MSBuild konfiguriert ist. 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 angezeigt.

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

Informationen zum Erstellen von WPF-Anwendungen finden Sie unter Building a WPF Application.

Fensterlebensdauer

Wie bei jeder Klasse hat ein Fenster eine Lebensdauer, die beginnt, wenn es zum ersten Mal instanziiert wird, nach dem es geöffnet, aktiviert und deaktiviert und schließlich geschlossen wird.

Öffnen eines Fensters

Zum Öffnen eines Fensters erstellen Sie zunächst eine Instanz davon, die im folgenden Beispiel veranschaulicht wird.

<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.

Wenn ein Fenster instanziiert wird, wird automatisch ein Verweis darauf einer Liste von Fenstern hinzugefügt, die vom Application-Objekt verwaltet werden (siehe Application.Windows). Darüber hinaus wird das erste Fenster, das instanziiert wird, standardmäßig von Application als Hauptanwendungsfenster festgelegt (siehe Application.MainWindow).

Das Fenster wird schließlich geöffnet, indem die Show-Methode aufgerufen wird; das Ergebnis wird in der folgenden Abbildung dargestellt.

Ein Fenster wurde geöffnet durch das Aufrufen von Window.Show

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.

Anmerkung

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 Initialisierungsarbeiten durch, um eine Infrastruktur einzurichten, die es ermöglicht, Benutzereingaben zu empfangen, bevor es angezeigt wird. Wenn das Fenster initialisiert wird, wird das SourceInitialized-Ereignis hervorgerufen und das Fenster wird angezeigt.

Als Abkürzung kann StartupUri festgelegt werden, um das erste Fenster anzugeben, das automatisch beim Start einer Anwendung 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

Ein Fenster, das mithilfe der Show-Methode geöffnet wird, weist keine implizite Beziehung mit dem Fenster auf, das es erstellt hat; Benutzer können unabhängig vom anderen Fenster mit beiden Fenstern interagieren, was bedeutet, dass beide Fenster die folgenden Aktionen ausführen können:

  • Verdecken 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. Beispielsweise kann eine IDE-Anwendung (Integrated Development Environment) Eigenschaftsfenster und Toolfenster öffnen, deren typisches Verhalten darin besteht, das Fenster zu überdecken, in dem sie erstellt werden. 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()

Nachdem das Eigentum etabliert ist:

  • 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 Fenster nicht aktiviert werden sollten, wenn sie angezeigt werden, z. B. Unterhaltungsfenster einer Anwendung im Internet Messenger-Stil oder Benachrichtigungsfenster einer E-Mail-Anwendung.

Wenn Ihre Anwendung über ein Fenster verfügt, das bei der Anzeige nicht aktiviert werden soll, können Sie die ShowActivated Eigenschaft auf false festlegen, bevor Sie die Show Methode zum ersten Mal aufrufen. Dies hat zur Folge:

  • Das Fenster ist nicht aktiviert.

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

  • Das aktuell aktivierte Fenster bleibt aktiviert.

Das Fenster wird jedoch aktiviert, sobald der Benutzer es aktiviert, indem er entweder auf den Client- oder nicht-Client-Bereich klickt. In diesem Fall:

  • Das Fenster wird aktiviert.

  • Das Activated-Ereignis des Fensters wird 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 derzeit Benutzereingaben erfasst, z. B. Tastenanschläge und Mausklicks. Wenn ein Fenster aktiv wird, löst es das Activated-Ereignis aus.

Anmerkung

Wenn ein Fenster zum ersten Mal geöffnet wird, werden die ereignisse Loaded und ContentRendered erst ausgelöst, nachdem das ereignis Activated ausgelöst wurde. Vor diesem Hintergrund gilt ein Fenster als tatsächlich geöffnet, nachdem ContentRendered ausgelöst wurde.

Nachdem ein Fenster aktiv wurde, kann ein Benutzer ein anderes Fenster in derselben Anwendung aktivieren 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 Behandlung von Activated und Deactivated ist das Aktivieren und Deaktivieren von Funktionen, die nur ausgeführt werden können, wenn ein Fenster aktiv ist. Beispielsweise zeigen einige Fenster interaktive Inhalte an, die eine konstante Benutzereingabe oder -aufmerksamkeit erfordern, einschließlich Spielen und Videoplayern. 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 können weiterhin Code im Hintergrund ausführen, wenn ein Fenster deaktiviert wird. Beispielsweise kann ein E-Mail-Client weiterhin den E-Mail-Server abfragen, während der Benutzer andere Anwendungen verwendet. Anwendungen wie diese bieten häufig ein anderes oder zusätzliches Verhalten, während das Hauptfenster deaktiviert wird. Im Hinblick auf das E-Mail-Programm kann dies sowohl das Hinzufügen des neuen E-Mail-Elements zum Posteingang als auch das Hinzufügen eines Benachrichtigungssymbols zur Taskleiste bedeuten. Ein Benachrichtigungssymbol muss nur angezeigt werden, wenn das E-Mail-Fenster nicht aktiv ist. Dies kann durch das Prüfen der IsActive-Eigenschaft bestimmt werden.

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 aktiviert wird, wenn Activate aufgerufen wird, blinkt die Taskleistenschaltfläche des Fensters. Wenn ein Benutzer mit der aktuellen Anwendung interagiert, wird durch das Aufrufen von Activate das Fenster in den Vordergrund gebracht.

Anmerkung

Sie können die Aktivierung des Anwendungsbereichs mit den Application.Activated- und Application.Deactivated-Ereignissen behandeln.

Schließen eines Fensters

Die Lebensdauer eines Fensters beginnt am Ende, wenn ein Benutzer es 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.

Sie können dem Clientbereich zusätzliche Mechanismen bereitstellen, um ein Fenster zu schließen, von denen die häufigeren Folgendes umfassen:

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

Um ein Fenster als Reaktion auf einen dieser benutzerdefinierten Mechanismen zu schließen, müssen Sie die Close-Methode aufrufen. 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 vor dem Schließen des Fensters ausgelöst und bietet einen Mechanismus, mit dem das Schließen des Fensters verhindert werden kann. Ein häufiger Grund zum Verhindern des Schließens von Fenstern ist, wenn Der Fensterinhalt geänderte Daten enthält. In diesem Fall kann das Closing-Ereignis behandelt werden, um zu bestimmen, ob Daten schmutzig sind, und wenn ja, den Benutzer zu fragen, ob das Schließen des Fensters fortgesetzt werden soll, ohne die Daten zu speichern oder das Schließen des Fensters abzubrechen. 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 diesem Punkt kann das Schließen eines Fensters nicht verhindert werden.

Anmerkung

Eine Anwendung kann so konfiguriert werden, dass sie automatisch heruntergefahren wird, wenn entweder das Hauptanwendungsfenster geschlossen wird (siehe MainWindow) oder das letzte Fenster geschlossen wird. Weitere 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 beendet Windows.

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

  • Das Hauptanwendungsfenster ist geschlossen und ShutdownMode ist OnMainWindowClose.

  • Shutdown wird aufgerufen.

Anmerkung

Ein Fenster kann nach dem Schließen nicht erneut geöffnet werden.

Ereignisse in der Lebensdauer eines Fensters

Die folgende Abbildung zeigt die Abfolge der Prinzipalereignisse in der Lebensdauer eines Fensters:

Diagramm, das Ereignisse in der Lebensdauer eines Fensters anzeigt.

Die folgende Abbildung zeigt die Abfolge der Prinzipalereignisse in der Lebensdauer eines Fensters, das ohne Aktivierung angezeigt wird (ShowActivated wird auf false festgelegt, bevor das Fenster angezeigt wird):

Diagramm, das Ereignisse in der Lebensdauer eines Fensters ohne Aktivierung anzeigt.

Fensterposition

Während ein Fenster geöffnet ist, hat es eine Position in den x- und y-Dimensionen 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 einer x- und y-Position verfügt ein Fenster auch über eine Position in der Z-Dimension, die seine vertikale Position in Bezug auf andere Fenster bestimmt. Dies wird als Z-Reihenfolge des Fensters bezeichnet, und es gibt zwei Typen: normale Z-Reihenfolge und 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 wird auch dadurch bestimmt, ob es aktuell aktiv ist oder nicht. Darüber hinaus befinden sich Fenster in der obersten Z-Reihenfolge immer über 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 oberhalb aller anderen Fenster in 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, Widthund MaxWidth werden verwendet, um den Bereich der Breiten zu verwalten, die ein Fenster während seiner Lebensdauer haben kann, und werden wie im folgenden Beispiel dargestellt konfiguriert.

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

Die Fensterhöhe wird von MinHeight, Heightund MaxHeightverwaltet und wie im folgenden Beispiel dargestellt konfiguriert.

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

Da die verschiedenen Breitenwerte und Höhenwerte jeweils einen Bereich angeben, ist es möglich, dass die Breite und Höhe eines größenveränderbaren Fensters an einer beliebigen Stelle innerhalb des angegebenen Bereichs für die jeweilige Dimension liegen kann. Um seine aktuelle Breite und Höhe zu ermitteln, prüfen Sie jeweils ActualWidth und ActualHeight.

Wenn die Breite und Höhe des Fensters eine Größe aufweisen sollen, die zur Größe des Fensterinhalts passt, können Sie die Eigenschaft SizeToContent verwenden, die die folgenden Werte aufweist:

  • Manual. Kein Effekt (Standard).

  • Width. An die Inhaltsbreite anpassen, was denselben Effekt hat wie das Festlegen von 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>

Das folgende Beispiel zeigt, wie die SizeToContent-Eigenschaft im Code festgelegt wird, um anzugeben, wie die Größe eines Fensters an den Inhalt angepasst wird.


// 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 Höhe für ein verkleinerbares Fenster zu definieren. Um sicherzustellen, dass ein gültiger Bereich beibehalten wird, wertet Window die Werte der Größeneigenschaften mithilfe 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 anpassbaren Fensters kann es sich in drei Zuständen befinden: 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.

Anmerkung

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

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

Das folgende Beispiel zeigt, 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 WindowState festlegen, um den Anfangszustand eines Fensters zu konfigurieren. Sobald ein verkleinerbares Fenster angezeigt wird, können Benutzer die Schaltflächen "Minimieren", "Maximieren" und "Wiederherstellen" auf der Titelleiste des Fensters drücken, um den Fensterzustand zu ändern.

Fensterdarstellung

Sie ändern die Darstellung des Clientbereichs eines Fensters, indem Sie ihr fensterspezifische Inhalte hinzufügen, z. B. Schaltflächen, Beschriftungen und Textfelder. Um den Nicht-Clientbereich zu konfigurieren, stellt Window mehrere Eigenschaften bereit, die Icon enthalten, um das Symbol eines Fensters festzulegen, und Title, um den Titel festzulegen.

Sie können auch das Erscheinungsbild und das Verhalten des Rahmens eines Nicht-Client-Bereichs ändern, indem Sie den Größenänderungsmodus, den Fensterstil und ob es als Schaltfläche in der Desktop-Taskleiste erscheint, konfigurieren.

Größenänderungsmodus

Je nach WindowStyle Eigenschaft können Sie steuern, wie (und ob) Benutzer die Größe des Fensters ändern können. Die Wahl des Fensterstils beeinflusst, ob ein Benutzer die Fenstergröße ändern kann, indem er den Rahmen mit der Maus zieht, ob die Schaltflächen Minimize, Maximizeund Resize im Nicht-Client-Bereich angezeigt werden und, falls sie angezeigt werden, ob sie aktiviert sind.

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 WindowStyleist es unwahrscheinlich, dass sich der Größenänderungsmodus eines Fensters während seiner Lebensdauer ändert. Dies bedeutet, dass Sie es wahrscheinlich aus XAML-Markup festlegen werden.

<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 eigenschaft WindowState überprüfen.

Fensterstil

Der Rahmen, der vom Nicht-Clientbereich eines Fensters verfügbar gemacht wird, eignet sich für die meisten Anwendungen. Es gibt jedoch Situationen, in denen unterschiedliche Rahmentypen erforderlich sind oder überhaupt keine Rahmen erforderlich sind, je nach Fenstertyp.

Um zu steuern, welche Art von Rahmen ein Fenster erhält, legen Sie dessen WindowStyle-Eigenschaft mit einem der folgenden Werte der WindowStyle-Enumeration fest:

Die Wirkung dieser Fensterstile wird in der folgenden Abbildung veranschaulicht.

Abbildung von Fensterrahmenarten.

Sie können WindowStyle entweder mit XAML-Markup oder Code festlegen; da es während der Lebensdauer eines Fensters unwahrscheinlich ist, dass sich dies ändert, werden Sie es höchstwahrscheinlich mit 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 können zum Beispiel eine Anwendung mit einem nicht rechteckigen Rahmen erstellen, wie der Microsoft Windows Media Player verwendet.

Betrachten Sie beispielsweise das Sprechblasenfenster in der folgenden Abbildung:

Sprechblasenfenster mit „Drag Me“ (Ziehen)

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>

Diese Kombination von Werten weist das Fenster an, vollständig transparent zu rendern. In diesem Zustand können die Elemente des Nicht-Client-Bereichs des Fensters (wie das Menü "Schließen" sowie die Schaltflächen "Minimieren", "Maximieren" und "Wiederherstellen") nicht verwendet werden. Folglich müssen Sie Ihre eigenen bereitstellen.

Vorhandensein der Taskleiste

Die Standarddarstellung eines Fensters enthält eine Taskleistenschaltfläche, wie die in der folgenden Abbildung gezeigte:

Screenshot, der ein Fenster mit einer Taskleistenschaltfläche zeigt.

Einige Fenstertypen verfügen nicht über eine Taskleistenschaltfläche, z. B. Meldungsfelder und Dialogfelder (siehe Dialogfelderübersicht). Sie können steuern, ob die Taskleistenschaltfläche für ein Fenster angezeigt wird, indem Sie die eigenschaft ShowInTaskbar ( standardmäßigtrue) festlegen.

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

Sicherheitsüberlegungen

Window benötigtUnmanagedCode die Sicherheitsberechtigung, um instanziiert zu werden. Bei Anwendungen, die auf dem lokalen Computer installiert und gestartet werden, liegt dies in der Gruppe der Berechtigungen, 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 können XBAPs keine Fenster oder Dialogfelder standardmäßig anzeigen. Eine Diskussion zu Überlegungen zur eigenständigen Anwendungssicherheit finden Sie unter WPF-Sicherheitsstrategie – Plattformsicherheit.

Andere Windows-Typen

NavigationWindow ist ein Fenster, das zum Hosten von navigierbaren Inhalten konzipiert ist. Weitere Informationen finden Sie in der Übersicht über die Navigation).

Dialogfelder sind Fenster, die häufig verwendet werden, um Informationen von einem Benutzer zu sammeln, um eine Funktion abzuschließen. Wenn beispielsweise ein Benutzer eine Datei öffnen möchte, wird das Dialogfeld Datei öffnen in der Regel von einer Anwendung angezeigt, um den Dateinamen vom Benutzer abzurufen. Weitere Informationen finden Sie unter Übersicht über Dialogfelder.

Siehe auch