【问题标题】:Passing complex navigation parameters with MvvmCross ShowViewModel使用 MvvmCross ShowViewModel 传递复杂的导航参数
【发布时间】:2013-10-04 04:31:30
【问题描述】:

即使配置了此处指定的 MvxJsonNavigationSerializer Custom types in Navigation parameters in v3

,我的复杂类型也不会从 Show 传递到 Init 方法
public class A
{
 public string String1 {get;set;}
 public string String2 {get;set;}
 public B ComplexObject1 {get;set;}
}

public class B
{
 public double Double1 {get;set;}
 public double Double2 {get;set;}
}

当我将对象 A 的实例传递给 ShowViewModel 方法时,我收到了正确反序列化 String1 和 String2 但 CopmlexObject1 为空的对象。

如何处理复杂对象MvvmCross序列化?

【问题讨论】:

  • 我可以通过在我的 uiview 项目中添加 mvvmcross json 插件来解决这个问题。

标签: serialization navigation viewmodel mvvmcross complextype


【解决方案1】:

我相信之前的答案中可能有一些小问题 - 将作为问题记录:/


还有其他可能的途径来实现这种复杂的可序列化对象导航,仍然使用 Json 和覆盖框架的部分,但实际上我认为最好只使用您自己的 BaseViewModel 进行序列化和反序列化 - 例如使用像这样的序列化代码:

public class BaseViewModel
    : MvxViewModel
{
    private const string ParameterName = "parameter";

    protected void ShowViewModel<TViewModel>(object parameter)
        where TViewModel : IMvxViewModel
    {
        var text = Mvx.Resolve<IMvxJsonConverter>().SerializeObject(parameter);
        base.ShowViewModel<TViewModel>(new Dictionary<string, string>()
            {
                {ParameterName, text}
            });
    }
}

反序列化如下:

public abstract class BaseViewModel<TInit>
    : MvxViewModel
{
    public void Init(string parameter)
    {
        var deserialized = Mvx.Resolve<IMvxJsonConverter>().DeserializeObject<TInit>(parameter);
        RealInit(deserialized);
    }

    protected abstract void RealInit(TInit parameter);
}

然后是这样的 viewModel:

public class FirstViewModel
    : BaseViewModel
{
    public IMvxCommand Go
    {
        get
        {
            return new MvxCommand(() =>
                {
                    var parameter = new A()
                        {
                            String1 = "Hello",
                            String2 = "World",
                            ComplexObject = new B()
                                {
                                    Double1 = 42.0,
                                    Double2 = -1
                                }
                        };
                    ShowViewModel<SecondViewModel>(parameter);
                });
        }
    }
}

可以导航到类似:

public class SecondViewModel
    : BaseViewModel<A>
{
    public A A { get; set; }

    protected override void RealInit(A parameter)
    {
        A = parameter;
    }
}

【讨论】:

  • 谢谢!有趣的方法,这肯定会奏效,因为我自己完全控制序列化/反序列化过程。
【解决方案2】:

对 Stuart 的回答添加类型安全的一个小补充:

public class BaseViewModel: MvxViewModel {

    protected bool ShowViewModel<TViewModel, TInit>(TInit parameter) where TViewModel: BaseViewModel<TInit> {
        var text = Mvx.Resolve<IMvxJsonConverter>().SerializeObject(parameter);
        return base.ShowViewModel<TViewModel>(new Dictionary<string, string> { {"parameter", text} });
    }
}

public abstract class BaseViewModel<TInit> : BaseViewModel {

    public void Init(string parameter)
    {
        var deserialized = Mvx.Resolve<IMvxJsonConverter>().DeserializeObject<TInit>(parameter);
        RealInit(deserialized);
    }

    protected abstract void RealInit(TInit parameter);
}

ShowViewModel 方法现在采用与 RealInit 方法相同的参数类型,而不是 object 类型。此外,BaseViewModel&lt;TInit&gt; 继承自 BaseViewModel,因此它们的实例也可以调用新的 ShowViewModel 方法。

唯一的缺点是你必须像这样在调用中显式指定参数类型:

ShowViewModel<StoreInfoViewModel, Store>(store);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-08
    相关资源
    最近更新 更多