我一直在查看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();
}
}
上面的技术对我来说似乎很合理,但看着样本我开始质疑这种方法。最好的方法是否有人有意见(没有双关语)?
答案 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