Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将对象传递给“对象”的最佳方式是什么;导航到;MVVMCross中的viewmodel?_C#_Windows Phone 7_Xamarin.ios_Xamarin.android_Mvvmcross - Fatal编程技术网

C# 将对象传递给“对象”的最佳方式是什么;导航到;MVVMCross中的viewmodel?

C# 将对象传递给“对象”的最佳方式是什么;导航到;MVVMCross中的viewmodel?,c#,windows-phone-7,xamarin.ios,xamarin.android,mvvmcross,C#,Windows Phone 7,Xamarin.ios,Xamarin.android,Mvvmcross,我有一个ViewModel,其中包含一个团队,该团队有一个Players属性,它是一个Player对象列表。在TeamView中,团队负载很重,因此玩家数据已经在内存中 将给定的选定玩家类实例传递给PlayerView的最佳方式是什么 问题是MVVMCross ViewModel构造函数在当前版本中只能包含字符串属性 我有以下想法: 传递所选玩家的Id,并将Team.Player属性作为ViewModel分配给PlayerView。如果选定的玩家只是PlayerView中的焦点玩家,Player

我有一个ViewModel,其中包含一个团队,该团队有一个Players属性,它是一个Player对象列表。在TeamView中,团队负载很重,因此玩家数据已经在内存中

将给定的选定玩家类实例传递给PlayerView的最佳方式是什么

问题是MVVMCross ViewModel构造函数在当前版本中只能包含字符串属性

我有以下想法:

  • 传递所选玩家的Id,并将Team.Player属性作为ViewModel分配给PlayerView。如果选定的玩家只是PlayerView中的焦点玩家,PlayerView实际上是一个“玩家”视图,用户也可以在其他团队玩家之间滑动,那么这是一个合理的解决方案

  • 有一个类似ASP.Net MVC的ViewBag服务,它只能在类似字典的存储中的导航操作之间传输数据,传递给PlayerView的参数是“ViewBag:PlayerId123”,这是一个指向类实例的特殊键

  • 将所选对象序列化为字符串,并将其作为序列化对象传递给构造函数。这是可能的,但我不喜欢这个解决方案


  • 在常规导航中,MvvmCross只允许在ViewModels之间传递字符串

    这样做的原因是导航需要通过诸如Xaml URI或Android意图等机制在平台级别完成

    对于您建议的情况,我通常使用的一般模式是:

    • TeamViewModel使用注入的ITeamService从网络获取团队数据
    • TeamViewModel还使用注入的singleton ITeamCache来缓存团队
    • 导航通过以下调用进行:
    this.RequestNavigate(新的{teamId,playerId})

    • PlayerViewModel然后在其构造函数中接收TeamId和PlayerId,并使用ITeamCache收集正确的播放器
    此代码可能如下所示:

     public class TeamViewModel 
         : MvxViewModel
         , IMvxServiceConsumer<ITeamCache>
     {
         public TeamViewModel(string teamId, string playerId)
         {
             var teamCache = this.GetService<ITeamCache>();
             Player = teamCache.GetPlayer(teamId, playerId);
             if (Player == null)
             {
                 // todo - handle this error somehow!
             }
         }
    
         public Player Player { get; set; }
     }
    
    公共类TeamViewModel
    :MvxViewModel
    ,IMvxServiceConsumer
    {
    公共团队视图模型(字符串teamId、字符串playerId)
    {
    var teamCache=this.GetService();
    Player=teamCache.GetPlayer(teamId,playerId);
    if(Player==null)
    {
    //todo-以某种方式处理此错误!
    }
    }
    公共播放器播放器{get;set;}
    }
    
    注意,上面的代码测试Player是否为
    null
    。这是因为您的假设“在TeamView中,团队负载很重,因此球员数据已经在内存中”存在问题

    问题在于,在Android和WP7等平台上,操作系统可以自由地从内存中删除应用程序,然后稍后重新启动。这在WP7上被称为,但在Android上似乎被称为

    在这些情况下,当用户返回时,操作系统可能会重新启动应用程序。此重新启动将直接转到用户上次所在的活动,它将记住后堆栈-然后由应用程序将所有必需的对象正确地重新水化回内存

    下面是一些非常小的图片来解释这一点

    有关详细信息,请参见和


    对于您的团队/球员,您可以通过以下方式处理补液:

    • 将ITeamCache实现为文件支持的对象—例如,它可以使用JSON文件或SQLite数据库作为内存中数据的持久存储
    • 在代码中实现一些逻辑,以便在需要时从网络中重新提取数据
    • 在这些情况下实施一些紧急导航回家策略——因为这些情况在现代资源丰富的手机上的许多应用程序中并不经常发生
    • 只是撞车-虽然这是不可取的
    毫不奇怪,许多应用程序不能很好地处理墓碑


    注意-对于小对象,您的选项3(序列化)可以很好地工作-但是,这对发生应用程序再水化以及用户从PlayServiceWModel导航回TeamViewModel的情况没有帮助



    有关MvvmCross中Android lifecyle最近的一些变化的更多信息,请参见

    感谢Stuart的回答。这很有意义,我们很幸运,我们已经有了客户端SQLite数据库,因此应用程序重启是一件很容易的事,只有ITeamCache应该支持它。我很乐意接受它作为一个答案:-)类似于会议示例的东西应该向您展示我通常做的事情,现在更新了最新vnext代码中允许的参数-请参阅