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

