3. WPF应用程序启动时StartUp事件和重写OnStartup方法有什么不同

一. 目标

  1. 搞明白WPF应用中OnStartup() 方法的作用和用法
  2. 搞明白WPF应用中StartUp事件的作用和用法
  3. 搞明白为什么同时需要这两个功能?它们设计上有所重叠,什么时候使用重写OnStartup()方法,什么时候使用StartUp事件?

二. 技能介绍

① OnStartup方法介绍

OnStartup() 方法是Application类中的一个虚拟方法,提供了一种在派生类中处理启动逻辑的方式.当WPF应用程序启动并且准备好运行时,会自动调用此方法.通过重写OnStartup方法,你可以在应用程序启动时插入自定义的启动逻辑,比如配置应用程序环境,注册服务,准备数据等.这种方法更适合面向对象设计,对于需要复杂逻辑和更好封装的应用程序,重写OnStartup方法是更好的选择.下面举一个例子来说明OnStartup()方法的使用场景

public partial class App : Application
    {
        public App()
        {
            // 通过这种方式,可以将调试信息打印到输出窗口,在这种WPF应用程序中进行调试的时候很方便.
            System.Diagnostics.Debug.WriteLine("App() 构造函数执行完毕");
        }
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            // 初始化数据库
            InitializeDatabase();
            // 初始化日志系统
            InitializeLogging();
            // 注册全局异常处理器
            DispatcherUnhandledException += GlobalUiExceptionHandler;
            System.Diagnostics.Debug.WriteLine("OnSatrtup() 方法执行完毕!");
        }

        private void GlobalUiExceptionHandler(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
        }

        private void InitializeLogging()
        {
        }

        private void InitializeDatabase()
        {
        }
    }

构造函数和OnStartup()方法执行顺序
上面代码我学到了哪些技能:

  1. WPF框架的Application类实现了虚方法OnStartup(),它的子类可以重写这个方法,来进行应用程序的一些初始化工作.并且它的调用是在App()构造函数执行完成之后.
  2. System.Diagnostics.Debug.WriteLine 可以在WPF应用程序调试的时候增加调试日志到visual studio的输出窗口
② Startup事件介绍

Startup事件是Application类提供的一个事件,当应用程序完成启动准备时触发.Startup事件提供了一种更灵活的方式来添加启动逻辑,如果你不想继承Application的时候使用Strtup事件是更好的完成初始化动作的选择.

Startup事件的使用方式1:XAML中声明事件,后台实现(常规方法)

<Application x:Class="OnStartUpTest.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:OnStartUpTest"
             Startup="Application_Startup" StartupUri="MainWindow.xaml">
    <Application.Resources />
</Application>

Startup事件使用方式2:后台直接在构造函数中绑定事件

        public App()
        {
            Startup += Application_Startup;
            // 通过这种方式,可以将调试信息打印到输出窗口,在这种WPF应用程序中进行调试的时候很方便.
            System.Diagnostics.Debug.WriteLine("App() 构造函数执行完毕");
        }

具体的后台代码如下:

namespace OnStartUpTest
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        public App()
        {
            Startup += Application_Startup;
            // 通过这种方式,可以将调试信息打印到输出窗口,在这种WPF应用程序中进行调试的时候很方便.
            System.Diagnostics.Debug.WriteLine("App() 构造函数执行完毕");
        }

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            // 初始化数据库
            InitializeDatabase();
            // 初始化日志系统
            InitializeLogging();
            // 注册全局异常处理器
            DispatcherUnhandledException += GlobalUiExceptionHandler;
            System.Diagnostics.Debug.WriteLine("OnSatrtup() 方法执行完毕!");
        }

        private void GlobalUiExceptionHandler(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
        }

        private void InitializeLogging()
        {
        }

        private void InitializeDatabase()
        {
        }

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            // 加载配置数据
            LoadConfigurationData();
            System.Diagnostics.Debug.WriteLine("Startup 事件执行完毕!");
        }

        private void LoadConfigurationData()
        {
        }
    }
}

运行结果:
在这里插入图片描述

三. 结论

OnStartup()方法和Startup事件从功能上来说非常的相似,都是在启动的时候执行一些初始化和资源加载的工作.但是它们具有本质上的不同.

① 不同点1: 设计意图
  1. OnStartup是面向对象的一个设计,当你继承Application类的时候,可以重写这个方法,然后里面执行更加复杂的逻辑和自己做的一些项目启动前的准备
  2. Startup是事件驱动设计.允许多个订阅者监听和响应事件,同时适用于不需要从Application类派生的情况
② 不同点2: 执行时机

从上面的日志可以看出来Startup事件会先于OnStartup()方法执行

结论: 具体你想使用哪种方式来完成项目启动前的初始化,都是可以的,我一般喜欢使用事件的方式,比较简单,并且不需要重写父类方法

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用WPF的动画和线程来实现这个功能。以下是一个简单的实现方法: 1. 在启动窗口中,添加一个动画控件,比如一个旋转的圆圈。 2. 启动一个线程,在后台检测连接是否成功。 3. 当连接成功时,关闭启动窗口,打开应用程序主窗口。 以下是一个示例代码: XAML代码: ```xml <Window x:Class="StartupWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:YourNamespace" Title="StartupWindow" Height="300" Width="300"> <Grid> <Canvas> <Ellipse Width="50" Height="50" Fill="Blue"> <Ellipse.RenderTransform> <RotateTransform Angle="0" CenterX="25" CenterY="25"/> </Ellipse.RenderTransform> <Ellipse.Triggers> <EventTrigger RoutedEvent="Loaded"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetProperty="(Ellipse.RenderTransform).(RotateTransform.Angle)" From="0" To="360" Duration="0:0:1" RepeatBehavior="Forever"/> </Storyboard> </BeginStoryboard> </EventTrigger> </Ellipse.Triggers> </Ellipse> </Canvas> </Grid> </Window> ``` C# 代码: ```csharp public partial class StartupWindow : Window { public StartupWindow() { InitializeComponent(); // 启动后台线程 Thread thread = new Thread(new ThreadStart(CheckConnection)); thread.Start(); } private void CheckConnection() { // 检测连接是否成功 bool isConnected = YourNamespace.CheckConnection(); // 如果连接成功,关闭启动窗口,打开主窗口 if (isConnected) { Dispatcher.Invoke(() => { MainWindow mainWindow = new MainWindow(); mainWindow.Show(); Close(); }); } } } ``` 在上面的代码中,我们使用了Canvas和Ellipse来创建一个圆圈动画。我们使用了一个后台线程来检测连接是否成功,如果连接成功,我们使用Dispatcher.Invoke方法在主线程中关闭启动窗口,打开主窗口。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值