MVVMLight项目Model View结构及全局视图模型注入器

目录
  • 一、先来说说分层结构:
    • 1、写一个Model,代码如下:
    • 2、写一个VideModel,来负责跟View的交互。
    • 3、写一个View,来显示和交互ViewModel。
  • 二、再来说说构造器:

MVVM和MVVMLight框架介绍及在项目中的使用详解

上一篇我们已经介绍了如何使用NuGet把MVVMLight应用到我们的WPF项目中。这篇我们来了解下一个基本的MVVMLight框架所必须的结构和运行模式。

MVVMLight安装之后,我们可以看到简易的框架布局,如上篇,生成了一个ViewModel文件夹,ViewModel层的内容都放在这边,除了Main对象的ViewModel之外,还包含一个ViewModelLocator文件,

用来注入当前的ViewModel全局实例。

一、先来说说分层结构:

如图:

1、View负责前端展示,与ViewModel进行数据和命令的交互。

2、ViewModel,负责前端视图业务级别的逻辑结构组织,并将其反馈给前端。

3、Model,主要负责数据实体的结构处理,与ViewModel进行交互。

根据上述的分层,我们来进行编码。

先建立一个完整三层结构的目录,如图,包含Model、View、ViewModel三层文件夹:

1、写一个Model,代码如下:

 using GalaSoft.MvvmLight;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 namespace MVVMLightDemo.Model
 {
     public class WelcomeModel : ObservableObject
     {
         private String introduction;
         /// <summary>
         /// 欢迎词
         /// </summary>
         public String Introduction
         {
             get { return introduction; }
             set { introduction = value; RaisePropertyChanged(()=>Introduction); }
         }
     }
 

很简单,仅仅是包含一个实体对象,这边注意的的是那他继承了一个父类:ObservableObject,这个父类的作用就是保证能够检测属性是否被改变。

它实现了INotifyPropertyChanged接口,通过触发PropertyChanged事件达到通知UI更改的目的;

所以我们在定义实体对象的时候,只需要调用RaisePropertyChanged(PropertyName)就可以进行属性更改通知了。

所以实体里面定义的每个属性都加上RaisePropertyChanged(PropertyName)的调用,就可以实现对UI的交互更新了。

2、写一个VideModel,来负责跟View的交互。

using GalaSoft.MvvmLight;
using MVVMLightDemo.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MVVMLightDemo.ViewModel
{
    public class WelcomeViewModel:ViewModelBase
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public WelcomeViewModel()
        {
            Welcome = new WelcomeModel() { Introduction = "Hello World!" };
        }
        #region 属性

        private WelcomeModel welcome;
        /// <summary>
        /// 欢迎词属性
        /// </summary>
        public WelcomeModel Welcome
        {
            get { return welcome; }
            set { welcome = value; RaisePropertyChanged(()=>Welcome); }
        }
        #endregion
    }
}

也很简单,包含了一个命名为Welcome的WelcomeModel属性,继承了ViewBaseModel父类,

ViewBaseModel同时继承 ObservableObject类和ICleanup接口。所以他同样有INotifyPropertyChanged接口的能力,

能够通过触发PropertyChanged事件达到通知View的目的;

构造函数中对 Welcome 属性进行了实例化。

3、写一个View,来显示和交互ViewModel。

<Window x:Class="MVVMLightDemo.View.WelcomeView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Title="WelcomeView" Height="300" Width="300">
     <Grid>
         <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" >
             <TextBlock Text="{Binding Welcome.Introduction}" FontSize="30" ></TextBlock>
         </StackPanel>
     </Grid>
 </Window>

TextBlock 绑定了 Welcome.Introduction,所以应该显示Welcome对象下的Introduction属性。

这时候的ViewModel和View是没有任何关系的,所以我们在code-Behind的构造函数中写上如下代码:

