一、MVVM分层概述

MVVM中,各个部分的职责如下:

Model:负责数据实体的结构处理,与ViewModel进行交互;

View:负责界面显示,与ViewModel进行数据和命令的交互;
ViewModel:负责前端视图业务级别的逻辑结构组织,并将其反馈给前端。
 
二、MVVMLight框架初探
通过NuGet安装MVVM Light 框架后,我们新建的Wpf项目中会自动生成一个ViewModel文件夹,里面有MainViewModel.cs和ViewModelLocator.cs两个文件。
下面我们就首先分析下这两个文件的内容:
MainViewModel.cs文件分析:
MainViewModel.cs文件中只有一个类MainViewModel,该类是主窗口MainWindow对应的ViewModel,继承自类ViewModelBase
ViewModelBase类又继承类ObservableObject,同时实现ICleanup接口
ObservableObject类实现INotifyPropertyChanged接口,用于通知属性的改变
由此分析,我们可以得出以下一般结论:
当我们定义一个自己的ViewModel时,一般让自定义ViewModel继承自ViewModelBase类,这样当ViewModel中属性发生变化的时候,就可以自动通知对应的VIew。
 
ViewModelLocator.cs文件分析:
ViewModelLocator.cs文件中只有一个ViewModelLocator类,类中包括一个构造函数、一个类型为MainViewModel的Main属性、以及一个静态的Cleanup函数。
 

 public class ViewModelLocator
{
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); ////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>();
////} SimpleIoc.Default.Register<MainViewModel>();
} public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
} public static void Cleanup()
{
// TODO Clear the ViewModels
}
}

在构造函数中,创建了一个SimpleIoc类型的单实例,用于注册ViewModel,然后用ServiceLocator对这个SimpleIoc类型的单实例进行包裹,方便统一管理。
观察App.xaml文件,我们会发现ViewModelLocator类被生成资源字典并加入到了全局资源,所以每次App初始化的时候,就会去初始化ViewModelLocator类。

实际上,他是一个很基本的视图模型注入器,在构造器中把使用到的ViewModel统一注册,并生成单一实例。然后使用属性把它暴露出来,每当我们访问属性的时候,就会返回相应的ViewModel实例。

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

由此分析,我们可以得出以下一般结论:

当我们自定义一个ViewModel的时候,就可以在ViewModelLocator类的构造函数中对ViewModel进行注册,然后在该类中定义一个属性,用于返回我们的自定义ViewModel

三、MVVMLight框架初探实战Demo

在建立一个MVVMLight框架的Wpf工程后,我们再在工程下建立Model和View(该文件夹在本Demo中暂时不用,我们只使用主窗口)文件夹,VIewModel文件夹框架已经自动帮我们建立了,无需再创建。

1)在Model文件夹下建立一个WelcomeModel .cs文件,文件内容如下:

using GalaSoft.MvvmLight;

namespace MvvmLightDemo1.Model
{
public class WelcomeModel : ObservableObject
{
private string welcomeMsg;
public string WelcomeMsg
{
get { return welcomeMsg; }
set { welcomeMsg = value; RaisePropertyChanged(() => WelcomeMsg); }
}
} }

类WelcomeModel继承自类ObservableObject,并包含一个简单的string类型的WelcomeMsg属性,用于显示欢迎信息。
类ObservableObject位于GalaSoft.MvvmLight命名空间,实现INotifyPropertyChanged接口,通过触发PropertyChanged事件达到通知UI属性更改的目的。

所以,我们在定义实体对象的时候,只需要在属性的set块中调用RaisePropertyChanged(PropertyName)就可以进行属性更改通知,实现与UI的交互。

2)在MainViewModel中定义一个WelcomeModel类型的属性WelcomeModel,并在构造函数中对该属性进行初始化。

