MVVMCross Passing values to ViewModel that has 2 constructors
我有 2 个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public ConfigurationViewModel() { NewConfigCommand = new MvxRelayCommand(DoNewConfig); EditConfigCommand = new MvxRelayCommand<ConfigurationSet>(DoEditConfig); } private void DoNewConfig() { this.RequestNavigate<EditConfigurationViewModel>(); } private void DoEditConfig(ConfigurationSet config) { this.RequestNavigate<EditConfigurationViewModel>(new { id = config.Id.ToString() }); } |
在 EditConfigurationViewModel 我有以下代码:
1 2 3 4 5 6 7 8 9 | public EditConfigurationViewModel() { Configuration = new ConfigurationSet(); } public EditConfigurationViewModel(string id) { Configuration = ConfigDataStore.GetConfiguration(Guid.Parse(id)); } |
我想要实现的是非常简单的......在
的构造函数
这段代码的问题是,无论触发什么命令,总是使用无参数构造函数,并且代码永远不会到达其他构造函数。
我做了一些实验,通过删除无参数构造函数,结果是调用了另一个构造函数,我得到了
不幸的是,此时我没有安装VS2010,所以我无法通过PCL代码进行调试......我做了一些"眼睛调试"并找到了这个类
此时我只想知道我做错了什么,或者这是否是预期的结果。同时我想我会抓住机会安装 VS2010 并祈祷它不会破坏任何东西...
关于 PCL 调试问题,为什么不直接添加一个 Win8 或 WP7/8 UI - 然后您可以通过 PCL 代码进行调试...
关于主要问题 - 关于如何使用多个构造函数...我建议你不要。
对我来说,edit 和 new 是两个不同的视图和两个不同的视图模型——它们可能共享共同的属性和共同的布局——但这可以通过继承、使用 UserControls、使用
有关我通常用于新建和编辑的示例,请参阅 https://github.com/slodge/MvvmCross/tree/vnext/Sample - CustomerManagement/CustomerManagement/CustomerManagement/ViewModels
如果您确实坚持使用一个视图模型,那么您可以考虑为 New 使用"神奇值" - 例如如果 Guid.Empty 被传递,那么这意味着新的?
或者,您可以删除无参数构造函数,并可以为第二个构造函数添加默认值:
1 2 3 4 5 6 7 8 9 10 11 12 | public EditConfigurationViewModel(string id = null) { Guid value; if (id == null || !Guid.TryParse(id, out value)) { Configuration = new ConfigurationSet(); } else { Configuration = ConfigDataStore.GetConfiguration(value); } } |
我觉得这样行吗?
最后,如果这些都不适合你,那么你可以考虑重写 ViewModel 构造机制。
为了解决这个问题,最近有一篇相当详细的文章介绍了如何为 MvvmCross 编写自己的默认 ViewModelLocator - 请参阅 http://slodge.blogspot.co.uk/2013/01/navigating-between-viewmodels-by-更多.html
使用这种方法,您可以创建一个更加自定义的导航模型 - 或者如果这是唯一的特殊视图模型,那么我怀疑您可以创建一个默认的 viewModelLocator,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public class MyViewModelLocator : MvxDefaultViewModelLocator { public override bool TryLoad(Type viewModelType, IDictionary<string, string> parameterValueLookup, out IMvxViewModel model) { if (viewModelType == typeof(EditConfigurationViewModel)) { string id; if (parameterValueLookup.TryGetValue("id", out id)) { model = new EditConfigurationViewModel(id); } else { model = new EditConfigurationViewModel(); } return true; } return base.TryLoad(viewModelType, parameterValueLookup, IMvxViewModel model); } } |
并在 App.cs 中注册该定位器:
1 2 3 4 | protected override IMvxViewModelLocator CreateDefaultViewModelLocator() { return new MyViewModelLocator(); } |