You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinUI3 Template Studio应用:主窗口启动前添加登录窗口的实现问题

WinUI 3 应用添加前置登录窗口的正确实现方案

核心问题解答

  1. 登录窗口的调用位置:必须在OnLaunched方法的最开始执行,不要先调用base.OnLaunched(args)和ActivateAsync(args)——这两个方法会直接初始化并启动Template Studio生成的主窗口,导致与登录窗口的生命周期冲突。
  2. 登录成功后切换主窗口:通过登录窗口的Closed事件触发主窗口初始化,在事件回调中判断登录状态,确认成功后再执行原本的主窗口启动逻辑。

你的三种尝试问题分析

  1. 第一种实现异常原因:先执行了base.OnLaunched和ActivateAsync,已经完成了主窗口的初始化,此时再创建并激活登录窗口,会触发WinUI 3窗口生命周期的冲突(默认应用启动流程已完成,重复初始化窗口导致异常)。
  2. 第二种实现无法启动主窗口原因:登录窗口刚Activate就立即判断ValidLogin,此时用户还未进行登录操作,ValidLogin必然为false,后续主窗口启动逻辑根本不会执行。
  3. 第三种实现的正确方向与优化点:通过Closed事件处理的思路是对的,但存在两个小问题:
    • 未正确保存LaunchActivatedEventArgs(需用私有字段存储,而非直接赋值)
    • 需确保LoginWindow中ValidLogin字段在登录成功后正确设置为true

正确实现代码

1. App.xaml.cs 修改

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Activation;

namespace YourAppNamespace;

public partial class App : Application
{
    private LaunchActivatedEventArgs? _launchArgs;

    protected override void OnLaunched(LaunchActivatedEventArgs args)
    {
        // 保存启动参数
        _launchArgs = args;

        // 创建并激活登录窗口
        var loginWindow = new LoginWindow();
        loginWindow.Closed += LoginWindow_Closed;
        loginWindow.Activate();
    }

    private async void LoginWindow_Closed(object sender, WindowEventArgs args)
    {
        if (sender is LoginWindow loginWindow && loginWindow.ValidLogin)
        {
            // 执行原本的主窗口启动逻辑
            base.OnLaunched(_launchArgs);
            App.GetService<IAppNotificationService>().Show(string.Format("AppNotificationSamplePayload".GetLocalized(), AppContext.BaseDirectory));
            await App.GetService<IActivationService>().ActivateAsync(_launchArgs);
        }
        else
        {
            // 登录失败或用户关闭窗口,直接退出应用
            Exit();
        }
    }
}

2. LoginWindow.xaml.cs 示例

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;

namespace YourAppNamespace;

public sealed partial class LoginWindow : Window
{
    public bool ValidLogin { get; private set; } = false;

    public LoginWindow()
    {
        InitializeComponent();
        // 设置登录窗口大小
        Width = 400;
        Height = 300;
    }

    private void LoginButton_Click(object sender, RoutedEventArgs e)
    {
        // 这里替换为你的登录验证逻辑
        var username = UsernameTextBox.Text;
        var password = PasswordBox.Password;

        if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
        {
            // 验证成功
            ValidLogin = true;
            Close();
        }
        else
        {
            // 验证失败,提示用户
            ContentDialog dialog = new ContentDialog()
            {
                Title = "登录失败",
                Content = "请输入有效的用户名和密码",
                PrimaryButtonText = "确定",
                XamlRoot = Content.XamlRoot
            };
            _ = dialog.ShowAsync();
        }
    }
}

关键注意事项

  • 登录窗口必须是Window类型,确保其独立于主窗口的生命周期。
  • 登录成功后必须调用Close()关闭登录窗口,触发Closed事件,进而启动主窗口。
  • 若用户未登录直接关闭登录窗口,需调用Exit()退出应用,避免应用后台驻留。

内容的提问来源于stack exchange,提问作者Niall O'Dwyer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 09:25:13