【问题标题】:MVVMCross Passing values to ViewModel that has 2 constructorsMVVMCross 将值传递给具有 2 个构造函数的 ViewModel
【发布时间】:2013-01-16 20:20:31
【问题描述】:

我有 2 个 ViewModelsConfigurationViewModelEditConfigurationViewModel)。在ConfigurationViewModel 我有以下代码:

    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 我有以下代码:

    public EditConfigurationViewModel()
    {
        Configuration = new ConfigurationSet();
    }

    public EditConfigurationViewModel(string id)
    {
        Configuration = ConfigDataStore.GetConfiguration(Guid.Parse(id));
    }

我想要实现的是非常简单的......在ConfigurationViewModel 触发NewConfigCommand 时,我想导航到EditConfigurationViewModel,并使用无参数构造函数。当EditConfigCommand 被触发时,我想使用接收string 的构造函数。

这段代码的问题是,无论触发什么命令,总是使用无参数构造函数,并且代码永远不会到达另一个构造函数。

我做了一些实验,通过删除无参数构造函数,结果是调用了另一个构造函数,我得到了EditConfigurationCommand 的预期结果,但是如果我尝试触发NewConfigurationCommand,则会抛出异常由于不存在无参数构造函数(到目前为止还不错)。

不幸的是,此时我没有安装VS2010,所以我无法通过PCL代码进行调试......我做了一些“眼睛调试”并找到了这个类MvxViewModelLocator。我认为问题出在此处。可能在DoLoad 方法中尝试获取MethodInfo...

此时我只想知道我做错了什么,或者这是否是预期的结果。同时我想我会抓住机会安装 VS2010 并祈祷它不会破坏任何东西......

【问题讨论】:

    标签: c# variables constructor mvvmcross


    【解决方案1】:

    关于 PCL 调试问题,何不直接加个 Win8 或 WP7/8 用户界面——然后你可以通过 PCL 代码调试...


    关于主要问题 - 关于如何使用多个构造函数...我建议你不要

    对我来说,edit 和 new 是两个不同的视图和两个不同的视图模型——它们可能共享共同的属性和共同的布局——但这可以通过继承、使用 UserControls、使用include axml 等来实现。

    有关我通常用于新建和编辑的示例,请参阅https://github.com/slodge/MvvmCross/tree/vnext/Sample%20-%20CustomerManagement/CustomerManagement/CustomerManagement/ViewModels


    如果您确实坚持使用一个视图模型,那么您可以考虑为 New 使用“神奇值” - 例如如果 Guid.Empty 被传递,那么这意味着新的?


    或者,您可以直接删除无参数构造函数,并为第二个构造函数添加默认值:

    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-more.html

    使用这种方法,您可以创建一个更加自定义的导航模型 - 或者如果这是唯一的特殊视图模型,那么我怀疑您可以创建一个默认的 viewModelLocator,例如:

    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 中注册该定位器:

    protected override IMvxViewModelLocator CreateDefaultViewModelLocator()
    {
         return new MyViewModelLocator();
    }
    

    【讨论】:

    • 像往常一样,一个非常详细的答案:) 谢谢你的帮助。在这种情况下,我将只使用构造函数中的默认值并删除无参数的值...将来在更复杂的场景中,如果可以的话,我将使用继承和/或 ViewModel 成本化。
    • 我刚刚尝试在 EditConfigurationViewModel public EditConfigurationViewModel(string id = null) 中使用具有默认值的构造函数。当我尝试导航到此 ViewModel 时,抛出异常:Cirrious.MvvmCross.Exceptions.MvxException: Failed to load ViewModel
    • 我想通了。尝试使用具有默认值的构造函数时会出现问题。由于某种原因,ViewModel 加载失败。在我重新安排我的开发环境来调试 PCL 代码后,我可以看看...
    • 如果失败,那么只需使用 Guid.Empty 作为特殊 id - 它只是 C# :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-09-28
    • 1970-01-01
    • 2011-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-09
    相关资源
    最近更新 更多