zoukankan      html  css  js  c++  java
  • WPF MVVMLight 回顾(转)

     

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

  • 相关阅读:
    python 安装第三方插件库报错的解决方案
    vue.js helloword
    node.js HelloWord
    十一 —— 迭代器、生成器、装饰器
    十、函数——匿名函数、推导式
    九、函数 —— 参数
    八、数据类型——bytes类型+set类型
    七、数据类型 —— 字典
    六、数据类型 —— 字符串
    五、数据类型 —— 元组
  • 原文地址:https://www.cnblogs.com/lzjsky/p/15681531.html
Copyright © 2011-2022 走看看