谁在S​​ilverlight MVVM中设置了DataContext

时间:2009-09-01 19:29:10

标签: silverlight mvvm

我一直在阅读各种来源的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,其他人会看到它),但在许多情况下根本不可能,甚至不可行。

4 个答案:

答案 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之间受到影响!