WPF中所有窗口的基类型都是System.Windows.Window。Window通常用于SDI(SingleDocumentInterface)、MDI(MultipleDocumentInterface)窗口和对话框。Window在应用程序中除了一个设计用于托管*内容的控件外,就别无他物了。典型的,可以混合使用标记和代码来定义一个窗口。代码如下(这里使用VisualStudio 输出窗口查看调试信息):
xaml代码:
<Window x:Class="WindowDemo.MainWindow"
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:WindowDemo"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Content="测试" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Name="BtnOpenWindow" Click="BtnOpenWindow_Click"/>
</Grid>
</Window>
c#代码:
using System;
using System.Windows; namespace WindowDemo
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Unloaded += MainWindow_Unloaded;
this.Initialized += MainWindow_Initialized;
this.ContentRendered += MainWindow_ContentRendered;
this.Loaded += MainWindow_Loaded;
this.Activated += MainWindow_Activated;
this.Deactivated += MainWindow_Deactivated;
this.Closing += MainWindow_Closing;
this.Closed += MainWindow_Closed;
Console.WriteLine($"{this.Name}:Constructor");
} private void MainWindow_Closed(object sender, EventArgs e)
{
Console.WriteLine($"{this.Name}:Closed");
} private void MainWindow_Unloaded(object sender, RoutedEventArgs e)
{
Console.WriteLine($"{this.Name}:Unloaded");
} private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
Console.WriteLine($"{this.Name}:Closing");
} private void MainWindow_ContentRendered(object sender, EventArgs e)
{
Console.WriteLine($"{this.Name}:ContentRendered");
} private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Console.WriteLine($"{this.Name}:Loaded");
} private void MainWindow_Deactivated(object sender, EventArgs e)
{
Console.WriteLine($"{this.Name}:Deactivated");
} private void MainWindow_Activated(object sender, EventArgs e)
{
Console.WriteLine($"{this.Name}:Activated");
} private void MainWindow_Initialized(object sender, EventArgs e)
{
Console.WriteLine($"{this.Name}:Initialized");
} private static int i = ;
private void BtnOpenWindow_Click(object sender, RoutedEventArgs e)
{
new MainWindow()
{
Name = $"window_{i}"
}.Show();
i++;
} }
}
界面:
生命周期中事件执行顺序:
1.Constructor:构造函数创建窗体对象是调用,整个生命周期中调用一次
2.Activated:在窗口成为前台窗口时发生
3.Loaded:当对元素进行布局、呈现,且可将其用于交互时发生
4.ContentRendered:在呈现窗口的内容之后发生
5.用户与窗体进行交互
6.Closing:之后立即发生 Close 被调用,并且可以处理以取消关闭窗口
7.Deactivated:在窗口成为后台窗口时发生
8.Closed:当窗口即将关闭时发生
9.Unloaded:当元素从加载元素的元素树中移除时发生。
过程1:在创建窗体对象是调用,过程2-4:在调用Show、ShowDialog时触发,过程6-9:关闭窗口时触发(点击关闭按钮,而非Application.Current.Shutdown退出应用)
用户在运行系统上的多个窗口中切换时,Activated和Deactivated在窗口的生命周期里会发生多次。ContentRendered事件只对窗口第一次完全呈现出来进行触发。为了让一些事情能在所有内容都显示给用户之前马上执行,可以用Loaded事件;为了让一些事情能在所有内容都显示给用户之后马上执行,可以用ContentRendered事件。
PS:
1.Unloaded:应用程序开始关闭后(Application.Current.Shutdown();),不会引发此事件。 如果您将处理程序中的清理代码放 Unloaded 事件,例如对于 Window 或 UserControl, ,可能不会按预期方式调用它。
2. 根据 ShutdownMode 属性配置的不同,关闭窗体时Shutdown的隐式调用可能会导致Unloaded不会按预期的方式被调用。