MvvmCross 中的默认导航机制是故意轻量级的。
它确实允许您传递一个简单的、可序列化的对象 - 例如
public class DogNav
{
public int Id {get;set;}
public string Caption {get;set;}
}
// received in:
public class DogViewModel : MvxViewModel
{
public void Init(DogNav dogNav)
{
}
}
使用此设置,如果触发导航,例如:
// navigation
ShowViewModel<DogViewModel>(new DogNav() { Id=12, Caption="Good boy" });
然后底层系统会将值从该DogNav
对象(可能使用Uri
sIntents
或其他序列化技术)传输到新对象DogViewModel
,然后确保Init
使用正确的值调用。
由于序列化,这很重要:
- 不要传递大对象(
Uri
WindowsPhone 上的 s 可以超过几百个字符)
- 不要期望相同的对象实例到达 - 即,如果您使用数据库支持或有状态的对象,那么最好传递某种查找键而不是对象本身。
- 不要期望只有一个 ViewModel 会收到消息 - 在某些操作系统上,可能是用户在应用程序之间来回多次来回,导致创建许多 Views 和 ViewModels。
- 不要期望接收消息的 ViewModel 与发送请求的 ViewModel 位于相同的进程和内存空间中 - 实际上可能会在墓碑事件发生几天后收到相同的消息。
如果您确实想通过导航传递多个对象,那么我认为您可以使用以下代码执行此操作:
public class CatNav
{
public int CatId {get;set;}
public string CatCaption {get;set;}
}
public class DogNav
{
public int DogId {get;set;}
public string DogCaption {get;set;}
}
// received in:
public class CatAndDogViewModel : MvxViewModel
{
public void Init(DogNav dogNav)
{
}
public void Init(CatNav catNav)
{
}
}
在这种情况下,您可以使用以下方式导航:
var catNav = new CatNav() { CatId =12, CatCaption="Meow" };
var dogNav = new DogNav() { DogId =12, DogCaption="Woof" };
var bundle = new MvxBundle();
bundle.Write(catNav);
bundle.Write(dogNav);
ShowViewModel<CatAndDogViewModel>(bundle);
我认为这会奏效...
但是......请注意,序列化非常简单 - 所以如果CatNav
并且DogNav
要共享一个属性名称,那么这会导致问题 - 你最终会得到一些 Cags 和 Dots
由于 Cag 和 Dot 问题,我不推荐这种方法......
如果您确实需要在应用程序中进行更复杂的转换,那么一种方法是:
更新- 请参阅使用 MvvmCross ShowViewModel 传递复杂的导航参数
1. 添加 Json 插件(或任何 Json 序列化程序)并更改您的 Setup.cs 代码以创建MvxJsonNavigationSerializer - 覆盖CreateNavigationSerializer
protected override IMvxNavigationSerializer CreateNavigationSerializer()
{
return new MvxJsonNavigationSerializer();
}
在导航中使用复合对象,例如:
public class DogAndCatNav
{
public DogNav DogNav {get;set;}
public CatNav CatNav {get;set;}
}
这将由以下人员收到:
public void Init(DogAndCatNav dogAndCatNav)
{
}
但请注意,这种技术确实需要更强大的序列化引擎——比如 Json。
总的来说......即使在写完所有这些......我建议您在导航中传递尽可能少的数据!