using GalaSoft.MvvmLight;
using MvvmLightDemo1.Model; namespace MvvmLightDemo1.ViewModel
{
/// <summary>
/// This class contains properties that the main View can data bind to.
/// <para>
/// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
/// </para>
/// <para>
/// You can also use Blend to data bind with the tool's support.
/// </para>
/// <para>
/// See http://www.galasoft.ch/mvvm
/// </para>
/// </summary>
public class MainViewModel : ViewModelBase
{
private WelcomeModel welcomeModel;
public WelcomeModel WelcomeModel
{
get { return welcomeModel; }
set { welcomeModel = value; RaisePropertyChanged(() => WelcomeModel); }
}
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel()
{
WelcomeModel = new WelcomeModel() { WelcomeMsg = "Welcome to MVVMLight World!" };
}
}
}

3)修改主窗口

<Window x:Class="MvvmLightDemo1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MvvmLightDemo1"
mc:Ignorable="d"
Title="MVVMLIghtDemo1" Height="350" Width="525" Background="#FF256795">
<Window.DataContext>
<Binding Path="Main" Source="{StaticResource Locator}"></Binding>
</Window.DataContext>
<Grid>
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Center" >
<TextBlock Text="{Binding WelcomeModel.WelcomeMsg}" FontSize="28" Foreground="#FF128738"></TextBlock>
</StackPanel>
</Grid>
</Window>

TextBlock 绑定了 WelcomeModel中的WelcomeMsg,用于显示欢迎信息。

然后,我们通过ViewModelLocator的Main属性返回MainViewModel,将它赋值给MainWindow的DataContext属性,完成VIew和ViewModel的关联。

     <Window.DataContext>
        <Binding Path="Main" Source="{StaticResource Locator}"></Binding>
    </Window.DataContext>
Key为Locator的类型为ViewModelLocator的资源在App.xaml中被声明,是一个全局资源。
App.xaml文件内容如下:
<Application x:Class="MvvmLightDemo1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MvvmLightDemo1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d1p1:Ignorable="d" xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" xmlns:vm="clr-namespace:MvvmLightDemo1.ViewModel" />
</ResourceDictionary>
</Application.Resources>
</Application>

ViewModelLocator.cs文件内容如下:

/*
In App.xaml:
<Application.Resources>
<vm:ViewModelLocator xmlns:vm="clr-namespace:MvvmLightDemo1"
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 CommonServiceLocator;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc; namespace MvvmLightDemo1.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); ////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>();
////} SimpleIoc.Default.Register<MainViewModel>();
} public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
} public static void Cleanup()
{
// TODO Clear the ViewModels
}
}
}

至此,一个初级的MVVMLight项目就构建完成了。
运行结果如下:

最新文章

  1. R平方
  2. GCD基础知识总结
  3. javascript数组的知识点讲解
  4. 关于 php mysql pdo cannot find driver 解决方案
  5. MemSQL分布式架构介绍(二)
  6. 数据库 使用DML语句更改数据
  7. c++ char * const p问题
  8. window7部署solr 4.7
  9. eclipse 分屏
  10. linux下编译安装nginx
  11. 踩坑之路_&quot;var name = &#39; &#39;;&quot;_迷之BUG
  12. Hibernate关系映射之many-to-many
  13. flume1.8 Sinks类型介绍(三)
  14. 设计模式——状态模式(C++实现)
  15. ubuntu16.04安装中文输入法
  16. C - Thief in a Shop - dp完全背包-FFT生成函数
  17. 内存管理中提到的hot cold page
  18. Win64/Linux 上PyMouse安装
  19. [dev][crypto][strongswan] 有关strongswan的forward policy的源码分析
  20. 用keras实现基本的回归问题

热门文章

  1. 详解Lombok中的@Builder用法
  2. React组件三大属性之state
  3. dotnet部署出现Failed to load the dll from [ ... hostfxr.dll], HRESULT: 0x80070057
  4. jvm源码解读--18 Java的start()方法解读 以及 wait 和notify流程图
  5. 误改win10下的windowsapps文件夹权限,导致自带应用闪退问题
  6. Webmin 远程命令执行漏洞(CVE-2019-15107)
  7. vue中this.$router.push()路由传值和获取的两种常见方法
  8. Linux的磁盘管理和进程管理(入门)
  9. vue 子目录配置,负载均衡 nginx
  10. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)