继承ReactiveUserControl<Job>后如何额外实现IViewFor<MainViewModel>并解决报错
结论
不可以同时继承ReactiveUserControl<Job>和实现IViewFor<MainViewModel>,你遇到的类型转换异常是ReactiveUI的固有机制导致的。
异常原因
ReactiveUserControl<T>本身已经内置实现了IViewFor<T>接口,接口的ViewModel属性强类型为泛型参数T。你额外为同一个视图实现IViewFor<MainViewModel>后,视图类会存在两个不同泛型版本的IViewFor<>实现。
当ItemsControl绑定ObservableCollection<Job>渲染JobView时,ReactiveUI会自动把当前的集合项(Job类型)赋值给IViewFor.ViewModel属性,运行时就会触发Job转MainViewModel的类型转换失败异常。
正确实现方案
你不需要修改JobView的基类就可以实现绑定MainViewModel属性的需求,可任选以下方案:
- 方案1:通过可视化树获取上级DataContext
在JobView的响应式绑定代码里,监听父级控件的DataContext获取MainViewModel实例:this.WhenAnyValue(x => x.Parent.DataContext) .OfType<MainViewModel>() .Subscribe(mainVm => { // 此处即可用mainVm做绑定 this.Bind(mainVm, vm => vm.你的主视图属性, v => v.你的视图控件属性) .DisposeWith(你的释放容器); }) .DisposeWith(你的释放容器); - 方案2:给Job模型增加父视图引用
在MainViewModel初始化Job实例时,把自身引用赋值给Job的ParentVM属性,之后在JobView中直接通过ViewModel.ParentVM即可拿到MainViewModel做绑定。 - 方案3:直接从Splat容器获取实例
如果你的MainViewModel已经注册到Splat容器,可在JobView中直接调用Locator.Current.GetService<MainViewModel>()获取实例进行绑定。
内容的提问来源于stack exchange,提问作者sa.he
相关产品推荐
相关产品推荐

