MVVMCross中多ViewModel复用同一View的实现方案问询
MvvmCross中复用Fragment视图适配多个ViewModel的解决方案
问题场景
我在MvvmCross中使用Fragments,一直遵循1视图对应1ViewModel的映射规则。现在遇到特殊需求:View A(Fragment)已绑定ViewModel A,而ViewModel B继承自ViewModel A,我希望直接复用View A,无需为ViewModel B新建View B。但MvvmCross的导航逻辑基于ViewModel,因此需要实现ViewModel A和ViewModel B导航时都指向View A。
作为新手初步调研后,考虑过1视图对应多ViewModel的映射方式,但发现MvxFragment仅支持单个泛型ViewModel参数,不确定是否需要自行实现适配逻辑。
可行解决方案
方案1:手动注册视图映射
在MvvmCross初始化阶段(如Setup.cs的InitializeLastChance方法),手动为ViewModel B添加到View A的映射:
protected override void InitializeLastChance() { base.InitializeLastChance(); var viewsContainer = Mvx.IoCProvider.Resolve<IMvxViewsContainer>(); // 注册ViewModel A与View A的映射(若默认自动注册可省略) viewsContainer.Add(typeof(ViewModelA), typeof(ViewA)); // 关键:将ViewModel B也映射到View A viewsContainer.Add(typeof(ViewModelB), typeof(ViewA)); }
这种方式直接覆盖默认映射逻辑,适合简单的继承场景,无需修改View的泛型定义。
方案2:利用ViewModel继承兼容
保持View A的泛型参数为父类ViewModelA(因为ViewModel B是其子类),MvvmCross导航时会自动兼容子类ViewModel:
// View A的定义(无需修改泛型参数) public class ViewA : MvxFragment<ViewModelA> { // 视图绑定逻辑基于ViewModelA的属性/命令 }
注意:如果ViewModel B有特有的属性或命令需要在View A中绑定,需在View中通过类型转换(如
(ViewModelB)ViewModel)访问,同时要处理类型转换的安全校验。
方案3:自定义视图查找器
如果需要更灵活的映射规则(比如多个无关ViewModel复用同一View),可以自定义视图查找器:
- 实现自定义
IMvxViewFinder:
public class CustomViewFinder : MvxAndroidViewFinder { public override Type GetViewType(Type viewModelType) { // 当导航目标是ViewModelB时,返回ViewA的类型 if (viewModelType == typeof(ViewModelB)) { return typeof(ViewA); } // 其他场景沿用默认查找逻辑 return base.GetViewType(viewModelType); } }
- 在
Setup.cs中替换默认查找器:
protected override IMvxViewFinder CreateViewFinder() { return new CustomViewFinder(); }
内容的提问来源于stack exchange,提问作者telksat_fr
相关产品推荐
相关产品推荐

