v3中导航参数中的自定义类型 [英] Custom types in Navigation parameters in v3

查看:64
本文介绍了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 Uris, 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 (Uris 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...

但是...请注意,序列化非常简单-因此,如果CatNavDogNav共享一个属性名称,则将导致问题-您最终会遇到一些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代码以创建

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();
     }

  1. 在导航中使用复合对象,例如:

  1. 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屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