【问题标题】:Who sets DataContext in Silverlight MVVM谁在 Silverlight MVVM 中设置 DataContext
【发布时间】:2010-11-24 18:05:45
【问题描述】:

我一直在从 MSDN 等各种来源阅读有关 MVVM 模式的信息:

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

在那篇文章中说:与 MVP 中的 Presenter 不同,ViewModel 不需要对视图的引用

如果视图 (XAML) 假定它的 DataContext 是 ViewModel,那么代码中的以下行是:

view.DataContext = viewModel;

ViewModel 对视图一无所知,因此无法设置数据上下文。如果我给 ViewModel 提供参考,我会打破 MVVM 模式吗?我的另一个选择是拥有某种 Builder 或额外的 Presenter,它们唯一的工作就是连接整个事物(等待 View 的加载事件,设置 DataContext)。

我知道不同的视图可以共享相同的 DataContext(例如,仅为主窗口设置 DataContext,其他人会看到它),但在许多情况下,这根本不可能,甚至不可行。

【问题讨论】:

    标签: silverlight mvvm


    【解决方案1】:

    这是一个很好的问题,有很多答案。这完全取决于您希望如何构建应用程序。例如,我使用依赖注入来创建我的 IViewModel,它反过来创建我的 IView,而我的 IViewModel 在构造函数上运行一个 IView.SetViewModel(this)。

    其他人可能希望通过在 Xaml 中设置 DataContext 来使用更可混合的方法:

    <UserControl.DataContext>
        <ns:CrazyViewModel />
    </UserControl.DataContext>
    

    有时 DataContext 可以是隐含的,因此它是由框架设置的,例如在 ItemsControl 使用的 DataTemplate 实例中。这在桌面 WPF 中也很常见,因为它支持类型化的 DataTemplates。

    因此,设置 DataContext 的方法确实没有错误,只要您将关注点分开、可维护且易于测试。

    【讨论】:

      【解决方案2】:

      Shawn Wildermuth 有一篇关于 View 还是 ViewModel 优先的文章很棒: http://wildermuth.com/2009/05/22/Which_came_first_the_View_or_the_Model

      我喜欢并使用他的婚姻概念,即第 3 方类创建视图和视图模型,然后将两者关联起来。对我来说效果很好。

      【讨论】:

        【解决方案3】:

        我在 Prism 中经常使用 MVVM。在 Prism 中,我使用 Unity 进行依赖注入。因此,我为使用 Unity 注册的每个类(包括视图)都有一个接口。 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;
           }
        
        }
        

        【讨论】:

          【解决方案4】:

          至于我自己的使用,ViewModel不知道View,也不知道View上的任何接口。大多数时候,View 并不知道它的 ViewModel,即使它不那么重要。 VM 只是由 DataContext 传输。

          这可确保 VM 和 V 保持高度独立。通过绑定、命令、行为、触发器等建立链接。即使 VM 通常与给定视图高度相关,我也会尽量使其通用,以便我可以切换相应的视图,和/或调整视图行为而无需更新 VM,除非架构链接V 和 M 之间受到影响!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-07-02
            • 1970-01-01
            • 2015-08-21
            • 2010-10-11
            • 1970-01-01
            • 2023-03-27
            • 2010-09-27
            相关资源
            最近更新 更多