using MVVMLightDemo.ViewModel;
using System.Windows;
 namespace MVVMLightDemo.View
 {
     /// <summary>
     /// Interaction logic for WelcomeView.xaml
     /// </summary>
     public partial class WelcomeView : Window
     {
         public WelcomeView()
         {
             InitializeComponent();
             this.DataContext = new WelcomeViewModel();
         }
     }

把 WelcomeViewModel 赋值给当前视图的数据上下文。所以可以在当前视图中使用ViewModel中所有的公开属性和命令。

执行效果如下:

二、再来说说构造器:

如果使用NuGet安装的是完整的一个是MVVM Light 框架,而非 MVVM Light libraries only的时候,总是会带上ViewModelLocator类,并且生成资源字典并加入到了全局资源中。

<Application x:Class="MVVMLightDemo.App"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              StartupUri="View/WelcomeView.xaml"
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              d1p1:Ignorable="d"
              xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006"
              xmlns:vm="clr-namespace:MVVMLightDemo.ViewModel" >
   <Application.Resources>
     <ResourceDictionary>
             <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
     </ResourceDictionary>
   </Application.Resources>
 </Application>

所以每次App初始化的时候,就会去初始化ViewModelLocator类。

实际上他就是一个很基本的视图模型注入器。在构造器中把使用到的ViewModel统一注册,并生成单一实例。

然后使用属性把它暴露出来,每当我们访问属性的时候,就会返回相应的ViewModel实例。

/*
   In App.xaml:
   <Application.Resources>
       <vm:ViewModelLocator xmlns:vm="clr-namespace:MVVMLightDemo"
                            x:Key="Locator" />
   </Application.Resources>

   In the View:
   DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"

   You can also use Blend to do all this with the tool's support.
   See http://www.galasoft.ch/mvvm
 */
 using GalaSoft.MvvmLight;
 using GalaSoft.MvvmLight.Ioc;
 using Microsoft.Practices.ServiceLocation;
 namespace MVVMLightDemo.ViewModel
 {
     /// <summary>
     /// This class contains static references to all the view models in the
     /// application and provides an entry point for the bindings.
     /// </summary>
     public class ViewModelLocator
     {
         /// <summary>
         /// Initializes a new instance of the ViewModelLocator class.
         /// </summary>
         public ViewModelLocator()
         {
             ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
             #region Code Example
             ////if (ViewModelBase.IsInDesignModeStatic)
             ////{
             ////    // Create design time view services and models
             ////    SimpleIoc.Default.Register<IDataService, DesignDataService>();
             ////}
             ////else
             ////{
             ////    // Create run time view services and models
             ////    SimpleIoc.Default.Register<IDataService, DataService>();
             ////}
             #endregion
             SimpleIoc.Default.Register<MainViewModel>();
         }
         #region 实例化
         public MainViewModel Main
         {
             get
             {
                 return ServiceLocator.Current.GetInstance<MainViewModel>();
             }
         }
         #endregion
         public static void Cleanup()
         {
             // TODO Clear the ViewModels
         }
     }
 

注意的是,这边把MVVMLight 自带的SimpleIoc作为默认的服务提供者,它是个简易的注入框架。

为了统一化,并且在设计的时候可以看到看到ViewModel的数据,这边用ServiceLocator 又将SimpleIoc包裹了一层。

上面我们写了一个Hello World,这时候就可以用这种方式改装了。

/*
   In App.xaml:
   <Application.Resources>
       <vm:ViewModelLocator xmlns:vm="clr-namespace:MVVMLightDemo"
                            x:Key="Locator" />
   </Application.Resources>
   In the View:
   DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"

   You can also use Blend to do all this with the tool's support.
   See http://www.galasoft.ch/mvvm
 */
 using GalaSoft.MvvmLight;
 using GalaSoft.MvvmLight.Ioc;
 using Microsoft.Practices.ServiceLocation;
 namespace MVVMLightDemo.ViewModel
 {
     /// <summary>
     /// This class contains static references to all the view models in the
     /// application and provides an entry point for the bindings.
     /// </summary>
     public class ViewModelLocator
     {
         /// <summary>
         /// Initializes a new instance of the ViewModelLocator class.
         /// </summary>
         public ViewModelLocator()
         {
             ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
             #region Code Example
             ////if (ViewModelBase.IsInDesignModeStatic)
             ////{
             ////    // Create design time view services and models
             ////    SimpleIoc.Default.Register<IDataService, DesignDataService>();
             ////}
             ////else
             ////{
             ////    // Create run time view services and models
             ////    SimpleIoc.Default.Register<IDataService, DataService>();
             ////}
             #endregion
             SimpleIoc.Default.Register<MainViewModel>();
             SimpleIoc.Default.Register<WelcomeViewModel>();
         }
         #region 实例化
         public MainViewModel Main
         {
             get
             {
                 return ServiceLocator.Current.GetInstance<MainViewModel>();
             }
         }
         public WelcomeViewModel Welcome
         {
             get
             {
                return ServiceLocator.Current.GetInstance<WelcomeViewModel>();
             }
         }
         #endregion
         public static void Cleanup()
         {
             // TODO Clear the ViewModels
         }
     }
 

注册完WelcomeViewModel实例之后,我们就可以在相应的View中使用了 ,原本的

 public WelcomeView()
 {
         InitializeComponent();
         this.DataContext = new WelcomeViewModel();
 }

中的 this.DataContext = new WelcomeViewModel();

可以去掉了,直接在WelcomeView中这样写:

DataContext="{Binding Source={StaticResource Locator},Path=Welcome}"

如下图:

这样做的好处,一个是绑定化相对于简单粗暴的赋值方式,更合理。一个是在可视化窗口可以看到所绑定的数据,达到所见即所得的友好效果。

如下:

当我们改掉绑定到的数据,编译之后就会立马呈现:

服务端开发人员可以专心写ViewModel的业务逻辑代码,UI开发人员可以专注设计视图了,

同样 ViewModel可以绑定到不同的视图上,所以从这边就可以体现出他其中的三个重要特性:低耦合、可重用性、独立开发。

大家有没有发现ViewModelLocator 类中还有个 ClearnUp()方法,主要目的用来清除ViewModel实例的。

ViewModelBase继承了GalaSoft.MvvmLight.ICleanup接口,并在自己的类中写好了Cleanup()虚方法。所以我们在实例ViewModel类中可以重写Cleanup()来达到清除当前实例的目的。

以上就是MVVMLight 之Model View结构及全局视图模型注入器的详细内容,更多关于ViewModel 结构及全局视图模型注入器的资料请关注我们其它相关文章!

(0)

相关推荐

  • Android ViewModel的使用总结

    目录 基本使用 MainRepository MainViewModel MainActivity ViewModel 相关问题是高频面试题.主要源于它是 MVVM 架构模式的重要组件,并且它可以在因配置更改导致页面销毁重建时依然保留 ViewModel 实例. 看看 ViewModel 的生命周期 ViewModel 只有在正常 Activity finish 时才会被清除. 问题来了: 为什么Activity旋转屏幕后ViewModel可以恢复数据 ViewModel 的实例缓存到哪儿了 什

  • 详解Android框架MVVM分析以及使用

    Android MVVM 分析以及使用 首先我们需要知道什么是MVVM,他的功能和优点,以及他的缺点. MVVM是Model-View-ViewModel的简写.它本质上就是MVC 的改进版.MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开.当然这些事 ViewModel 已经帮我们做了,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑.微软的WPF带来了新的技术体验,如Silverlight.音频.视频.3D.动画-

  • Android通过ViewModel保存数据实现多页面的数据共享功能

    通过ViewModel实现的数据共享符合Android的MVC设计模式,将数据独立出来 实现的Demo 1.主页面通过SeekBar 来改变数字的值 2.点击进入就进入第二个界面,但是数据还是共享的 3.随便加两个数字上去,再次切换 4.发现数据还是共享的 下面是具体实现步骤: 1.建立两个Fragment(使用了Binding 和 Navigation) 一点要添加Binding 和 Navigation 不然做不了 2.建立一个继承于ViewModel的类 3.分别在两个Fragment的代

  • Android Jetpack架构组件 ViewModel详解

    前言 前面两篇文章我们已经学习了Lifecycle和DataBind,本篇文章我们来学习Jetpack系列中比较重要的ViewModel,Jetpack的很多很多组件都是搭配使用的,所以单独的知识点可能会有些"无意义"但却是我们项目实战的基础! ViewModel的使用 ViewModel类旨在以注重生命周期的方式存储和管理界面相关的数据.ViewModel类让数据可在发生屏幕旋转等配置更改后继续存在.这句话很好理解,还记得我们在讲解Lifecycle的时候 举的例子吗,我们还是使用那

  • MVVMLight项目Model View结构及全局视图模型注入器

    目录 一.先来说说分层结构: 1.写一个Model,代码如下: 2.写一个VideModel,来负责跟View的交互. 3.写一个View,来显示和交互ViewModel. 二.再来说说构造器: MVVM和MVVMLight框架介绍及在项目中的使用详解 上一篇我们已经介绍了如何使用NuGet把MVVMLight应用到我们的WPF项目中.这篇我们来了解下一个基本的MVVMLight框架所必须的结构和运行模式. MVVMLight安装之后,我们可以看到简易的框架布局,如上篇,生成了一个ViewMod

  • MVVMLight项目之双向数据绑定

    目录 第一步:先写一个Model,里面包含我们需要的数据信息 第二步:写一个ViewModel 第三步:在ViewModelLocator中注册我们写好的ViewModel: 第四步:编写View(注意标红的代码) MVVM和MVVMLight框架介绍及在项目中的使用详解 MVVMLight项目Model View结构及全局视图模型注入器 前篇我们已经了解了MVVM的框架结构和运行原理.这里我们来看一下伟大的双向数据绑定. 说到双向绑定,大家比较熟悉的应该就是AngularJS了,几乎所有的An

  • MVVMLight项目之绑定在表单验证上的应用示例分析

    目录 常见的表单验证机制有如下几种: 验证交互的关系模式如图: 下面详细描述下这三种验证模式 1.Exception 验证: 2.ValidationRule 验证: 3.IDataErrorInfo 验证: 表单验证是MVVM体系中的重要一块.而绑定除了推动 Model-View-ViewModel (MVVM) 模式松散耦合 逻辑.数据 和 UI定义 的关系之外,还为业务数据验证方案提供强大而灵活的支持. WPF 中的数据绑定机制包括多个选项,可用于在创建可编辑视图时校验输入数据的有效性.

  • MVVMLight项目的绑定及各种使用场景示例分析

    目录 一.绑定: 1.元素绑定: 2.非元素类型绑定: 2.1 Source属性: 2.2 RelativeSource 属性: 2.3 DataContext 属性: 二.绑定的各种使用场景: 1.下拉框: 2.单选框 3.组合单选框 4.复选框,复选框与单选框的使用情况类似: 5.树形控件 6.ListBox 7.用户控件的集合绑定: 一.绑定: 主要包含元素绑定和非元素绑定两种. 1.元素绑定: 是绑定的最简单形式,源对象是WPF的元素,并且源对象的属性是依赖项属性. 根据我们之前的知识

  • 浅析Android系统的架构以及程序项目的目录结构

    Android框架结构 直接上图: 由上图,我们可以看出Android系统架构由5部分组成, 分别是:Linux Kernel(linux内核).Android Runtime(运行时环境).Libraries(类库).Application Framework(应用框架).Applications(应用). 1.1.Linux Kernel Android基于Linux 2.6提供核心系统服务,例如:安全.内存管理.进程管理.网络堆栈.驱动模型.Linux Kernel也作为硬件和软件之间的抽

  • 使用SpringBoot中web项目推荐目录结构的问题

    目录 下面是我创建的目录结构 项目结构 静态资源的目录结构 完整项目结构 SpingBoot 365计划开始更新了,计划手敲365个dSpringBoot案例回顾总结形成知识体系.目前已经输出了32节的内容.所有源码托管在GitHub和Gitee上. 下面是我创建的目录结构 . ├── ./pom.xml └── ./src ├── ./src/main │ ├── ./src/main/java │ │ └── ./src/main/java/com │ │ └── ./src/main/ja

  • QT委托代理机制之Model View Delegate使用方法详解

    目录 本地数据加载(Data) 添加数据模型(Model) 添加代理模型(Proxy) 添加元素的代理(Delegate) 添加视图层(View) 使用效果 之前的一篇文章中介绍过QT的委托代理机制,那时候由于理解的比较浅就简单的给了一个例子.最近又做了一部分相关的工作,发现之前的理解有点问题.这里就详细的介绍一下QT的委托代理机制的用法,希望对大家有帮助. Model-View-Delegate机制可以简单的理解为将本地的一些数据以特定的UI形式呈现出来.常见的数据结构包括列表数据(list)

  • 基于vue-cli创建的项目的目录结构及说明介绍

    一. ├── build // 项目构建(webpack)相关代码 记忆:(够贱) 9个 │ ├── build.js // 生产环境构建代码 │ ├── check-versions.js // 检查node&npm等版本 │ ├── dev-client.js // 热加载相关 │ ├── dev-server.js // 构建本地服务器 │ ├── utils.js // 构建配置公用工具 │ ├── vue-loader.conf.js // vue加载器 │ ├── webpack.b

  • Java项目的目录结构详解

    一个java web项目 目录分为两个部分 ① Web应用的根目录下子目录WEB-INF,里面内容不能被客户端访问的,包括专用Web应用程序软件,包括Servlet类文件.部署描述符web.xml.外部库以及其他任何由此应用程序使用的专用文件. ② 所有位于WEB-INF之外的文件都被看作是公共的,客户端是可以访问到的.资源包括HTML页面.JSP页面和图像等. 一.Common包 Common用来封装一些常用的公共方法. 二.Dao包 Dao主要用来封装对数据库的新增,删除,查询,修改.叫做数

  • thinkphp 3.2框架视图模型 实例视图查询结果的二维数组合并操作示例

    本文实例讲述了thinkphp 3.2框架视图模型 实例视图查询结果的二维数组合并操作.分享给大家供大家参考,具体如下: 使用视图模型查询的时候 结果是这样的 array(6) { [0] => array(5) { ["picTitle"] => string(7) "标题2" ["picCategroy"] => string(6) "海报" ["picAuthor"] => s

随机推荐