开发手册 欢迎您!
软件开发者资料库

MVVM - 连接ViewModel

MVVM连接ViewModel - 从简单和简单的步骤学习MVVM,从基本到高级概念,包括简介,优点,责任,第一个应用程序,连接视图,连接ViewModel,WPF数据绑定,WPF数据模板,View和ViewModel通信,层次结构和导航,验证,依赖注入,事件,单元测试,框架,面试问题。

在本章中,我们将介绍如何连接ViewModel.这是我们讨论View第一个结构的最后一章的延续.现在,第一种结构的下一种形式是元模式,它被称为 ViewModelLocator .它是一个伪模式,并且位于MVVM模式之上.

  • 在MVVM中,每个View都需要连接起来ViewModelLocator是一种集中代码和解耦视图的简单方法.

  • 这意味着它不必明确了解ViewModel类型以及如何构建它.

  • 有许多不同的方法使用ViewModelLocator,但在这里我们使用与PRISM框架中最相似的那个.

ViewModelLocator提供标准,一致的,声明性和松散耦合的方式来查看第一个构造,自动化ViewModel连接到View的过程.下图表示ViewModelLocator的高级过程.

挂钩ViewModel

第1步 : 找出正在构建的View类型.

第2步 : 确定特定视图类型的ViewModel.

第3步 : 构建ViewModel.

第4步 : 将Views DataContext设置为ViewModel.

要理解基本概念,让我们通过继续上一章中的相同示例来查看ViewModelLocator的简单示例.如果查看StudentView.xaml文件,您将看到我们已静态连接ViewModel.

现在,如下面的程序所示,注释这些XAML代码也会删除代码代码隐藏.

                                                                                                                                                                                                            

现在让我们创建一个新的文件夹VML并添加一个新的公共类ViewModelLocator,它将包含一个附加属性(依赖属性)AutoHookedUpViewModel,如下面的代码所示.

public static bool GetAutoHookedUpViewModel(DependencyObject obj) {    return (bool)obj.GetValue(AutoHookedUpViewModelProperty); }public static void SetAutoHookedUpViewModel(DependencyObject obj, bool value) {    obj.SetValue(AutoHookedUpViewModelProperty, value); }// Using a DependencyProperty as the backing store for AutoHookedUpViewModel. //This enables animation, styling, binding, etc... public static readonly DependencyProperty AutoHookedUpViewModelProperty =   DependencyProperty.RegisterAttached("AutoHookedUpViewModel",   typeof(bool), typeof(ViewModelLocator), new PropertyMetadata(false,   AutoHookedUpViewModelChanged));

现在你可以看到一个基本的附件属性定义.要向属性添加行为,我们需要为此属性添加更改的事件处理程序,其中包含连接ViewModel for View的自动过程.执行此操作的代码如下 :

private static void AutoHookedUpViewModelChanged(DependencyObject d,    DependencyPropertyChangedEventArgs e) {    if (DesignerProperties.GetIsInDesignMode(d)) return;    var viewType = d.GetType();    string str = viewType.FullName;    str = str.Replace(".Views.", ".ViewModel.");    var viewTypeName = str;    var viewModelTypeName = viewTypeName + "Model";    var viewModelType = Type.GetType(viewModelTypeName);    var viewModel = Activator.CreateInstance(viewModelType);   ((FrameworkElement)d).DataContext = viewModel;  }

以下是ViewModelLocator类的完整实现.

using System; using System.ComponentModel; using System.Windows;namespace MVVMDemo.VML {    public static class ViewModelLocator {       public static bool GetAutoHookedUpViewModel(DependencyObject obj) {         return (bool)obj.GetValue(AutoHookedUpViewModelProperty);       }      public static void SetAutoHookedUpViewModel(DependencyObject obj, bool value) {          obj.SetValue(AutoHookedUpViewModelProperty, value);       }      // Using a DependencyProperty as the backing store for AutoHookedUpViewModel.       //This enables animation, styling, binding, etc...      public static readonly DependencyProperty AutoHookedUpViewModelProperty =         DependencyProperty.RegisterAttached("AutoHookedUpViewModel",          typeof(bool), typeof(ViewModelLocator), new         PropertyMetadata(false, AutoHookedUpViewModelChanged));      private static void AutoHookedUpViewModelChanged(DependencyObject d,         DependencyPropertyChangedEventArgs e) {          if (DesignerProperties.GetIsInDesignMode(d)) return;          var viewType = d.GetType();          string str = viewType.FullName;          str = str.Replace(".Views.", ".ViewModel.");          var viewTypeName = str;          var viewModelTypeName = viewTypeName + "Model";         var viewModelType = Type.GetType(viewModelTypeName);          var viewModel = Activator.CreateInstance(viewModelType);        ((FrameworkElement)d).DataContext = viewModel;       }    }  }

首先要做的是添加命名空间,以便我们可以访问ViewModelLocator输入我们项目的根目录.然后在作为视图类型的route元素上,添加AutoHookedUpViewModel属性并将其设置为true.

xmlns:vml = "clr-namespace:MVVMDemo.VML"vml:ViewModelLocator.AutoHookedUpViewModel = "True"

以下是StudentView.xaml文件的完整实现.

                                                                                                                                                                                                                

编译并执行上述代码时,您将看到ViewModelLocator正在连接该特定View的ViewModel.

挂钩ViewModel主窗口

要注意的一个关键是视图不再耦合一种方式,了解ViewModel的类型或构造方式.这一切都被移到了ViewModelLocator内部的中心位置.