一、MVVM分層概述
MVVM中,各個部分的職責如下:
Model:負責數據實體的結構處理,與ViewModel進行交互;
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類。
<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的關聯。
<Binding Path="Main" Source="{StaticResource Locator}"></Binding>
</Window.DataContext>
<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項目就構建完成了。
運行結果如下: