C# 如何在MVVM中将ObservableCollection从ViewModelA传递到ViewModelB
我正在尝试将信息从C# 如何在MVVM中将ObservableCollection从ViewModelA传递到ViewModelB,c#,mvvm,xamarin,mvvmcross,C#,Mvvm,Xamarin,Mvvmcross,我正在尝试将信息从ViewModelA传递到ViewModelB,如下所示。当我调试代码时,我可以观察到我的SCoordinates中有5个对象,但当我尝试在ViewModelB中获取这5个对象时,它将为空。其他信息(日期、sId)不为空,只有SCoordinates为空 ViewModelA public ObservableCollection<SVModel> SCoordinates { get { return _sp; } set { _sp
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 });
}
公共可观测集合坐标
{
获取{return\u sp;}
设置
{
_sp=值;
RaisePropertyChanged(()=>坐标);
}
}
已选择专用作废(SVModel obj)
{
ShowViewModel(新的{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;
}
public void Init(字符串sId、日期时间日期、可观测集合坐标)
{
var sp=_sService.GetService(sId);
SVModel=新SVModel(sp);
//下面的值为空
坐标轴=坐标轴;
}
正如文件中明确指出的:
请注意,由于序列化要求,此技术中使用的唯一可用参数类型只有:
- 它必须包含无参数构造函数
- 它应该只包含具有get和set访问权限的公共属性
- 这些属性应仅为以下类型:
- int、long、double、字符串、Guid、枚举值
null
。从而通知你,而不是让你在这里寻找答案
这一理念甚至有一个名字:,正如该书明确指出的:
请注意,由于序列化要求,此技术中使用的唯一可用参数类型只有:
- 它必须包含无参数构造函数
- 它应该只包含具有get和set访问权限的公共属性
- 这些属性应仅为以下类型:
- int、long、double、字符串、Guid、枚举值
null
。从而通知你,而不是让你在这里寻找答案
这种哲学甚至有一个名字:我可以在这里想到三种选择: 1) {Bad practice but easy}创建一个服务(mvvmcross中默认为singleton)来保存
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.Init()
上可以恢复数据
我建议将其用作一个简单的本地缓存,但您可以使用其他库或普通的SQLite表
3) 并将其作为字符串传递给
ShowViewModel()
init params。然后在Init()方法上反序列化它我可以在这里想到3个选项:
1) {Bad practice but easy}创建一个服务(mvvmcross中默认为singleton)来保存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.Init()
上可以恢复数据
我建议将其用作一个简单的本地缓存,但您可以使用其他库或普通的SQLite表
3) 并将其作为字符串传递给
ShowViewModel()
init params。然后在Init()方法上反序列化它我没有看到对Init方法的任何调用…?Init
方法在传递参数时会在mvvm模式中自动调用。如果我错了,请纠正我。请参考以下url,特别是在带参数的导航中-使用参数对象部分,我没有看到对Init方法的任何调用…?Init
方法在传递参数时会在mvvm模式中自动调用。如果我错了,请纠正我。请参考以下url,特别是在带参数的导航中-使用参数对象部分,您有什么建议,我应该如何处理?将ObservableCollection转换为List然后传递它是否正确?我已经对你的答案投了赞成票。我建议不要依赖于框架的这些特性。viewmodels之间的导航非常容易自己构建,因此遵循了所有坚实的设计原则。您的viewmodels现在依赖于MVVMCross。这是相当可怕的,如果你以后想切换MVVM框架,即使我已经将ObservableCollection转换为列表,它仍然是nu