MVVM - View应该引用Presenter / ViewModel吗?

时间:2009-09-16 08:47:42

标签: mvvm prism mvp

我一直在查看PRISM 2示例,了解如何最好地处理我正在处理的新应用程序,这将是一个PRISM 2 / WPF应用程序。特别关注PRISM附带的View Injection示例应用程序我注意到所有视图都实现了一个接口,允许演示者(或ViewModel)与View进行交互。

过去我以相反的方式完成了这个,我将演示者注入到视图中,以便视图可以直接调用演示者上的方法,如下所示:

    public partial class SomeView : ModuleBase
    {

        private ISomePresenter _somePresenter;

        public SomeView (ISomePresenter somePresenter):this()
        {
            // Give the view a reference to the presenter
            _somePresenter = somePresenter;
            // Bind the View to the presenter
            DataContext = _somePresenter;
        }

    private void btnSubmit_Click(object sender, RoutedEventArgs e)
    {
        // The view can call actions directly on the presenter (OK I should probably use a command for this)
        _somePresenter.SomeAction();
    }
}

上面的技术对我来说似乎很合理,但看着样本我开始质疑这种方法。最好的方法是否有人有意见(没有双关语)?

  • 将演示者添加到视图中并获取视图以与演示者进行交互
  • 将视图添加到演示者并让演示者与视图进行交互
  • 我还没有想到的完全不同的东西?

2 个答案:

答案 0 :(得分:5)

将ViewModel映射到MVVM中的View的最常用方法是使用DataTemplate

<DataTemplate DataType="{x:Type vm:SomeViewModel}">
    <v:SomeView />
</DataTemplate>

当您在ContentControl或ItemsControl中显示ViewModel实例时,WPF将自动为ViewModel实例化相应的View,并将View的DataContext设置为ViewModel实例。

这样,您在ViewModel中没有对View的任何引用,View只通过DataContext属性引用ViewModel。如果您真的需要在View的代码隐藏中访问ViewModel,您总是可以转换DataContext(但这意味着View知道ViewModel的实际类型,这会导致耦合)

答案 1 :(得分:2)

我认为这都是品味问题。就个人而言,我喜欢你在看的样品中看到它的方式。 IView有一个方法,即SetViewModel(...)。 IViewModel有一个名为View of Object的属性,它基本上返回DI实例化的IView。

我喜欢这种方式的原因是我几乎总是想首先创建一个ViewModel,我希望代码中的 nobody 能够对我的IView做任何事情,除了获取对实例的引用(对于视图注入或绑定视图来说一个ContentControl),这就是它的类型对象的原因。如果任何代码需要与View交谈,对我而言,它始终通过VM ...即使这样,视图通常也会通过绑定进行更新。从View-&gt; ViewModel-&gt; UpdateBinding-&gt; View看起来比现在感觉奇怪,VM-&gt; UpdateBinding-&gt; View

要回答这个问题,我通常不需要在代码隐藏中引用演示者。通常我可以使用绑定到VM的视图中的命令来处理它。 在某些情况下,您可能希望继续引用演示者来执行示例中的操作,但是在给定正确的工具集的情况下可以避免(使SL更难以使其没有内置命令)。

就像我说的那样,这都是品味问题......

-Jer