Translate

Saturday, 17 August 2013

WPF Top-Level Windows

WPF Top-Level Windows

A top-level window is a window that is not contained within or owned by another
window (window ownership is discussed in more detail later). A WPF application’s
main window is the top-level window that is set in the MainWindow property of the
Application object. This property is set by default when the first instance of the
Window class is created and the Application.Current property is set. In other words,
by default, the main window is the top-level window that’s created first after the
application itself has been created. If you like, you can override this default by setting
the MainWindow property manually.
In addition to the main window, the Application class provides a list of top-level
windows from the Windows property. This is useful if you’d like to implement a Window
menu.

To implement the Window menu, we first start with a MenuItem element:
<!-- Window1.xaml -->
<Window ...>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Menu>
<MenuItem Header="Window" x:Name="windowMenu">
<MenuItem Header="dummy item" />
</MenuItem>
</Menu>
</Grid>
</Window>
MenuItem is a HeaderedItemControl (as described in Chapter 5), which means that it
has header content that we’ll use to hold the name of the menu item (“Window”),
and subcontent that we’ll use to hold the menu items for each top-level window.
Notice the use of a dummy subitem to start with. Without this dummy item, you
won’t be able to get notification that the user has asked to show the menu items
(whether via mouse or via keyboard).
To populate the Window menu, we’ll handle the menu item’s SubmenuOpened event:
public partial class Window1 : Window {
...
public Window1( ) {
InitializeComponent( );
windowMenu.SubmenuOpened += windowMenu_SubmenuOpened;
}
void windowMenu_SubmenuOpened(object sender, RoutedEventArgs e) {
windowMenu.Items.Clear( );
foreach (Window window in Application.Current.Windows) {
MenuItem item = new MenuItem( );
item.Header = window.Title;
item.Click += windowMenuItem_Click;
item.Tag= window;
item.IsChecked = window.IsActive;
windowMenu.Items.Add(item);
}
}
void windowMenuItem_Click(object sender, RoutedEventArgs e) {
Window window = (Window)((MenuItem)sender).Tag;
window.Activate( );
}
}
When the SubmenuOpened event is triggered, we use the Application object’s Windows
property to get a list of each top-level Window, creating a corresponding MenuItem for
each Window.


Application Shutdown Modes

Some applications work naturally with the idea of a single main window. For example,
many applications (drawing programs, IDEs, Notepad, etc.) have a single top-level window
that controls the lifetime of the application itself (i.e., when the main window goes
away, the application shuts down). On the other hand, some applications have multiple
top-level windows or some other kind of lifetime control that’s independent of a single
main window.* You can specify when your application shuts down by setting the application’s
ShutdownMode property to one of the values of the ShutdownMode enumeration:
namespace System.Windows {
public enum ShutdownMode {
OnLastWindowClose = 0, // default
OnMainWindowClose = 1,
OnExplicitShutdown = 2,
}
}
The OnMainWindowClose value is useful when you’ve got a single top-level window,
and the OnLastWindowClose value is useful for multiple top-level windows (and is the
default). In either of these cases, in addition to the automatic application shutdown
the ShutdownMode policy describes, an application can also be shut down manually by
calling the Application object’s Shutdown method. However, in the case of
OnExplicitShutdown, the only way to stop a WPF application is by calling Shutdown:
public partial class Window1 : System.Windows.Window {
...
void shutdownButton_Click(object sender, RoutedEventArgs e) {
Application.Current.Shutdown();
}
}
You can change the shutdown mode in code whenever you like, or you can set it in
the application definition XAML:
<Application
x:Class="AppWindowsSample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml"
ShutdownMode="OnExplicitShutdown" />

No comments: