MVVMLight学习笔记(二)---MVVMLight框架初探

可紊 提交于 2020-12-19 04:53:03

一、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项目就构建完成了。
运行结果如下:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!