WPF Window对象的生命周期

  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 = 0;
        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退出应用)

  用户在运行系统上的多个窗口中切换时,ActivatedDeactivated在窗口的生命周期里会发生多次。ContentRendered事件只对窗口第一次完全呈现出来进行触发。为了让一些事情能在所有内容都显示给用户之前马上执行,可以用Loaded事件;为了让一些事情能在所有内容都显示给用户之后马上执行,可以用ContentRendered事件。

PS:

  1.Unloaded:应用程序开始关闭后(Application.Current.Shutdown();),不会引发此事件。  如果您将处理程序中的清理代码放 Unloaded 事件,例如对于 Window  UserControl, ,可能不会按预期方式调用它。

       2. 根据 ShutdownMode 属性配置的不同,关闭窗体时Shutdown的隐式调用可能会导致Unloaded不会按预期的方式被调用。

原文地址:https://www.cnblogs.com/u-drive/p/8295861.html