As with any class, a window has a lifetime that begins when it is first instantiated, after which it is opened, activated and deactivated, and eventually closed.
This section contains the following subsections.
- Opening a Window
- Window Activation
- Closing a Window
- Window Lifetime Events
Opening a Window
To open a window, you first create an instance of it, which is demonstrated in the following example.
<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 this example, the MarkupAndCodeBehindWindow is instantiated when the application starts, which occurs when the Startup event is raised.
When a window is instantiated, a reference to it is automatically added to a list of windows that is managed by the Application object (see Application..::.Windows). Additionally, the first window to be instantiated is, by default, set by Application as the main application window (see Application..::.MainWindow).
The window is finally opened by calling the Show method; the result is shown in the following figure.
.png)
A window that is opened by calling Show is a modeless window, which means that the application operates in a mode that allows users to activate other windows in the same application.
When Show is called, a window performs initialization work before it is shown to establish infrastructure that allows it to receive user input. When the window is initialized, the SourceInitialized event is raised and the window is shown.
As a shortcut, StartupUri can be set to specify the first window that is opened automatically when an application starts.
<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" />
When the application starts, the window specified by the value of StartupUri is opened modelessly; internally, the window is opened by calling its Show method.
Window Ownership
A window that is opened by using the Show method does not have an implicit relationship with the window that created it; users can interact with either window independently of the other, which means that either window can do the following:
Cover the other (unless one of the windows has its Topmost property set to true).
Be minimized, maximized, and restored without affecting the other.
Some windows require a relationship with the window that opens them. For example, an Integrated Development Environment (IDE) application may open property windows and tool windows whose typical behavior is to cover the window that creates them. Furthermore, such windows should always close, minimize, maximize, and restore in concert with the window that created them. Such a relationship can be established by making one window own another, and is achieved by setting the Owner property of the owned window with a reference to the owner window. This is shown in the following example.
// Create a window and make this window its owner
Window ownedWindow = new Window();
ownedWindow.Owner = this;
ownedWindow.Show();
After ownership is established:
The owned window can reference its owner window by inspecting the value of its Owner property.
The owner window can discover all the windows it owns by inspecting the value of its OwnedWindows property.
Preventing Window Activation
There are scenarios where windows should not be activated when shown, such as conversation windows of an Internet messenger-style application or notification windows of an e-mail application.
If your application has a window that shouldn't be activated when shown, you can set its ShowActivated property to false before calling the Show method for the first time. As a consequence:
The window is not activated.
The window's Activated event is not raised.
The currently activated window remains activated.
The window will become activated, however, as soon as the user activates it by clicking either the client or non-client area. In this case:
The window is activated.
The window's Activated event is raised.
The previously activated window is deactivated.
The window's Deactivated and Activated events are subsequently raised as expected in response to user actions.
For an example that demonstrates how to show a window without activating it, see Show a Window Without Activating Sample.
Window Activation
When a window is first opened, it becomes the active window (unless it is shown with ShowActivated set to false). The active window is the window that is currently capturing user input, such as key strokes and mouse clicks. When a window becomes active, it raises the Activated event.
After a window becomes active, a user can activate another window in the same application, or activate another application. When that happens, the currently active window becomes deactivated and raises the Deactivated event. Likewise, when the user selects a currently deactivated window, the window becomes active again and Activated is raised.
One common reason to handle Activated and Deactivated is to enable and disable functionality that can only run when a window is active. For example, some windows display interactive content that requires constant user input or attention, including games and video players. The following example is a simplified video player that demonstrates how to handle Activated and Deactivated to implement this behavior.
<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();
}
}
}
Other types of applications may still run code in the background when a window is deactivated. For example, a mail client may continue polling the mail server while the user is using other applications. Applications like these often provide different or additional behavior while the main window is deactivated. With respect to the mail program, this may mean both adding the new mail item to the inbox and adding a notification icon to the system tray. A notification icon need only be displayed when the mail window isn't active, which can be determined by inspecting the IsActive property.
If a background task completes, a window may want to notify the user more urgently by calling Activate method. If the user is interacting with another application activated when Activate is called, the window's taskbar button flashes. If a user is interacting with the current application, calling Activate will bring the window to the foreground.
Closing a Window
The life of a window starts coming to an end when a user closes it. A window can be closed by using elements in the non-client area, including the following:
You can provide additional mechanisms to the client area to close a window, the more common of which include the following:
An Exit item in the File menu, typically for main application windows.
A Close item in the File menu, typically on a secondary application window.
A Cancel button, typically on a modal dialog box.
A Close button, typically on a modeless dialog box.
To close a window in response to one of these custom mechanisms, you need to call the Close method. The following example implements the ability to close a window by choosing the Exit on the File menu.
<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();
}
}
}
When a window closes, it raises two events: Closing and Closed.
Closing is raised before the window closes, and it provides a mechanism by which window closure can be prevented. One common reason to prevent window closure is if window content contains modified data. In this situation, the Closing event can be handled to determine whether data is dirty and, if so, to ask the user whether to either continue closing the window without saving the data or to cancel window closure. The following example shows the key aspects of handling 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;
...
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;
}
}
}
}
}
The Closing event handler is passed a CancelEventArgs, which implements the Boolean Cancel property that you set to true to prevent a window from closing.
If Closing is not handled, or it is handled but not canceled, the window will close. Just before a window actually closes, Closed is raised. At this point, a window cannot be prevented from closing.
Note: |
|---|
An application can be configured to shut down automatically when either the main application window closes (see
MainWindow) or the last window closes. For details, see ShutdownMode.
|
While a window can be explicitly closed through mechanisms provided in the non-client and client areas, a window can also be implicitly closed as a result of behavior in other parts of the application or Windows, including the following:
Note: |
|---|
A window cannot be reopened after it is closed.
|
Window Lifetime Events
The following illustration shows the sequence of the principal events in the lifetime of a window.
.png)
The following illustration shows the sequence of the principal events in the lifetime of a window that is shown without activation (ShowActivated is set to false before the window is shown).
.png)