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

如何在MAUI多窗口应用中正确注册可复用视图?

在MAUI多窗口应用中正确注册并复用视图的解决方案

问题根源

你碰到的System.InvalidOperationException: 'MauiContext is null.'错误,核心原因是一个ContentPage实例只能绑定到一个Window。你的代码中:

  • MainPage被注册为单例(AddSingleton),它的构造函数只会执行一次,注入的SubPage实例也就只会被创建一次
  • 每次点击按钮时,你都把同一个SubPage实例赋值给新窗口,这违反了MAUI页面的生命周期规则,导致第二次绑定窗口时,页面的上下文已经被第一个窗口占用,无法初始化新的MauiContext。

正确处理方式

你临时用new SubPage()创建新实例的思路是对的,但更规范的做法是通过依赖注入容器获取新实例,这样能保留依赖注入的优势(比如SubPage有其他依赖时能自动注入)。下面提供两种可行方案:

方案一:通过IServiceProvider获取新实例

修改MainPage代码,注入服务容器,每次点击时从容器中获取全新的SubPage实例:

public partial class MainPage : ContentPage
{
    private readonly IServiceProvider _serviceProvider;

    public MainPage(IServiceProvider serviceProvider)
    {
        InitializeComponent();
        _serviceProvider = serviceProvider;
    }

    private void OnNewWindowClicked(object sender, EventArgs e)
    {
        var subPage = _serviceProvider.GetRequiredService<SubPage>();
        Window newWindow = new()
        {
            Page = subPage,
        };
        Application.Current?.OpenWindow(newWindow);
    }
}

MauiProgram中的注册代码保持不变,因为SubPage已经被注册为Transient,每次调用GetRequiredService都会创建新实例。

方案二:用Func<SubPage>工厂方法注入

在MauiProgram中注册一个工厂委托,让MainPage通过工厂获取新实例:

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .Services
                .AddSingleton<MainPage>()
                .AddTransient<SubPage>()
                .AddSingleton<Func<SubPage>>(sp => () => sp.GetRequiredService<SubPage>());
        return builder.Build();
    }
}

修改MainPage注入工厂委托:

public partial class MainPage : ContentPage
{
    private readonly Func<SubPage> _subPageFactory;

    public MainPage(Func<SubPage> subPageFactory)
    {
        InitializeComponent();
        _subPageFactory = subPageFactory;
    }

    private void OnNewWindowClicked(object sender, EventArgs e)
    {
        var subPage = _subPageFactory();
        Window newWindow = new()
        {
            Page = subPage,
        };
        Application.Current?.OpenWindow(newWindow);
    }
}

关键注意事项

  • 永远不要复用ContentPage实例:MAUI页面有专属的生命周期,每个实例会和所属窗口、上下文绑定,重复使用必然导致异常。
  • 保持SubPage的Transient注册:确保每次请求都能得到全新的实例,这是多窗口场景下的正确注册方式。
  • 优先通过依赖注入获取实例:避免直接new,这样能统一管理页面的依赖项,让代码更易于维护和测试。

内容的提问来源于stack exchange,提问作者symboli-rudolf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 23:23:10