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

MAUI多窗口应用中DisplayPromptAsync始终显示在主窗口的问题咨询

问题原因与解决方案

这个问题其实是MAUI多窗口场景下的一个常见小坑——模态对话框的显示上下文默认绑定到当前活动窗口,而你创建的新窗口没有被主动激活,导致所有DisplayPromptAsync都附着到了主窗口上。

具体原因拆解:

  1. 当你调用Application.Current.OpenWindow()创建新窗口时,MAUI会显示这个窗口,但并不会自动将它设置为"当前活动窗口",此时应用的活动窗口仍然是主窗口(MainPage所在的窗口)。
  2. DisplayPromptAsync是Page的方法,但它的显示依赖于当前活动窗口的模态展示服务。所以即使你在子窗口的Page里调用它,只要子窗口没被激活,对话框就会弹在主窗口上。
  3. 后续子窗口的调用会排队等待主窗口的模态对话框处理完毕,所以会按创建顺序依次弹出;而每个子窗口的newPlayerName是各自Page实例的独立变量,只是因为对话框弹在主窗口,让你误以为变量没有更新——实际上第一个对话框的输入会赋值给第一个子窗口的变量,第二个对话框的输入会赋值给第二个子窗口的变量,只是显示位置不对而已。

修复步骤:

1. 创建新窗口时主动激活它

修改主页面的按钮点击事件代码,在打开新窗口后立即激活它,确保它成为当前活动窗口:

private void NewTournamentButton_Clicked(object sender, EventArgs e)
{
    var newWindow = new Window(new NewTournamentPage());
    Application.Current.OpenWindow(newWindow);
    // 关键:激活新窗口,让MAUI将其视为当前活动窗口
    newWindow.Activate();
}

2. 调用对话框前确保当前窗口处于激活状态(可选但保险)

在子页面的添加选手按钮事件中,先激活当前页面所在的窗口,再调用DisplayPromptAsync,避免因为窗口失去焦点导致对话框跑错位置:

public async void AddNewPlayer_Clicked(object sender, EventArgs e)
{
    // 确保当前页面所在的窗口是激活状态
    this.Window.Activate();
    
    string newPlayerName = await this.DisplayPromptAsync("Add new Player", "Name:");
    
    if (!string.IsNullOrWhiteSpace(newPlayerName))
    {
        // 这里写添加选手到赛事的逻辑
    }
}

3. (可选)优化异步事件处理写法

虽然async void在事件处理中是允许的,但async Task更符合异步编程规范,也更容易排查问题。你可以这样修改事件处理方法:

public async Task AddNewPlayer_Clicked(object sender, EventArgs e)
{
    this.Window.Activate();
    string newPlayerName = await this.DisplayPromptAsync("Add new Player", "Name:");
    // 添加选手逻辑...
}

然后在XAML中绑定事件时,使用Command而不是Clicked(.NET MAUI也支持直接绑定async Task类型的事件处理方法)。

这样修改后,每个子窗口的对话框就会正确显示在自己的窗口上,输入的内容也会正确赋值给对应子窗口的newPlayerName变量,不会再出现主窗口"抢"对话框的情况了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 22:19:08