我正在尝试将信息从ViewModelA
传递到ViewModelB
,如下所示。当我调试代码时,我能够观察到我的SCoordinates
中有5个对象,但当我尝试在ViewModelB
中获取这5个对象时,它将变为空。其他信息(日期,sId)不为空,只有SCoordinates
为空。
ViewModelA
public ObservableCollection<SVModel> SCoordinates
{
get { return _sp; }
set
{
_sp = value;
RaisePropertyChanged(() => SCoordinates );
}
}
private void SSelected(SVModel obj)
{
ShowViewModel<ViewModelB>(new { sId = obj.Id, date = DateTime.Now, sCoordinates = SCoordinates });
}
ViewModelB
public void Init(string sId, DateTime date, ObservableCollection<SVModel> sCoordinates)
{
var sp = _sService.GetService(sId);
SVModel = new SVModel (sp);
// the following gets null
SCoordinates = sCoordinates;
}
答案 0 :(得分:4)
正如documentation明确指出:
请注意,由于序列化要求,此技术中使用的唯一可用参数类型仅为:
- 它必须包含无参数构造函数
- 它应该只包含具有get和set访问权限的公共属性
- 这些属性应仅包含以下类型:
- int,long,double,string,Guid,枚举值
换句话说,只支持使用valuetype作为参数的成员。
我认为这是MvvmCross的一个重大设计缺陷。我不是说这应该得到支持,但如果不遵循文档中的约束,框架应该抛出异常。因此,不是默默地接受传递不符合约束的类并传递null
,而是应该抛出一个明确的异常框架。从而通知您,而不是让您在这里搜索答案。
这种理念甚至有一个名称:Fail fast!
答案 1 :(得分:2)
我可以在这里考虑3个选项:
1){糟糕的做法,但很简单}创建一个服务(默认情况下在mvvmcross中单独使用)来保存您的SCoordinates
集合,而不是将它们保留在ViewModel中。这可能被认为是不好的做法,因为服务应该是无国籍的。虽然它会起作用。
<强>更新强>
作为评论问题的答案,这是一个例子。如果你使用MvvmCross,你应该熟悉这个:
public class App : MvxApplication
{
public override void Initialize()
{
CreatableTypes()
.EndingWith("Service")
.AsInterfaces()
.RegisterAsLazySingleton();
/// ...
}
}
因此,您创建一个以“Service”结尾的简单类以及核心项目中的相应接口。
public interface ICoordinatesService
{
ObservableCollection<SVModel> Coordinates { get; set; }
}
public class CoordinatesService : ICoordinatesService
{
public ObservableCollection<SVModel> Coordinates { get; set; }
}
要访问viewmodel中的服务,您可以使用constructor injection并无需使用方法即可访问服务中托管的集合,更简单的方法如下:
public class YourViewModel : MvxViewModel
{
public ObservableCollection<SVModel> Coordinates => _coordinatesService.Coordinates;
private readonly ICoordinatesService _coordinatesService;
public YourViewModel(ICoordinatesService coordinatesService)
{
_coordinatesService = coordinatesService;
}
public void SaveSomeCoordinates()
{
Coordinates.Add(new SVModel());
}
public void RemoveSomeCoordinates()
{
Coordinates.RemoveAt(1);
}
public void ResetCoordinates()
{
_coordinatesService.Coordinates = new ObservableCollection<SVModel>();
}
}
2)使用本地缓存系统保存SCoordinates
。您可以通过服务来完成:
public class Service
{
public ObservableCollection<SVModel> RestoreCoordinates()
{
// get from cache
}
public bool SaveCoordinates(ObservableCollection<SVModel> coordinates)
{
// save to cache
}
}
然后,在ViewModel.Init()
上,您可以恢复数据。
我建议使用Akavache作为简单的本地缓存,但您可以使用其他库或简单的SQLite表
3)Serialize your collection with Json.Net并将其作为字符串传递给ShowViewModel()
init params。然后在Init()方法