Uno Platform应用MainPage构造函数中Host为null问题求助
Uno Platform中Host为null问题的排查与解决
问题描述
我创建了一个新的Uno Platform应用,正尝试将环境特定的appSettings.json数据注入到页面中。目前已完成以下操作:
- 导入配置:
.UseConfiguration(configure: configBuilder => configBuilder .EmbeddedSource<App>() .Section<AppConfig>() .Section<ProjectorSettings>() .Section<HoleSettings>() ) - 注册路由:
private static void RegisterRoutes(IViewRegistry views, IRouteRegistry routes) { views.Register( new ViewMap(ViewModel: typeof(ShellModel)), new ViewMap<MainPage, MainModel>(), new ViewMap<BallPathPage, BallPathModel>() ); routes.Register( new RouteMap("", View: views.FindByViewModel<ShellModel>(), Nested: [ new("Main", View: views.FindByViewModel<MainModel>(), IsDefault: true), new("BallPath", View: views.FindByViewModel<BallPathModel>()) ] ) ); } - 在
MainModel.cs中注入IOptions:public MainModel( IStringLocalizer localizer, IOptions<AppConfig> appInfo, IOptions<ProjectorSettings> projectorSettingsOptions, IOptions<HoleSettings> holeSettingsOptions, INavigator navigator) { projectorSettings = projectorSettingsOptions.Value; holeSettings = holeSettingsOptions.Value; _navigator = navigator; }
最后尝试在MainPage.xaml.cs的构造函数中获取MainModel:
{ InitializeComponent(); var app = Application.Current as App; app?.MainWindow?.AppWindow.SetPresenter(Microsoft.UI.Windowing.AppWindowPresenterKind.FullScreen); var mainModel = (Application.Current as App)?.Host?.Services.GetRequiredService<MainModel>(); _projectorSettings = mainModel.projectorSettings; _holeSettings = mainModel.holeSettings; }
但执行到MainPage构造函数时,Host为null,请问哪里操作有误?
问题原因与解决方法
1. 核心问题:初始化时机不对
MainPage构造函数执行时,应用的Host尚未完成初始化。在Uno Platform的MVVM路由模式下,页面由路由系统创建,此时直接从App.Host读取服务容器会因为时机过早导致Host为null。
2. 正确实现:通过DataContext获取ViewModel
Uno的路由系统在导航到页面时,会自动将对应的ViewModel实例赋值给页面的DataContext。不需要手动从服务容器获取,直接读取DataContext即可:
修改MainPage.xaml.cs的构造函数:
{ InitializeComponent(); var app = Application.Current as App; app?.MainWindow?.AppWindow.SetPresenter(Microsoft.UI.Windowing.AppWindowPresenterKind.FullScreen); // 从DataContext获取已注入配置的MainModel实例 if (DataContext is MainModel mainModel) { _projectorSettings = mainModel.projectorSettings; _holeSettings = mainModel.holeSettings; } }
3. 额外验证:确保ViewModel已注册
虽然通过ViewMap<MainPage, MainModel>()的方式,Uno路由系统通常会自动注册ViewModel,但如果是自定义场景,需要手动在服务容器中注册MainModel:
在App.xaml.cs的服务配置代码中添加:
.Services.AddTransient<MainModel>();
这样就能保证MainModel被正确注入配置,页面也能正常获取到实例。
内容的提问来源于stack exchange,提问作者Matthew Flynn
相关产品推荐
相关产品推荐

