Loading

WPF的Application类详解

一、STAThread关键字

​ STAThread是一种线程模型,用在程序的入口方法上(在C#和VB.NET里是Main()方法),来指定当前线程的ApartmentState 是STA。所有WPF程序,都必须在单一线程公寓(STA)模型中运行。在Main函数前加上STAThread属性,就是满足WPF的这一要求,即UI不能在多线程的环境中运行。

​ [STAThread] attribute指示应用程序的 COM 线程模型是单线程单元,而于此对应的多线程单元则是 [MTAThread] (多线程单元线程)。

​ COM线程模型只适用于使用COM interop(托管代码与非托管代码之间的协同过程)的应用程序,如果将此属性应用到不使用 COM interop 的应用程序,将没有任何效果。

​ COM线程模型可设置为单线程单元或多线程单元。如果应用程序线程实际调用了 COM 组件,则仅为COM interop初始化该线程。如果没有使用 COM interop,则不初始化该线程。

二、Application类中与应用程序生存期相关的事件

image-20210515120146449

三、Application类的属性

image-20210515164307563

四、Application的关闭

​ WPF应用程序的关闭只有在应用程序的 Shutdown 方法被调用时,应用程序才停止运行。 ShutDown 是隐式或显式发生,可以通过指定 ShutdownMode 的属性值来进行设置。对ShutdownMode选项的更改,可以直接在App.xaml中更改。ShutdownMode选项具体含义如下:

image-20210515164442961

五、使用OnStartup重写处理Main函数的命令行参数

当我们不能定义自己的Main方法。这时候若要处理命令行参数,则要移植OnStartUp方法,具体如下:

 protected override void OnStartup(StartupEventArgs e)
        {
            Console.WriteLine($"{DateTime.Now:O} 当调用Run方法时,系统调用此方法");
            base.OnStartup(e);
            foreach (var arg in e.Args)
            {
                Console.WriteLine($"命令行:{arg}");
            }
        }

全部的测试代码和测试输入如下:

  public partial class App : Application
    {
        private void App_OnStartup(object sender, StartupEventArgs e)
        {
            var window = new MainWindow();
            window.Loaded += (s1, e1) =>
            {
                Console.WriteLine(App.Current); 
                Console.WriteLine(App.Current.MainWindow);
                Console.WriteLine(App.Current.Windows);
                Console.WriteLine(App.Current.StartupUri);
                Console.WriteLine(App.Current.ShutdownMode);
                Console.WriteLine(App.Current.Dispatcher);

            };
            window.ShowDialog();
        }
        protected override void OnActivated(EventArgs e)
        {
            Console.WriteLine($"{DateTime.Now:O} 应用程序获得输入焦点时调用");
            base.OnActivated(e);
        }
        protected override void OnDeactivated(EventArgs e)
        {
            Console.WriteLine($"{DateTime.Now:O} 应用程序失去输入焦点时调用");
            base.OnDeactivated(e);
        }

        protected override void OnStartup(StartupEventArgs e)
        {
            Console.WriteLine($"{DateTime.Now:O} 当调用Run方法时,系统调用此方法");
            base.OnStartup(e);
            foreach (var arg in e.Args)
            {
                Console.WriteLine($"命令行:{arg}");
            }
        }

        protected override void OnExit(ExitEventArgs e)
        {
            Console.WriteLine($"{DateTime.Now:O} 在应用程序退出前调用");
            Console.WriteLine($"按任意键结束...");
            Console.ReadKey();
            base.OnExit(e);
        }
        protected override void OnSessionEnding(SessionEndingCancelEventArgs e)
        {
            Console.WriteLine($"{DateTime.Now:O} 当用户退出登录或者系统关机前调用");
            base.OnSessionEnding(e);
        }
    }

使用cmd启动程序,输入入参aa bbb cc后,输入结果如下:

Microsoft Windows [版本 10.0.19042.928]
(c) Microsoft Corporation。保留所有权利。

C:\Users\97460>D:\@dwayne\@MyProcess\@书籍\WPF专业编程指南\books\src\chapter01\chapter01\bin\Debug\chapter01.exe aa bbb cc
2021-05-15T16:59:26.9534731+08:00 当调用Run方法时,系统调用此方法
2021-05-15T16:59:27.0914739+08:00 应用程序获得输入焦点时调用
chapter01.App
chapter01.MainWindow
System.Windows.WindowCollection

OnLastWindowClose
System.Windows.Threading.Dispatcher
aa
bbb
cc
2021-05-15T16:59:41.5539152+08:00 应用程序失去输入焦点时调用

posted @ 2021-05-15 17:07  Dwaynerbing  阅读(620)  评论(0编辑  收藏  举报