谁在Silverlight MVVM中设置DataContext

9

我一直在各个来源,如MSDN上阅读有关MVVM模式的内容:

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

在那篇文章中,它说:与MVP中的Presenter不同,ViewModel不需要引用视图
如果视图(XAML)假定它的DataContext是ViewModel,那么在代码中以下一行位于何处:
view.DataContext = viewModel;

ViewModel并不知道视图,因此无法设置数据上下文。如果我将引用传递给ViewModel,是否会破坏MVVM模式?我的另一个选择是拥有某种构建器或额外的Presenter,其唯一的工作是连接整个过程(等待View的加载事件,设置DataContext)。
我知道不同的视图可以共享相同的DataContext(例如仅为主窗口设置DataContext,其他人将看到它),但在许多情况下,这根本不可能甚至不可行。
4个回答

6
这是一个非常好的问题,有很多答案。这完全取决于您如何设计应用程序架构。例如,我使用依赖注入来创建我的IViewModel,然后IViewModel又创建我的IView,并在构造函数中运行IView.SetViewModel(this)。
其他人可能希望使用更可混合的方法,在Xaml中设置DataContext:
<UserControl.DataContext>
    <ns:CrazyViewModel />
</UserControl.DataContext>

有时候,DataContext 可能会被隐含设置,比如在 ItemsControl 使用 DataTemplate 的情况下,其由框架自动设置。这在桌面 WPF 中也很常见,因为它支持带类型的 DataTemplate。
所以实际上没有一种错误的设置 DataContext 的方式,只要你将关注点分离、易于维护和易于测试即可。

3

0
对于我的使用,ViewModel 不知道 View,也不知道 View 上的任何接口。而且大部分时间,View 也不知道它的 ViewModel,即使它不那么重要。VM 只是通过 DataContext 进行传递。
这样确保了 VM 和 V 之间的高度独立性。通过绑定、命令、行为、触发器等方式建立链接。即使 VM 往往与给定的视图高度相关,我尽量使其尽可能通用,以便可以切换对应的视图,并且/或者调整视图行为,而无需更新 VM,除非 V 和 M 之间的架构链接受到影响!

0
我在使用Prism时经常使用MVVM。在Prism中,我使用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;
   }

}

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