MVVM模式下的模型实例化

13

在WPF的MvvmFoundation之后,连接View和ViewModel有很多选择,就像http://www.paulstovell.com/mvvm-instantiation-approaches中描述的那样。

然而他们的示例没有说明如何将ViewModel与Model链接起来。

传统上,我会先创建模型,然后创建一个或多个渲染它的视图。但是,MVVM似乎推动人们创建View,这样就会创建ViewModel,然后创建Model。我希望这不是真的,因为将复杂的业务模型与各种ModelView联系起来可能很困难。

您如何在MVVM中实例化业务模型类并将其与ViewModel链接起来?


我在http://marlongrech.wordpress.com/2008/03/20/more-than-just-mvc-for-wpf/上找到了一些关于这个问题的信息。解决方案是使用**中介者设计模式**,例如通过MVVM Foundation的Message来实现。这有助于解决ViewModel之间的通信问题。 - Wernight
5个回答

16

通常我将Model对象作为构造函数参数传递给VM。 我使用App类作为控制器,它将使用主模型初始化MainWindow、MainWindowViewModel。 然后,MainWindowViewModel负责使用相应的模型对象初始化其他VM。

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        mainWindow = new MainWindow();
        mainWindow.DataContext = new MainWindowViewModel(new Model());
        mainWindow.Show();
    }

6
您需要在ViewModel中创建BusinessModel类。 因此,在您的 CustomerViewModel 中,您将说 this.CurrentCustomer = new CustomerModel(),并且您的 CustomerView 将绑定到ViewModel上的CurrentCustomer属性。
如果您感兴趣,我写了一个使用MVVM的简单示例,作为View、Model和ViewModel之间交互的示例。

通常情况下,我看到它是这样工作的,但当您拥有由多个相互连接的类组成的模型并在后台执行某些操作时,这就变得非常困难了。然后,各种ModelView希望访问模型中的各种类。当然,可以塑造模型以支持此功能,但那样它就不会真正成为业务模型了。 - Wernight
1
@Wernight 模型不应该在后台执行任何操作。它们只是用来保存数据的虚拟容器。后台进程应该在 ViewModel 中运行。你的模型运行什么样的进程? - Rachel
@Rachel:在http://marlongrech.wordpress.com/2008/03/20/more-than-just-mvc-for-wpf/上的示例已经足够了。*Search*和*ProductList*应该显示所有项,因此需要查看相同的*ProductList*模型。这意味着ModelView不应直接创建模型。 - Wernight
@Wernight 你发布的链接并没有使用 MVVM,而是使用了 MVC,这两者不同。如果你想在 MVVM 中实现类似的 ViewModel 间通信,我建议你查看 MVVM Light 的 Messenger 或 Prism 的 EventAggregator - Rachel
@Rachel:当然可以。我只是把它作为解决方案的提示。我在某些 ViewModel 之间使用了这种方式进行通信。但对于应该在相互连接的模型中的业务逻辑,如果采用 MVVM,问题似乎没有简单的解决方案。 - Wernight
@Wernight 那种业务逻辑应该存在于ViewModels中。 - Rachel

2

我使用依赖注入/MEF来实现这一点。只需将所有模型类一直导出到链的底部,并在ViewModel构造函数中自动导入它们。


那么,你如何将模型的实例链接在一起? - Wernight

2
我会根据不同情况采取各种不同的方法。我发现,在将这些数据链接起来方面,没有一种通用的方法适用于所有情况。
对于简单的情况,我会让ViewModel和Model成为同一个东西。显然,并非所有情况都适用,但有时候没有必要去分离M和VM。 (在列表框中仅需要少量信息的情况下非常适用)
有时,特别是当模型是另一个开发人员编写的代码块时,可以很容易地对模型进行子类化,并将所有VM内容(observable属性等)添加到其中。
最后,我会使用Souvik提到的方法。使用要用作参数的模型信息构建VM,或以其他方式允许其被传递。这可能是我针对更大更复杂的模型/视图模型关系所采用的最常见方法。

0

我正在使用IoC容器自动将IRepository实例传递给VM构造函数,并且VM需要处理模型的所有操作都通过此存储库完成。存储库是一个类,用于创建、读取、更新和删除数据。当我需要显示某个视图(窗口)时,我使用IViewService.ShowDialog(viewModel As ViewModelBase)。在IViewService的实现中,已经注册了与VM关联的视图,因此VM只需要知道其他VM而不是它们的视图(例如“为此视图模型显示视图”)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接