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

WinUI3:如何从主窗口启动时显示对话框?

WinUI3 启动时正确显示ContentDialog的方法

问题出在窗口构造函数执行时,UI还没完成渲染,XamlRoot还没被初始化,所以直接调用DisplayDialog会报错。你需要等窗口的UI完全加载完成后再操作,WinUI3的窗口本身就提供了官方时机——Loaded事件或者OnLoaded重写方法,不需要依赖控件。

方法一:绑定窗口的Loaded事件

这是最直观的方式,直接监听窗口加载完成的信号:

public MainWindow()
{
    this.InitializeComponent();
    // 绑定窗口自身的Loaded事件,而非控件的
    this.Loaded += MainWindow_Loaded;
}

// 事件处理方法用async void是允许的
private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    await DisplayDialog();
}

// 普通异步方法建议用async Task,比async void更规范
private async Task DisplayDialog()
{
    var dlg = new ContentDialog();
    dlg.XamlRoot = this.Content.XamlRoot;
    dlg.Title = "提示"; // 建议添加标题,提升用户体验
    dlg.Content = "Hello World";
    dlg.PrimaryButtonText = "确定"; // 必须添加至少一个按钮,否则用户无法关闭对话框
    await dlg.ShowAsync();
}

方法二:重写窗口的OnLoaded方法

这是更符合面向对象设计的方式,直接重写WinUI3 Window类的虚方法:

public MainWindow()
{
    this.InitializeComponent();
}

// 重写窗口的OnLoaded方法,这是官方推荐的窗口加载完成回调
protected override async void OnLoaded(RoutedEventArgs e)
{
    base.OnLoaded(e); // 一定要调用基类的OnLoaded方法,否则会破坏原有逻辑
    await DisplayDialog();
}

private async Task DisplayDialog()
{
    var dlg = new ContentDialog();
    dlg.XamlRoot = this.Content.XamlRoot;
    dlg.Title = "提示";
    dlg.Content = "Hello World";
    dlg.PrimaryButtonText = "确定";
    await dlg.ShowAsync();
}

为什么这两种方法可行?

窗口的Loaded事件和OnLoaded方法,会在窗口的所有UI元素都完成渲染、XamlRoot被正确赋值之后才触发,这时候访问this.Content.XamlRoot肯定不会为空,完全不需要依赖任何控件,是最规范的实现方式。

新手小贴士

  • 永远不要在窗口构造函数里直接执行需要UI初始化完成的代码,构造阶段只是创建对象,UI还没开始渲染。
  • async void仅适合事件处理方法,普通异步方法优先用async Task,方便后续的错误捕获和逻辑扩展。
  • ContentDialog必须设置至少一个按钮(Primary/Secondary/Cancel),否则用户无法手动关闭对话框,只能通过代码强制关闭。

内容的提问来源于stack exchange,提问作者WalderFrey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:55:15