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
相关产品推荐
相关产品推荐

