MVVM模式,我不明白我应该如何编写一个"详细信息"视图模型

时间:2016-01-08 14:43:47

标签: c# wpf xaml mvvm mvvm-light

想象一下,我有一个显示客户通用列表的视图。在这种情况下,我将实现CustomersViewModel绑定到XAML Button的RelayCommand,下载它并填充ObservableCollection Customer,绑定到{{1} }}

如果我想定义一个ListView,一个显示有关客户的其他信息的视图,我会创建一个CustomerDetailView,一个CustomerDetailViewModel,并重复相同的逻辑。但不同之处在于ViewModel必须将选定的Customer作为参数,而CustomerView每次都可以显示,而无需外部参数。 在WinForm解决方案中,我会放置一个参数来构造我需要的对象形式。

我的问题是:为了尊重MVVM模式,实施此类导航的正确方法是什么?

我的导航逻辑:

CustomersViewModel

我认为的选项:

  1. 以某种方式将参数传递给" NavigateTo"函数,并在构造函数中定义具有此参数的相对ViewModel。我没有办法做到这一点,虽然这对我来说似乎是合理的。

  2. 如上导航,然后向ViewModel发送消息。这个想法很有效,但我并不相信。在我看来,似乎有一种方法可以使一件简单的事情复杂化。

    static ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
    
        var nav = new NavigationService();
        nav.Configure("CustomersView", typeof(CustomersView));
        nav.Configure("CustomerDetailView", typeof(CustomerDetailView));
    
        SimpleIoc.Default.Register<INavigationService>(() => nav);
    
        SimpleIoc.Default.Register<CustomersViewModel>();
        SimpleIoc.Default.Register<CustomerDetailViewModel>();
    }
    
    private RelayCommand _navigateToCustomerDetailCommand;
    public RelayCommand NavigateToCustomerDetailCommand
    {
        get
        {
            return _navigateToCustomerDetailCommand
                ?? (_navigateToCustomerDetailCommand = new RelayCommand(
                () =>
                {
                    _navigationService.NavigateTo("CustomerDetail");
                }
        {
    }
    

    在ViewModel中收听该消息:

        return _navigateToCustomerDetailCommand
            ?? (_navigateToCustomerDetailCommand = new RelayCommand(
            () =>
            {
                _navigationService.NavigateTo("CustomerDetail");
                Messenger.Default.Send(new CustomMessageCustomerSelected(SelectedCustomer));            
            }
    

1 个答案:

答案 0 :(得分:1)

这两种选择都是适当的方法。您应该使用哪一个取决于应用程序的UI和工作流程。具体来说,您如何访问详细信息视图?比如,如果你点击一个按钮打开一个新的屏幕&#34; (启动一个全新的视图来替换用户正在查看的内容),然后你应该使用选项1.如果你有一个类似客户列表的东西与详细信息视图并排,并且视图应该在新客户时更新单击,然后使用选项2.

要实现第一个选项,您需要使用控件容器和ViewModelLocator类的SimpleIoc反转。您使用定位器注册ViewModel,然后使用该定位器处理对新VM的请求并调用其构造函数。这意味着您可以轻松地将包含客户的消息作为参数发送,然后将其提供给VM的构造函数。 Here is a decent introduction to ViewModelLocator,虽然已有几年了,但here is a quick and dirty intro to SimpleIoc

顺便说一句,如果您要拥有多个并发用户(特别是选项2),我建议发送客户的ID,而不是对象。这意味着您必须从存储中获取它,这是一个小的性能影响,但也意味着您的用户在打开视图时始终获取最新数据,这反过来减少了编辑冲突。