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

.NET Maui如何创建模态多窗口?

.NET Maui 实现模态窗口(父窗口可见但不可交互)的解决方案

核心问题分析

你的思路方向没问题,但.NET Maui原生对跨平台独立窗口的模态支持有限:直接用OpenWindow()+WinUI设置IsModal=true会因未正确绑定窗口所有者报错;而PushModalAsync是页面级导航模态,会隐藏父页面,完全不符合你要父窗口可见但不可交互的需求。

可行解决方案

方案1:Windows平台原生模态实现(WinUI)

针对Windows平台,通过平台特定代码获取父窗口句柄,为新窗口设置所有者后启用模态,可获得原生系统级模态体验:

// 在你的WindowPage类中重写OnAppearing方法
protected override void OnAppearing()
{
    base.OnAppearing();

#if WINDOWS
    var activeParentWindow = Application.Current.Windows.First(w => w.IsActive);
    if (activeParentWindow == null || this.Window == null) return;

    // 获取父窗口与新窗口的原生句柄
    var parentHandle = WinRT.Interop.WindowNative.GetWindowHandle(activeParentWindow.Handler.PlatformView);
    var newWindowHandle = WinRT.Interop.WindowNative.GetWindowHandle(this.Window.Handler.PlatformView);
    var winuiNewWindow = Microsoft.UI.Xaml.Window.GetWindowFromWindowId(Microsoft.UI.WindowId.GetFromWindowHandle(newWindowHandle));

    // 设置所有者并启用模态
    winuiNewWindow.SetWindowOwner(parentHandle);
    winuiNewWindow.IsModal = true;
#endif
}

注意:需在Windows项目中引用WinRT.Interop和Microsoft.UI.Xaml命名空间。

方案2:跨平台通用方案——禁用父窗口交互

如果需要跨平台兼容,无需依赖平台特定代码,可通过以下步骤模拟模态效果:

  1. 打开新窗口前,禁用父窗口的交互能力
  2. 监听新窗口的Closed事件,窗口关闭后恢复父窗口交互

示例代码(Razor组件的ModalWindowLaunch()方法):

private async void ModalWindowLaunch()
{
    var activeParentWindow = Application.Current.Windows.FirstOrDefault(w => w.IsActive);
    if (activeParentWindow == null) return;

    // 禁用父窗口交互(以ContentPage为例,可根据布局调整禁用范围)
    if (activeParentWindow.Page is ContentPage parentPage)
    {
        parentPage.IsEnabled = false;
    }

    // 创建并打开新窗口
    var modalWindow = new Window(new WindowPage());
    modalWindow.Closed += (sender, args) =>
    {
        // 恢复父窗口交互
        if (activeParentWindow.Page is ContentPage page)
        {
            page.IsEnabled = true;
        }
    };

    await Application.Current.OpenWindowAsync(modalWindow);
}

此方案跨平台通用,若父窗口布局复杂,可针对性禁用关键交互控件,而非直接禁用整个页面。

思路修正建议

你最初尝试WinUI设置模态的方向是对的,只是缺少了窗口所有者的绑定步骤;而PushModalAsync本身是页面导航栈的模态逻辑,和独立窗口的模态需求不匹配,确实不适用。

如果仅需支持Windows平台,方案1能获得最原生的模态体验;如果要覆盖多平台,方案2是更稳妥的选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 23:16:07