5

在 v3 中,如果我想将两个对象传递给另一个视图模型:

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字典中?

更新:

这似乎做到了:

var foo = Mvx.Resolve<IMvxFillableStringToTypeParser>();
foo.ExtraParsers.Add(new MyParser());
4

1 回答 1

11

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对象(可能使用UrisIntents或其他序列化技术)传输到新对象DogViewModel,然后确保Init使用正确的值调用。

由于序列化,这很重要:

  • 不要传递大对象(UriWindowsPhone 上的 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();
     }
  1. 在导航中使用复合对象,例如:

    public class DogAndCatNav
    {
       public DogNav DogNav {get;set;}
       public CatNav CatNav {get;set;}
    }
    
  2. 这将由以下人员收到:

    public void Init(DogAndCatNav dogAndCatNav)
    {
    }
    

但请注意,这种技术确实需要更强大的序列化引擎——比如 Json。


总的来说......即使在写完所有这些......我建议您在导航中传递尽可能少的数据!

于 2013-05-14T09:57:05.743 回答