Wie alle Klassen hat auch ein Fenster eine Lebensdauer, die mit dem erstmaligen Instanziieren beginnt. Anschließend wird es geöffnet, aktiviert, deaktiviert und schließlich geschlossen.
Dieser Abschnitt enthält folgende Unterabschnitte.
Öffnen eines Fensters
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 einer Liste der vom Application-Objekt verwalteten Fenster automatisch ein Verweis darauf hinzugefügt (siehe Application..::.Windows). Zusätzlich wird das erste zu instanziierende Fenster standardmäßig von Application als Hauptanwendungsfenster festgelegt (siehe Application..::.MainWindow).
Schließlich wird das Fenster durch Aufrufen der Show-Methode geöffnet. Das Ergebnis wird in der folgenden Abbildung dargestellt.
.png)
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.
Wenn Show aufgerufen wird, führt ein Fenster die Initialisierung aus, bevor es zum Festlegen der Infrastruktur angezeigt wird, durch die es Benutzereingaben empfangen kann. Wenn das Fenster initialisiert wird, wird das SourceInitialized-Ereignis ausgelöst, und das Fenster wird angezeigt.
Als Arbeitserleichterung kann StartupUri so festgelegt werden, dass er das Fenster angibt, das beim Starten der Anwendung automatisch geöffnet wird.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
StartupUri="PlainWindow.xaml" />
Wenn die Anwendung gestartet wird, wird das durch den Wert von StartupUri angegebene Fenster im nicht modalen Modus geöffnet. Intern wird das Fenster durch Aufrufen der Show-Methode geöffnet.
Besitz von Fenstern
Zwischen dem mit der Show-Methode geöffneten Fenster und dem Fenster, von dem es erstellt wurde, besteht keine implizite Beziehung. Benutzer können mit dem jeweiligen Fenster unabhängig interagieren. Infolgedessen kann jedes Fenster folgende Aufgaben ausführen:
Das andere Fenster überdecken (es sei denn, die Topmost-Eigenschaft eines der Fenster ist auf true festgelegt).
Es wird minimiert, maximiert und wiederhergestellt, ohne das andere zu beeinflussen.
Bei einigen Fenstern ist eine Beziehung zu dem Fenster erforderlich, durch das es geöffnet wird. Eine Integrierte Entwicklungsumgebung (Integrated Development Environment, IDE)-Anwendung kann beispielsweise Eigenschaftenfenster und Toolfenster öffnen, deren typisches Verhalten es ist, das Fenster zu überdecken, von dem es erstellt wurde. Darüber hinaus sollten solche Fenster stets mit den Fenstern geschlossen, minimiert, maximiert und wiederhergestellt werden, durch die sie erstellt wurden. Eine solche Beziehung lässt sich herstellen, indem festgelegt wird, dass ein Fenster das andere besitzt. Dazu legen Sie die Owner-Eigenschaft von zum Besitzer gehöriges Fenster mit einem Verweis auf Besitzerfenster fest. Dies wird im folgenden Beispiel gezeigt.
// Create a window and make this window its owner
Window ownedWindow = new Window();
ownedWindow.Owner = this;
ownedWindow.Show();
Nach Einrichten des Besitzes:
Das zum Besitzer gehörige Fenster kann auf sein Besitzerfenster verweisen, indem der Wert der Owner-Eigenschaft überprüft wird.
Das Besitzerfenster kann alle ihm gehörenden Fenster durch Überprüfen des Wertes der OwnedWindows-Eigenschaft ermitteln.
Verhindern der Fensteraktivierung
Es gibt Szenarien, in denen angezeigte Fenster nicht aktiviert werden sollten, z. B. Unterhaltungsfenster einer Internet-Messenger-Anwendung oder Benachrichtigungsfenster einer E-Mail-Anwendung.
Falls Ihre Anwendung ein Fenster bereitstellt, das nicht aktiviert werden sollte, wenn Sie es anzeigen, können Sie die ShowActivated-Eigenschaft auf false festlegen, bevor Sie die Show-Methode zum ersten Mal ausführen. Daraus folgt:
Das Fenster wird nicht aktiviert.
Das Activated-Ereignis des Fensters wird nicht ausgelöst.
Das momentan aktivierte Fenster bleibt aktiviert.
Das Fenster wird jedoch aktiviert, sobald der Benutzer es durch Klicken auf den Client- oder Nicht-Clientbereich aktiviert. In diesem Fall gilt Folgendes:
Das Fenster wird aktiviert.
Das Activated-Ereignis des Fensters wird ausgelöst.
Das zuvor aktivierte Fenster wird deaktiviert.
Die Ereignisse Deactivated und Activated des Fensters werden anschließend als Reaktion auf Benutzeraktionen wie erwartet ausgelöst.
Ein Beispiel, das veranschaulicht, wie ein Fenster angezeigt wird, ohne es zu aktivieren, finden Sie unter Beispiel für das Anzeigen eines Fensters ohne Aktivieren.
Aktivieren von Fenstern
Wenn ein Fenster zum ersten Mal geöffnet wird, wird es zum aktiven Fenster (es sei denn, ShowActivated ist auf false festgelegt). Das aktive Fenster ist das Fenster, das gegenwärtig Benutzereingaben annimmt, z. B. Tastenanschläge und Mausklicks. Wird ein Fenster aktiv, löst es das Activated-Ereignis aus.
Hinweis: |
|---|
Beim ersten Öffnen eines Fensters, werden das Loaded-Ereignis und das ContentRendered-Ereignis erst ausgelöst, nachdem das Activated-Ereignis ausgelöst wurde. Vor diesem Hintergrund gilt ein Fenster als tatsächlich geöffnet, nachdem ContentRendered ausgelöst wurde. |
Nachdem ein Fenster aktiv geworden ist, kann ein Benutzer ein weiteres Fenster in derselben Anwendung oder eine andere Anwendung aktivieren. In diesem Fall wird das derzeit aktive Fenster deaktiviert, und es löst das Deactivated-Ereignis aus. Wenn der Benutzer ein derzeit deaktiviertes Fenster auswählt, wird das Fenster entsprechend neu aktiviert, und Activated wird ausgelöst.
Ein häufiger Grund für das Behandeln von Activated und Deactivated ist das Aktivieren und Deaktivieren der Funktionalität, die nur bei einem aktiven Fenster ausgeführt werden kann. In einigen Fenstern wird beispielsweise interaktiver Inhalt angezeigt, der andauernde Benutzereingaben oder Aufmerksamkeit erfordert, wie beispielsweise Spiele und Videoplayer. Im folgenden Beispiel wird durch einen vereinfachten Videoplayer veranschaulicht, wie Activated und Deactivated behandelt wird, um dieses Verhalten zu implementieren.
<Window
xmlns="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; // EventArgs
using System.Windows; // Window
namespace SDKSample
{
public partial class CustomMediaPlayerWindow : Window
{
public CustomMediaPlayerWindow()
{
InitializeComponent();
}
void window_Activated(object sender, EventArgs e)
{
// Recommence playing media if window is activated
this.mediaElement.Play();
}
void window_Deactivated(object sender, EventArgs e)
{
// Pause playing if media is being played and window is deactivated
this.mediaElement.Pause();
}
}
}
Andere Anwendungstypen führen im Hintergrund möglicherweise weiterhin Code aus, nachdem ein Fenster deaktiviert wurde. Ein E-Mail-Client kann z. B. weiterhin den E-Mail-Server abrufen, während der Benutzer andere Anwendungen verwendet. Während das Hauptfenster deaktiviert ist, stellen derartige Anwendungen häufig zusätzliches oder anderes Verhalten zur Verfügung. Im Hinblick auf das E-Mail-Programm kann das sowohl das Hinzufügen des neuen E-Mail-Elements zum Posteingang als auch eines Benachrichtigungssymbol in die Taskleiste bedeuten. Ein Benachrichtigungssymbol muss nur angezeigt werden, wenn das E-Mail-Fenster nicht aktiv ist. Dies lässt sich durch Überprüfen der IsActive-Eigenschaft feststellen.
Nach Ausführen einer Hintergrundtask benachrichtigt ein Fenster den Benutzer etwas dringlicher, indem die Activate-Methode aufgerufen wird. Wenn der Benutzer mit einer anderen Anwendung interagiert, die durch Aufrufen von Activate gestartet wird, blinkt die Taskleistenschaltfläche des Fensters. Interagiert der Benutzer mit der aktuellen Anwendung, wird das Fenster durch Aufrufen von Activate in den Vordergrund gestellt.
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:
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; // window, RoutedEventArgs
namespace SDKSample
{
public partial class WindowWithFileExit : System.Windows.Window
{
public WindowWithFileExit()
{
InitializeComponent();
}
void fileExitMenuItem_Click(object sender, RoutedEventArgs e)
{
// Close this window
this.Close();
}
}
}
Wenn ein Fenster geschlossen wird, löst es zwei Ereignisse aus: Closing und Closed.
Closing wird ausgelöst, bevor das Fenster geschlossen wird. Zusätzlich werden Mechanismen bereitgestellt, mit deren Hilfe das Schließen des Fensters verhindert werden kann. Der häufigste Grund, um das Schließen eines Fensters zu verhindern, liegt darin, dass Fensterinhalt geänderte Daten enthält. In diesem Fall kann das Closing-Ereignis behandelt werden, um festzustellen, ob Daten geändert wurden und um in diesem Fall den Benutzer zu fragen, ob er mit dem Schließen des Fensters fortfahren oder den Vorgang abbrechen möchte. Im folgenden Beispiel werden die wichtigsten Aspekte bei der Behandlung von Closing verdeutlicht.
using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // window
namespace CSharp
{
public partial class DataWindow : Window
{
// Is data dirty
bool isDataDirty = false;
...
void DataWindow_Closing(object sender, CancelEventArgs e)
{
MessageBox.Show("Closing called");
// If data is dirty, notify user and ask for a response
if (this.isDataDirty)
{
string msg = "Data is dirty. Close without saving?";
MessageBoxResult result =
MessageBox.Show(
msg,
"Data App",
MessageBoxButton.YesNo,
MessageBoxImage.Warning);
if (result == MessageBoxResult.No)
{
// If user doesn't want to close, cancel closure
e.Cancel = true;
}
}
}
}
}
Der Closing-Ereignishandler wird an CancelEventArgs übergeben, das die Boolean Cancel-Eigenschaft implementiert, die Sie auf true festlegen, um das Schließen eines Fensters zu verhindern.
Wenn Closing nicht behandelt bzw. behandelt, aber nicht abgebrochen wird, wird das Fenster geschlossen. Unmittelbar vor dem eigentlichen Schließen des Fensters wird Closed ausgelöst. An dieser Stelle kann das Schließen des Fensters nicht verhindert werden.
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 Windows implizit geschlossen wird, z. B.:
Ein Benutzer meldet sich ab oder schließt Windows.
Der Besitzer eines Fensters schließt (siehe Owner).
Das Hauptanwendungsfenster wird geschlossen, und ShutdownMode ist OnMainWindowClose.
Shutdown wird aufgerufen.
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.
.png)
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).
.png)