我一直在阅读各种来源的MVVM模式,如MSDN:
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
在那篇文章中它说:与MVP中的Presenter不同,ViewModel不需要对视图的引用。
如果View(XAML)假定它的DataContext是ViewModel,那么代码中的位置是以下行:
view.DataContext = viewModel;
ViewModel对视图一无所知,因此无法设置datacontext。如果我给ViewModel提供参考,我是否打破了MVVM模式?我的另一个选择是拥有某种类型的Builder或额外的Presenter,其唯一的工作就是连接整个事物(等待View的加载事件,设置DataContext)。
我知道不同的视图可以共享相同的DataContext(例如,只为主窗口设置DataContext,其他人会看到它),但在许多情况下根本不可能,甚至不可行。
答案 0 :(得分:6)
这个问题有很多答案。这一切都取决于您希望如何构建您的应用程序。例如,我使用依赖注入来创建我的IViewModel,然后创建我的IView,我的IViewModel在构造函数上运行IView.SetViewModel(this)。
其他人可能希望通过在Xaml中设置DataContext来使用更多Blendable方法:
<UserControl.DataContext>
<ns:CrazyViewModel />
</UserControl.DataContext>
有时可以隐含DataContext,因此它由框架设置,就像在ItemsControl使用的DataTemplate实例中一样。这在桌面WPF中也很常见,因为它支持类型化的DataTemplates。
因此,设置DataContext确实没有错误的方法,只要您分离关注点,可维护且易于测试。
答案 1 :(得分:3)
Shawn Wildermuth关于View或ViewModel是否排在第一位的帖子很棒: http://wildermuth.com/2009/05/22/Which_came_first_the_View_or_the_Model
我喜欢并使用他的婚姻概念,其中第三方类创建视图和视图模型,然后将两者联系起来。它对我有用。
答案 2 :(得分:0)
我在Prism中使用MVVM很多。在棱镜中,我使用Unity进行依赖注射。因此,我为Unity注册的每个类都有一个界面,包括View。 IView接口有一个这样的方法:
void SetViewModel(object viewModel);
ViewModel在其构造函数的末尾调用此方法,将其自身作为参数传递:
public ViewModel(IView view, ...)
{
...
this._view=view;
this._view.SetViewModel(this);
}
在View.xaml.cs中实现了IView接口。这将是我添加到视图代码隐藏的唯一代码:
public partial class View:UserControl, IView
{
public View()
{
...
}
public SetViewModel(object viewModel)
{
this.DataContext = viewModel;
}
}
答案 3 :(得分:0)
至于我自己的用法,ViewModel不知道View或View上的任何界面。大多数时候,View不知道它的ViewModel,即使它不那么重要。虚拟机只是由DataContext传输。
这可确保VM和V保持高度独立性。链接是通过绑定,命令,行为,触发器和放大器建立的。等等。即使VM通常与给定视图高度相关,我也尽量使其尽可能通用,以便我可以切换相应的View,和/或调整View行为而无需更新VM,除非架构链接V和M之间受到影响!