MVVMLight學習筆記(二)---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項目就構建完成了。
運行結果如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM