Übersicht über WPF-Fenster (WPF .NET)
Benutzer interagieren mit 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. WPF-Anwendungen stellen ihre eigenen Fenster mithilfe der -Klasse Window zur Verfügung. In diesem Artikel wird Window vorgestellt, ehe die Grundlagen zum Erstellen und Verwalten von Fenstern in Anwendungen behandelt werden.
Wichtig
In diesem Artikel wird XAML verwendet, das aus einem C#-Projekt generiert wurde. Wenn Sie Visual Basic verwenden, sieht der XAML-Code möglicherweise etwas anders aus. Diese Unterschiede sind in der Regel bei x:Class
Attributwerten vorhanden. C# enthält den Stammnamespace für das Projekt, Visual Basic nicht.
Die Projektvorlagen für C# erstellen einen App
Typ, der in der app.xaml Datei enthalten ist. In Visual Basic wird der Typ Application
und die Datei Application.xaml
benannt.
Die Fensterklasse
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
In der folgenden Abbildung werden die Bestandteile eines Fensters dargestellt:
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:
- Titelleiste (1-5).
- Symbol (1).
- Titel (2).
- Schaltflächen Minimieren (3), Maximieren (4) und Schließen (5).
- Systemmenü (6) mit Menüelementen. Wird angezeigt, wenn auf das Symbol (1) geklickt wird.
- Randbereich (7).
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.
- Clientbereich (8).
- Klammergröße ändern (9). Dies ist ein Steuerelement, das dem Clientbereich (8) hinzugefügt wurde.
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 x:Class="WindowsOverview.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WindowsOverview"
>
<!-- Client area containing the content of the window -->
</Window>
Der folgende Code ist der CodeBehind für den XAML.
using System.Windows;
namespace WindowsOverview
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
}
}
Public Class Window1
End Class
Folgende Voraussetzungen müssen erfüllt sein, damit die XAML-Markupdatei und die Code-Behind-Datei zusammenarbeiten:
Im Markup muss das
Window
-Element dasx:Class
-Attribut enthalten. Beim Erstellen der Anwendung führt das Vorhandensein vonx:Class
-Attribut die Microsoft-Build-Engine dazu, dass einepartial
-Klasse erstellt wird, die von Window abgeleitet wird und den durch dasx: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 generiertepartial
-Klasse implementiert dieInitializeComponent
-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 dasx:Class
s-Attribut angegeben ist, und sie muss von Window abgeleitet werden. Auf diese Weise kann die CodeBehind-Datei mit derpartial
-Klasse verknüpft werden, die beim Erstellen der Anwendung für weitere Informationen 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 generiertepartial
-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. Das nachfolgende Beispiel zeigt ein Fenster mit einer Schaltfläche, die einen Ereignishandler für das Click-Ereignis definiert. Dies wird im XAML-Code implementiert, und der Handler wird im CodeBehind implementiert.
<Window x:Class="WindowsOverview.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WindowsOverview"
>
<!-- Client area containing the content of the window -->
<Button Click="Button_Click">Click This Button</Button>
</Window>
Der folgende Code ist der CodeBehind für den XAML.
using System.Windows;
namespace WindowsOverview
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button was clicked.");
}
}
}
Public Class Window1
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
MessageBox.Show("Button was clicked.")
End Sub
End Class
Konfigurieren eines Fensters 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.
.NET SDK-Projekte importieren automatisch die richtigen Page
und Compile
-Elemente für Sie, und Sie müssen diese nicht deklarieren. Wenn das Projekt für WPF konfiguriert ist, werden die XAML-Markupdateien automatisch als Page
Elemente importiert, und die entsprechende CodeBehind-Datei wird als Compile
importiert.
MSBuild-Projekte importieren die Typen nicht automatisch, und Sie müssen sie selbst deklarieren:
<Project>
...
<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:
using System.Windows;
namespace WindowsOverview
{
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
// Create the window
Window1 window = new Window1();
// Open the window
window.Show();
}
}
}
Class Application
Private Sub Application_Startup(sender As Object, e As StartupEventArgs)
' Create the window
Dim window As New Window1
' Open the window
window.Show()
End Sub
End Class
In diesem Beispiel wird Window1
beim Starten der Anwendung instanziiert, was beim Auslösen des Startup-Ereignisses erfolgt. Weitere Informationen zum Startfenster finden Sie unter So erhalten oder setzen Sie das Hauptanwendungsfenster.
Wird ein Fenster instanziiert, wird ein Verweis darauf automatisch zu einer -Liste von Fenstern hinzugefügt, die vom Application-Objekt verwaltet wird. Das erste zu instanziierte Fenster wird automatisch von Application als Hauptanwendungsfensterfestgelegt.
Das Fenster wird schließlich durch den Aufruf der Show-Methode geöffnet, wie im folgenden Bild gezeigt:
Ein Fenster, das durch Aufrufen von Show geöffnet wird, ist ein modusloses Fenster, und die Anwendung verhindert nicht, dass Benutzer mit anderen Fenstern in der Anwendung interagieren. Das Öffnen eines Fensters mit ShowDialog öffnet ein Fenster als modal und schränkt die Benutzerinteraktion auf das jeweilige Fenster ein. 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.
Weitere Informationen finden Sie unter Öffnen eines Fensters oder Dialogfelds.
Startfenster
Im vorherigen Beispiel wurde das Startup
-Ereignis verwendet, um Code auszuführen, der das erste Anwendungsfenster anzeigte. Als Verknüpfung können Sie stattdessen StartupUri verwenden, um den Pfad zu einer XAML-Datei in Ihrer Anwendung anzugeben. Die Anwendung erstellt automatisch das von dieser Eigenschaft angegebene Fenster und zeigt es an.
<Application x:Class="WindowsOverview.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WindowsOverview"
StartupUri="ClippedWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
Besitz von Fenstern
Ein Fenster, das mithilfe der Show-Methode geöffnet wird, hat keine implizite Beziehung zu dem Fenster, in dem es erstellt wurde. Benutzer können unabhängig vom anderen Fenster mit beiden Fenstern interagieren. Dies bedeutet, dass beide Fenster Folgendes tun können:
- 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.
private void Button_Click(object sender, RoutedEventArgs e)
{
// Create a window and make the current window its owner
var ownedWindow = new ChildWindow1();
ownedWindow.Owner = this;
ownedWindow.Show();
}
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
' Create a window and make the current window its owner
Dim ownedWindow As New ChildWindow1
ownedWindow.Owner = Me
ownedWindow.Show()
End Sub
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.
Aktivieren von Fenstern
Wenn ein Fenster zum ersten Mal geöffnet wird, dann wird es das aktive Fenster. 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 x:Class="WindowsOverview.CustomMediaPlayerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Activated="Window_Activated"
Deactivated="Window_Deactivated"
Title="CustomMediaPlayerWindow" Height="450" Width="800">
<Grid>
<MediaElement x:Name="mediaElement" Stretch="Fill"
LoadedBehavior="Manual" Source="numbers.mp4" />
</Grid>
</Window>
Der folgende Code ist der CodeBehind für den XAML.
using System;
using System.Windows;
namespace WindowsOverview
{
public partial class CustomMediaPlayerWindow : Window
{
public CustomMediaPlayerWindow() =>
InitializeComponent();
private void Window_Activated(object sender, EventArgs e)
{
// Continue playing media if window is activated
mediaElement.Play();
}
private void Window_Deactivated(object sender, EventArgs e)
{
// Pause playing if media is being played and window is deactivated
mediaElement.Pause();
}
}
}
Public Class CustomMediaPlayerWindow
Private Sub Window_Activated(sender As Object, e As EventArgs)
' Continue playing media if window Is activated
mediaElement.Play()
End Sub
Private Sub Window_Deactivated(sender As Object, e As EventArgs)
' Pause playing if media is being played and window is deactivated
mediaElement.Pause()
End Sub
End Class
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. Für ein 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 wird durch Überprüfen der IsActive-Eigenschaft bestimmt.
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.
Verhindern der Fensteraktivierung
Es gibt Szenarien, in denen angezeigte Fenster nicht aktiviert werden sollten, z. B. Unterhaltungsfenster einer Chat-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 ist 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.
Schließen eines Fensters
Die Lebensdauer eines Fensters endet, wenn der Benutzer das Fenster schließt. Sobald ein Fenster geschlossen wurde, kann es nicht erneut geöffnet werden. 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.
- Drücken Sie ESC, wenn für eine Schaltfläche die IsCancel-Eigenschaft in einem
true
modalen Fenster auf festgelegt ist.
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 x:Class="WindowsOverview.ClosingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ClosingWindow" Height="450" Width="800">
<StackPanel>
<Menu>
<MenuItem Header="_File">
<MenuItem Header="E_xit" Click="fileExitMenuItem_Click" />
</MenuItem>
</Menu>
</StackPanel>
</Window>
Der folgende Code ist der CodeBehind für den XAML.
using System.Windows;
namespace WindowsOverview
{
public partial class ClosingWindow : Window
{
public ClosingWindow() =>
InitializeComponent();
private void fileExitMenuItem_Click(object sender, RoutedEventArgs e)
{
// Close the current window
this.Close();
}
}
}
Public Class ClosingWindow
Private Sub fileExitMenuItem_Click(sender As Object, e As RoutedEventArgs)
' Close the current window
Me.Close()
End Sub
End Class
Hinweis
Eine Anwendung kann so konfiguriert werden, dass sie automatisch beendet wird, wenn entweder das Hauptanwendungsfenster (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 schließt Windows.
- Ein Owner Fenster wird geschlossen.
- Das Hauptanwendungsfenster ist geschlossen und ShutdownMode ist OnMainWindowClose .
- Shutdown wird aufgerufen.
Wichtig
Ein Fenster kann nicht erneut geöffnet werden, nachdem es geschlossen wurde.
Schließen des Fensters abbrechen
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.
<Window x:Class="WindowsOverview.DataWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataWindow" Height="450" Width="800"
Closing="Window_Closing">
<Grid>
<TextBox x:Name="documentTextBox" TextChanged="documentTextBox_TextChanged" />
</Grid>
</Window>
Der folgende Code ist der CodeBehind für den XAML.
using System.Windows;
using System.Windows.Controls;
namespace WindowsOverview
{
public partial class DataWindow : Window
{
private bool _isDataDirty;
public DataWindow() =>
InitializeComponent();
private void documentTextBox_TextChanged(object sender, TextChangedEventArgs e) =>
_isDataDirty = true;
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
// If data is dirty, prompt user and ask for a response
if (_isDataDirty)
{
var result = MessageBox.Show("Document has changed. Close without saving?",
"Question",
MessageBoxButton.YesNo);
// User doesn't want to close, cancel closure
if (result == MessageBoxResult.No)
e.Cancel = true;
}
}
}
}
Public Class DataWindow
Private _isDataDirty As Boolean
Private Sub documentTextBox_TextChanged(sender As Object, e As TextChangedEventArgs)
_isDataDirty = True
End Sub
Private Sub Window_Closing(sender As Object, e As ComponentModel.CancelEventArgs)
' If data is dirty, prompt user and ask for a response
If _isDataDirty Then
Dim result = MessageBox.Show("Document has changed. Close without saving?",
"Question",
MessageBoxButton.YesNo)
' User doesn't want to close, cancel closure
If result = MessageBoxResult.No Then
e.Cancel = True
End If
End If
End Sub
End Class
Dem Closing-Ereignishandler wird ein CancelEventArgs übergeben, der die Cancel-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.
Ereignisse in der Lebensdauer eines Fensters
In der folgenden Darstellung wird die Abfolge der wichtigsten Ereignisse in der Lebensdauer eines Fensters gezeigt:
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):
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. Legen Sie die Eigenschaften fest, 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:
- CenterOwner (Standard)
- CenterScreen
- Manual
Wenn der Startspeicherort als angegeben ist Manual und Left und Top Eigenschaften nicht festgelegt worden sind, fragt das Betriebssystem nach einem Speicherort, in dem Window 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 befindet sich in der obersten Z-Reihenfolge, indem seine Topmost-Eigenschaft auf true
festgelegt wird.
Innerhalb jedes Z-Reihenfolgen-Typs 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 werden MaxWidth verwendet, um den Breitenbereich zu verwalten, den ein Fenster während seiner Lebensdauer haben kann.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
MinWidth="300" Width="400" MaxWidth="500">
</Window>
Die Fensterhöhe wird von MinHeightHeight, und MaxHeightverwaltet.
<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:
- SizeToContent.Manual
Keine Auswirkung (Standard). - SizeToContent.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. - SizeToContent.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. - SizeToContent.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:
- FrameworkElement.MinHeight
- FrameworkElement.MaxHeight
- SizeToContent.Height / SizeToContent.WidthAndHeight
- FrameworkElement.Height
Für Breiteneigenschaften:
- FrameworkElement.MinWidth
- FrameworkElement.MaxWidth
- SizeToContent.Width / SizeToContent.WidthAndHeight
- FrameworkElement.Width
Durch die Rangfolge kann beim Maximieren eines Fensters auch dessen Größe festgelegt werden. Dies wird von der WindowState-Eigenschaft verwaltet.
Window state
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. Der Fensterstil wirkt sich auf Folgendes aus:
- Erlauben oder verbieten Sie die Größenänderung, indem Sie den Fensterrand mit der Maus bewegen.
- Gibt an ob die SchaltflächenMinimieren, Vergrößern, und Schließen auf dem Nicht-Client-Bereich erscheinen.
- Gibt an ob die SchaltflächenMinimieren, Vergrößern, und Schließen 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:
- NoResize
- CanMinimize
- CanResize (Standard)
- CanResizeWithGrip
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.
Window style
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:
- None
- SingleBorderWindow (Standard)
- ThreeDBorderWindow
- ToolWindow
Die Auswirkung der Anwendung eines Fensterstils wird in der folgenden Abbildung veranschaulicht:
Beachten Sie, dass das obige Bild keinen erkennbaren Unterschied zwischen SingleBorderWindow
und ThreeDBorderWindow
zeigt. Zurück in Windows XP hat ThreeDBorderWindow
beeinflusst, wie das Fenster gezeichnet wurde, indem dem Clientbereich ein 3D-Rahmen hinzugefügt wurde. Ab Windows 7 sind die Unterschiede zwischen den beiden Stilen minimal.
Sie können WindowStyle festlegen, indem Sie entweder XAML-Markup oder Code verwenden. Da es unwahrscheinlich ist, dass sich dies während der Lebensdauer eines Fensters ändert, konfigurieren Sie es wahrscheinlich mit XAML-Markup.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowStyle="ToolWindow">
</Window>
Nicht rechteckiger Fensterstil
Es gibt auch Situationen, in denen vonWindowStyle erlaubten 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 im folgenden Image:
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 x:Class="WindowsOverview.ClippedWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ClippedWindow" SizeToContent="WidthAndHeight"
WindowStyle="None" AllowsTransparency="True" Background="Transparent">
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Rectangle Stroke="#FF000000" RadiusX="10" RadiusY="10"/>
<Path Fill="White" Stretch="Fill" Stroke="#FF000000" HorizontalAlignment="Left" Margin="15,-5.597,0,-0.003" Width="30" Grid.Row="1" Data="M22.166642,154.45381 L29.999666,187.66699 40.791059,154.54395"/>
<Rectangle Fill="White" RadiusX="10" RadiusY="10" Margin="1"/>
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="25" Text="Greetings!" TextWrapping="Wrap" Margin="5,5,50,5"/>
<Button HorizontalAlignment="Right" VerticalAlignment="Top" Background="Transparent" BorderBrush="{x:Null}" Foreground="Red" Content="❌" FontSize="15" />
<Grid.Effect>
<DropShadowEffect BlurRadius="10" ShadowDepth="3" Color="LightBlue"/>
</Grid.Effect>
</Grid>
</Window>
Durch diese Kombination von Werten wird das Fenster angewiesen, ein transparentes Rendering zu übernehmen. In diesem Zustand können die Nicht-Clientbereichs-Adornmentschaltflächen des Fensters nicht verwendet werden, und Sie müssen Ihre eigenen angeben.
Vorhandensein der Taskleiste
Die Standarddarstellung eines Fensters umfasst eine Taskleistenschaltfläche. Einige Arten von Fenstern verfügen nicht über eine Taskleistenschaltfläche, z. B. Meldungsfelder, Dialogfelderoder Fenster, für die die WindowStyle -Eigenschaft auf festgelegt ToolWindow ist. Sie können steuern, ob die Taskleistenschaltfläche für ein Fenster angezeigt wird, indem Sie die ShowInTaskbar-Eigenschaft, die standardmäßig auftrue
festgelegt ist, einstellen.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
ShowInTaskbar="False">
</Window>
Andere Fenstertypen
NavigationWindow ist ein Fenster, das zur Aufnahme von navigierbarem Inhalt bestimmt ist.
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 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
- Übersicht über Dialogfelder
- So öffnen Sie ein Fenster oder ein Dialogfeld
- So öffnen Sie ein allgemeines Dialogfeld
- So öffnen Sie ein Nachrichtenfeld
- So schließen Sie ein Fenster oder Dialogfeld
- System.Windows.Window
- System.Windows.MessageBox
- System.Windows.Navigation.NavigationWindow
- System.Windows.Application
.NET Desktop feedback