WinUI 3如何在Application类的OnLaunched方法中实现带启动逻辑的闪屏
WinUI 3 启动前校验展示闪屏/登录窗口的实现方案
WinUI 3 从App SDK 1.0 版本开始已经原生支持多窗口实例化,你提到的无法创建第二个Window派生类大概率是旧版本限制或者用法问题,以下提供3种可落地的实现方案:
方案1:单窗口内容切换(兼容性最优,无窗口闪烁)
不需要依赖多窗口能力,用同一个窗口做内容切换,是最稳妥的方案:
protected override async void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) { // 先实例化空窗口作为容器 m_window = new Window(); // 初始加载闪屏/登录页面 var splashLoginPage = new SplashLoginPage(); m_window.Content = splashLoginPage; m_window.Activate(); // 等待自定义校验逻辑完成,可在SplashLoginPage中暴露异步校验方法 var validationPassed = await splashLoginPage.RunValidationAsync(); if (!validationPassed) { // 校验失败直接退出应用 Application.Current.Exit(); return; } // 校验通过,替换窗口内容为主业务内容 // 如果你的NavigationRootWindow是Window类型,可取它的Content赋值,或者直接实例化新主窗口 var navigationRoot = new NavigationRootWindow(); m_window.Content = navigationRoot.Content; // 也可以直接销毁当前容器窗口,加载主窗口: // m_window.Close(); // m_window = new NavigationRootWindow(); // m_window.Activate(); }
如果不想修改NavigationRootWindow的继承关系,可以把主业务逻辑封装为UserControl,切换时直接替换Content属性即可。
方案2:多窗口实现(App SDK 1.0+支持)
当前新版本WinUI 3已经完全支持多窗口,可以先实例化闪屏窗口,校验完成后销毁再加载主窗口:
protected override async void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) { // 实例化闪屏窗口 var splashWindow = new Window(); var splashPage = new SplashLoginPage(); splashWindow.Content = splashPage; splashWindow.Activate(); // 等待校验完成 var validationPassed = await splashPage.RunValidationAsync(); // 关闭闪屏窗口 splashWindow.Close(); if (!validationPassed) { Application.Current.Exit(); return; } // 加载主窗口 m_window = new NavigationRootWindow(); m_window.Activate(); }
方案3:模态ContentDialog实现(最轻量)
如果不需要独立的闪屏窗口样式,直接用模态对话框做校验,用户无法跳过,实现成本最低:
protected override async void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) { m_window = new NavigationRootWindow(); // 先激活窗口 m_window.Activate(); // 弹出模态校验对话框 var validationDialog = new LoginValidationDialog(); validationDialog.XamlRoot = m_window.Content.XamlRoot; var dialogResult = await validationDialog.ShowAsync(); if (dialogResult != ContentDialogResult.Primary) { Application.Current.Exit(); return; } // 校验通过,初始化主业务逻辑 }
注意事项
OnLaunched作为事件处理器使用async void是合法的,但建议在校验逻辑中加异常捕获,避免未处理异常导致应用崩溃- 若需要适配更低版本的App SDK,优先选择方案1,不存在多窗口兼容性问题
- 闪屏页的校验逻辑可以封装到对应ViewModel中,和页面视图解耦
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

