【问题标题】:Hooking up the ViewModel to the View in Silverlight将 ViewModel 连接到 Silverlight 中的视图
【发布时间】:2009-06-11 17:26:53
【问题描述】:

我可以看到两种将 ViewModel 连接到 View 的方法。一个在 XAML 中,另一个通过依赖注入在后面的代码中。

哪种方法更可取?我更喜欢 xaml 方法,因为我根本不想要后面的代码中的任何代码,但是两者之间有什么问题吗?

<navigation:Page x:Class="MyNamespace.MyViewModel" 
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:ViewModel="clr-namespace:MyNameSpace.MyViewModel"
   xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
   Title="ViewModel Page" >

    <navigation:Page.Resources>
        <ViewModel:MyViewModel x:Key="ViewModel"></ViewModel:MyViewModel>
    </navigation:Page.Resources>

    <Grid x:Name="LayoutRoot" Background="White" 
          DataContext="{StaticResource ViewModel}">

    </Grid>
</navigation:Page>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;

namespace MyNamespace
{
    public partial class MyView : Page
    {
        public MyView()
        {
            InitializeComponent(MyViewModel viewModel);

            this.DataContext = viewModel;
        }
    }
}

【问题讨论】:

    标签: c# silverlight mvvm


    【解决方案1】:

    我使用了一个我称之为“屏幕”的类来处理 MVVM 三元组。我开始时将 V 注入到 VM 中,然后将 VM 作为 V 中的资源,但最终 Screen 概念对我来说效果最好。它允许我使用 V 和 VM 而无需相互耦合。它还抽象出我的整个演示框架中的其他功能。下面以我的 Screen 类的构造函数为例:

        public CatalogItemScreen(IUnityContainer container) : base(container)
        {
            this.ViewModel = Container.Resolve<ICatalogItemViewModel>();
            this.View = Container.Resolve<CatalogItemView>();
            this.View.DataContext = this.ViewModel;
        }
    

    注意VM是在Screen中创建的,V是在这里创建的,2是相互绑定的。此示例使用 Unity 和 Prism,但没有必要实现这一点。

    【讨论】:

      【解决方案2】:

      Shawn 首先在View or ViewModel 上发了一篇好帖子。在 XAML 中拥有 VM 可以为您提供 Blendability(在 Blend 中查看示例数据),这很酷,但代价是必须将信息推送回视图。出于这个原因,John Papa 已经放弃了这种方法。

      我正在使用肖恩的婚姻理念(见上面的链接)。

      HTH -埃里克

      【讨论】:

      • 嗯.. 感谢您的链接。我现在正在读它。我想我需要再读几遍,因为我没有得到任何东西。肖恩说:“在这两种方法中,我倾向于不喜欢视图对视图模型的粘性。而且,这两种方法都暗示着一对一的关系,虽然这是常见的情况,但并非总是如此。”但是使用 View-First,可以将许多视图数据绑定到一个 VM。一个视图可以绑定到多个虚拟机吗?嗯.. 再次,我想如果你的 V 是一个简单的网格,可能希望将它绑定到不同的虚拟机。
      • 到目前为止,我很喜欢在 Vs 和 VM 之间保持一对一的关系。这并不意味着我反对等级制度。也就是说,一个视图可能包含子视图,每个子视图都有自己的虚拟机,这似乎工作得很好。
      • 在我们的应用程序中,我们有一个标准网格视图,它只显示数据行。这些数据可能来自不同的 ViewModel,因此一对一地保存对我们来说没有意义。当多个网格视图除了它包含的数据之外,它们都相同时,没有意义。
      • 附言。我真的很喜欢你的视频。继续加油!
      • 我明白了。我以为您指的是同时绑定到多个虚拟机的视图...大声笑。谢谢!
      【解决方案3】:

      按照您在此处的方式,我将使用 XAML。还有其他方法可以设置为 DataContext 属性。如果您有兴趣,请查看适用于 WPF 的 Microsoft CAG 框架。

      【讨论】:

        【解决方案4】:

        我已经在代码中设置了 VM,因为这使得 View 的测试变得更加容易。 Justin Angel 对此有一篇很棒的帖子:

        public partial class Page : UserControl
        {
            private PageViewModel _viewModel = new PageViewModel();
        
            public PageViewModel ViewModel
            {
                get { return _viewModel; }
                set { _viewModel = value; }
            } 
        
            public Page()
            {
                InitializeComponent();
                this.Loaded += new RoutedEventHandler(Page_Loaded);
            }
        
            void Page_Loaded(object sender, RoutedEventArgs e)
            {
                this.DataContext = ViewModel;
            }
        
        }
        

        我发现他的帖子对于了解围绕 MVVM 模式进行测试的复杂性非常有用。

        http://silverlight.net/blogs/justinangel/archive/2009/02/25/silverlight-unit-testing-rhinomocks-unity-and-resharper.aspx

        【讨论】:

        • 感谢您的链接。我现在还在读,但我现在更喜欢肖恩的方法。我需要花更多的时间来考虑它,但我想要一个明确解耦的 VM 和 V。
        猜你喜欢
        • 1970-01-01
        • 2011-10-02
        • 2023-03-27
        • 1970-01-01
        • 2013-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多