use*_*032 1 c# android mvvmcross xamarin
我有两个按钮,它们都显示一个新的视图模型,但是传递给viewmodel的数据不同.传递的数据并不完全不同,因此它们都从相同的基础继承.不幸的是,似乎传递给viewmodel的Init()方法的数据在途中丢失了它的运行时类型信息?使用调试器(或代码),传递的数据仅被识别为基类 - 而不是实际构造并传递给ShowViewModel <>()方法的派生类.
是什么我试图不可能?
public class BasePasser
{
}
public class PasserA : BasePasser
{
}
public class PasserB : BasePasser
{
}
public class ViewModelOne : MvxViewModel
{
// ...
private void DoSwitchViewModelA()
{
var tobepassed = new PasserA {
// ...
};
ShowViewModel<ViewModelTwo>(tobepassed);
}
private void DoSwitchViewModelB()
{
var tobepassed = new PasserB {
// ...
};
ShowViewModel<ViewModelTwo>(tobepassed);
}
}
public class ViewModelTwo : MvxViewModel
{
// ...
public async Task Init(BasePasser passed)
{
if(passed is PasserA)
{
// ...
}
else if(passed is PasserB)
{
// ...
}
else
{
// Always called/hit
throw new InvalidOperationException("Unknown data passed");
}
}
}
Run Code Online (Sandbox Code Playgroud)
在MvvmCross中显示ViewModel实际上是一个非常复杂的过程.
当您调用ShowViewModel(param)时, Mvx会将param值序列化为名称/值字典.此时,param的Type信息将丢失.
实例化ViewModel后,它最终将查找ViewModel上定义的任何Init方法.
如果您查看Cirrious.MvvmCross.ViewModels.MvxViewModelExtensions.CallBundleMethod(),您将看到它首先查找具有IMvxBundle类型的单个参数的方法.然后它查找一个不是简单类型的单个参数(如string,int等)
如果它找到此类型,则假定它是在ShowViewModel()调用中已序列化的对象.然后,它尝试根据Init方法中的参数类型而不是原始类型反序列化值.
这就是您只看到基类型的原因,因为Mvx没有初始调用的类型信息,并且在反序列化时,只能看到Init方法中的基类型.
解决方法是将所有属性放入单个类中.只设置你需要的那个,并创建一个discriminator属性,指定它是什么"类型".
var param = new Passer { PasserType = "A", ParamA = "ValueA", ... etc. }
您还可以选择使用命名方法参数.
请参阅https://github.com/MvvmCross/MvvmCross/wiki/View-Model-Lifecycle的Init部分
| 归档时间: |
|
| 查看次数: |
181 次 |
| 最近记录: |