v3中导航参数中的自定义类型 [英] Custom types in Navigation parameters in v3
问题描述
在v3中,如果我想将两个对象传递给另一个视图模型:
In v3 if I wanted to pass two objects to another viewmodel:
public class Dog
{
}
public class Cat
{
}
var dog = new Dog();
var cat = new Cat();
ShowViewModel<SomeViewModel>(new {Dog = dog, Cat = cat });
public class SomeViewModel
{
Init(Dog dog, Cat cat)
{
}
}
据我所知,这是行不通的,因为类型无法识别且不能卡在字典中.如果我想将这些序列化为json,传递给视图模型并反序列化为Init
参数,我是否可以实现IExtraParser
?如果正确的话,我该如何将实现添加到ExtraParsers
词典中?
As far as I can tell that won't work because the types aren't recognized and can't be stuck in a dictionary. If I wanted to have these serialized as json, passed to the view model, and deserialized as Init
parameters, would I implement IExtraParser
? And if that is correct, how do I go about adding the implementations to the ExtraParsers
dictionary?
更新:
这似乎可以做到:
var foo = Mvx.Resolve<IMvxFillableStringToTypeParser>();
foo.ExtraParsers.Add(new MyParser());
推荐答案
MvvmCross中的默认导航机制特意是轻量级的.
The default navigation mechanism in MvvmCross is deliberately lightweight.
确实可以让您仅传递一个简单的可序列化对象-例如.
It is really there to allow you to pass just one simple, serializable object - e.g.
public class DogNav
{
public int Id {get;set;}
public string Caption {get;set;}
}
// received in:
public class DogViewModel : MvxViewModel
{
public void Init(DogNav dogNav)
{
}
}
通过此设置,如果触发导航的方式如下:
With this setup, if a navigation is triggered like:
// navigation
ShowViewModel<DogViewModel>(new DogNav() { Id=12, Caption="Good boy" });
然后底层系统会将值从该DogNav
对象(可能使用Uri
s,Intents
或其他序列化技术)传输到新的DogViewModel
用正确的值调用Init
.
then the underlying system will transport the values from that DogNav
object - possibly using Uri
s, Intents
or other serialization techniques - to the new DogViewModel
and will then ensure Init
is called with the correct values.
由于序列化,这一点很重要:
Because of the serialization, it's important:
- 不传递大对象(WindowsPhone上的
Uri
可能会破译几百个字符) - 不不能期望会有相同的对象实例到达-即,如果您使用的是数据库支持的或有状态的对象,则最好传递某种查找关键字,而不是对象本身. li>
- 不,不能期望只有一个ViewModel会收到该消息-在某些操作系统上,可能是用户在应用之间来回了很多次,导致许多View和ViewModel出现.已创建.
- 不,不能期望接收消息的ViewModel与发送请求的ViewModel处于相同的进程和内存空间中-逻辑删除事件发生后几天实际上可能会收到相同的消息. /li>
- not to pass big objects (
Uri
s on WindowsPhone can break above a few hundred characters) - not to expect the same object instance to arrive - i.e. if you are using database-backed or stateful objects, then it's best to pass some kind of lookup key rather than the objects themselves.
- not to expect that only one ViewModel will receive the message - on some operating systems, it may be that the user goes back and forth many, many times between apps causing many Views and ViewModels to be created.
- not to expect that a ViewModel that receives the message is in the same process and memory space as the ViewModel that sent the request - the same may actually be received days later after a tombstoning event.
如果您确实想通过导航传递多个对象,那么我认为您可以使用以下代码来做到这一点:
If you do want to pass multiple objects via navigation, then I think you can do this using code like:
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)
{
}
}
在这种情况下,您可以使用:
In this case you could navigate using:
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);
我认为这会起作用...
I think this would work...
但是...请注意,序列化非常简单-因此,如果CatNav
和DogNav
共享一个属性名称,则将导致问题-您最终会遇到一些Cags和Dots
However... please be aware that the serialization is very simple - so if CatNav
and DogNav
were to share a property name, then this would lead to problems - you'd end up with some Cags and Dots
由于存在点状和点状问题,因此我不建议您使用这种方法...
Because of the Cag and Dot problem I don't recommend this approach...
如果您确实需要在应用中进行更复杂的转换,那么一种方法是:
If you do need more complex transitions in your apps, then one route is to:
更新-请参见将复杂的导航参数与MvvmCross ShowViewModel
<罢工> 1.添加Json插件(或任何Json序列化程序)并更改Setup.cs代码以创建 CreateNavigationSerializer
1. Add the Json Plugin (or any Json serializer) and change your Setup.cs code to create a MvxJsonNavigationSerializer - overriding CreateNavigationSerializer
protected override IMvxNavigationSerializer CreateNavigationSerializer()
{
return new MvxJsonNavigationSerializer();
}
-
在导航中使用复合对象,例如:
Use a composite object in navigation like:
public class DogAndCatNav
{
public DogNav DogNav {get;set;}
public CatNav CatNav {get;set;}
}
这将由以下人员接收:
This would be received by:
public void Init(DogAndCatNav dogAndCatNav)
{
}
但是请注意,此技术确实需要更强大的序列化引擎-例如Json.
But note that this technique does need a more powerful serialization engine - such as Json.
总体...即使写完了所有这些内容... 我建议您在导航中传递尽可能少的数据!
Overall... even after writing all this... I'd recommend you pass as little data as possible in your navigations!
这篇关于v3中导航参数中的自定义类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!