【问题标题】:MVVM Pattern, I don't understand how should I code a "Detail" ViewModelMVVM 模式,我不明白我应该如何编写“详细信息”视图模型
【发布时间】:2016-04-13 06:57:44
【问题描述】:

假设我有一个显示通用客户列表的视图。在这种情况下,我将实现一个CustomersViewModel,其中RelayCommand 绑定到XAML 按钮,下载它并填充CustomerObservableCollection,绑定到ListView

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

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

我的导航逻辑:

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");
            }
    {
}

我想到的选项:

  1. 以某种方式将参数传递给“NavigateTo”函数,并在构造函数中使用该参数定义相对 ViewModel。虽然对我来说这似乎是合理的,但我没有找到这样做的方法。

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

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

    并在 ViewModel 中监听该消息:

    public CustomerDetailViewModel(NavigationService _navigationService)
    {
        // ...
                    Messenger.Default.Register<CustomMessageCustomerSelected>
                    (
                        this,
                        (action) =>
                        {
                            SelectedCustomer = action.Value;
                        }
                    );
        // ...
    
    }
    

【问题讨论】:

    标签: c# wpf xaml mvvm mvvm-light


    【解决方案1】:

    这两个选项都是合适的方法。您应该使用哪一个取决于您的应用程序的 UI 和工作流程。具体来说,您如何访问详细信息视图?例如,如果您单击一个按钮以打开一个新的“屏幕”(启动一个全新的视图来替换用户正在查看的任何内容),那么您应该使用选项 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,而不是对象。这意味着您必须从存储中获取数据,这对性能造成的影响很小,但也意味着您的用户在打开视图时始终会获得最新数据,从而减少了编辑冲突。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-15
      • 1970-01-01
      • 1970-01-01
      • 2011-01-15
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多