ReactiveUI.XamForms页面ViewModel未初始化问题
问题根因
ReactiveUI.XamForms 提供的 ReactiveContentPage<TViewModel> 仅对ViewModel做泛型类型约束,不会自动实例化泛型参数指定的ViewModel类型并赋值给View的ViewModel属性。当前代码既没有手动给ViewModel属性赋值,也没有配置依赖注入/视图定位器自动解析ViewModel实例,因此ItemViewModel始终不会被创建,WhenActivated生命周期中拿到的ViewModel为null,所有绑定、命令逻辑自然无法生效。
修复方案
最小可运行修复
直接在View的构造函数中手动实例化ViewModel并赋值,修改ItemPage.xaml.cs的构造函数代码即可:
public ItemPage() { Trace.WriteLine("**** In ItemPage constructor"); InitializeComponent(); // 新增该行,手动注入ViewModel实例 ViewModel = new ItemViewModel(); this.WhenActivated( disposables => { Trace.WriteLine($"**** in WhenActivated: {this.ViewModel}."); this.OneWayBind(ViewModel, x => x.Counter, x => x.LblCounter.Text) .DisposeWith(disposables); this.BindCommand(ViewModel, x => x.IncrementCounter, x => x.BtnIncrement) .DisposeWith(disposables); }); }
额外代码问题修正
你当前ViewModel中的计数逻辑存在冗余自增,点击一次按钮Counter会累加2,需要把命令回调中Trace语句里的Counter++去掉:
this.incrementCounter = ReactiveCommand.Create(() => { Counter++; // 去掉Trace里的++,仅读取值即可 Trace.WriteLine($"Current Counter: {Counter}"); });
规范化自动关联方案
如果不想每个View都手动编写ViewModel实例化逻辑,可以配置ReactiveUI的内置依赖注入容器和视图定位器,实现ViewModel自动解析:
- 在App启动入口(通常是App.xaml.cs的构造函数)中注册程序集内的View和ViewModel映射:
using ReactiveUI; using System.Reflection; public App() { InitializeComponent(); // 自动扫描当前程序集中实现了IViewFor的View,自动关联对应ViewModel Locator.CurrentMutable.RegisterViewsForViewModels(Assembly.GetExecutingAssembly()); // 如果自动扫描不生效,可以手动注册ViewModel Locator.CurrentMutable.Register(() => new ItemViewModel(), typeof(ItemViewModel)); MainPage = new ItemPage(); }
- 配置完成后无需在View构造函数中手动赋值ViewModel,视图定位器会自动创建对应类型的ViewModel实例注入到View中。
你当前的XAML代码配置没有问题,x:TypeArguments和x:DataType的声明均符合编译绑定和ReactiveUI的要求,不需要修改。
内容的提问来源于stack exchange,提问作者Chu Bun
相关产品推荐
相关产品推荐

