写了篇MVVM小记http://www.cnblogs.com/whosedream/p/mvvmnote1.html,说好要写点MVVMLight的东西,所以接着写,以便和大家共勉。
我假设你已经有了MVVM的一些概念,那么我们就单刀直入了,怎样基于MVVMLight 来建项目呢?其实很简单,首先我们需要下载MVVMLight,然后安装,完了你会看到
Binaries里有各个版本的程序集
这里我用到了silverlight4的程序集
不过你安装了模板的话,新建模板项目,那么上面这些程序集就不用你手动去添加了,我用的是VS2012,所以安装了下面的第二个模板MvvmLight.VS2012.vsix
现在可以新建项目了,在新建项目silverlight选项里你会多看见2个选项
我用的是SL4那么我就选择第一个新建
我们可以看到一个大体的架子帮你搭出来了,按F5运行,会看到
恭喜你的第一个MVVMLight应用完成了!!!让我们看看都写了些什么。
找到程序的入口App
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="MvvmLightTest.App" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="clr-namespace:MvvmLightTest.ViewModel" mc:Ignorable="d"> <Application.Resources> <!--Global View Model Locator--> <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" /> </Application.Resources> </Application>
我们看到添加了个应用程序资源ViewModelLocator,这是干什么用的呢,下面再说,看看App.cs里写了些什么
private void Application_Startup(object sender, StartupEventArgs e) { RootVisual = new MainPage(); DispatcherHelper.Initialize(); } private void Application_Exit(object sender, EventArgs e) { ViewModelLocator.Cleanup(); }
和以前的代码相比,在程序退出里我们又看到了ViewModelLocator,看来这东西是贯穿我们应用程序始终的,待会再说。我们还发现在启动里多了个 DispatcherHelper.Initialize(),这是初始化什么的呢?
... public static void Initialize() { if (UIDispatcher == null) { UIDispatcher = Deployment.Current.Dispatcher; } } public static Dispatcher UIDispatcher { get; private set; } ...
看到了吗?它会获取当前应用程序的Dispatcher,Dispatcher是干什么用的?跨线程操作的时候你就会用到。
好了我们的程序RootVisual已经置了MainPage了,看看MainPage有什么
<UserControl x:Class="MvvmLightTest.MainPage" 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:ignore="http://www.ignore.com" mc:Ignorable="d ignore" Height="300" Width="300" DataContext="{Binding Main, Source={StaticResource Locator}}"> <UserControl.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Skins/MainSkin.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </UserControl.Resources> <Grid x:Name="LayoutRoot"> <TextBlock FontSize="36" FontWeight="Bold" Foreground="Purple" Text="{Binding WelcomeTitle}" VerticalAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap" /> </Grid> </UserControl>
是不是还奇怪App里怎么MainPage没有对DataContext进行赋值,原来在这里
DataContext="{Binding Main, Source={StaticResource Locator}}"
这里Locator是不是很熟悉,啊~对了,就是App的资源文件里添加的东西。现在我们来看看到底ViewModelLocator扮演着何方神圣。
public class ViewModelLocator { static ViewModelLocator() { ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); if (ViewModelBase.IsInDesignModeStatic) { SimpleIoc.Default.Register<IDataService, Design.DesignDataService>(); } else { SimpleIoc.Default.Register<IDataService, DataService>(); } SimpleIoc.Default.Register<MainViewModel>(); } /// <summary> /// Gets the Main property. /// </summary> public MainViewModel Main { get { return ServiceLocator.Current.GetInstance<MainViewModel>(); } } /// <summary> /// Cleans up all the resources. /// </summary> public static void Cleanup() { } }
ServiceLocator 和 SimpleIoc 这两个东西比较陌生,看ServiceLocator的注释
This class provides the ambient container for this application. If your framework
defines such an ambient container, use ServiceLocator.Current to get it.
该类为应用程序提供了一个容器,如果你的框架定义了这么一个容器,那么你可以用ServiceLocator.Current来获取。
既然是个容器,那么是干嘛的呢?继续看代码,ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);为这个容器置一个委托SimpleIoc.Default,可能看到IOC,马上就想到了控制反转,依赖注入。对~SimpleIoc就是MVVMLight实现的一个IOC容器,再看SimpleIoc.Default.Register方法,你就明白原来是往容器里塞东西(接口实现,类)。
有放就有取
public MainViewModel Main { get { return ServiceLocator.Current.GetInstance<MainViewModel>(); } }
这也是页面绑定的属性
到现在我们只看到了个ViewModel的属性,嗯,看看ViewModel是怎样的
public class MainViewModel : ViewModelBase { private readonly IDataService _dataService; /// <summary> /// The <see cref="WelcomeTitle" /> property's name. /// </summary> public const string WelcomeTitlePropertyName = "WelcomeTitle"; private string _welcomeTitle = string.Empty; /// <summary> /// Gets the WelcomeTitle property. /// Changes to that property's value raise the PropertyChanged event. /// </summary> public string WelcomeTitle { get { return _welcomeTitle; } set { if (_welcomeTitle == value) { return; } _welcomeTitle = value; RaisePropertyChanged(WelcomeTitlePropertyName); } } /// <summary> /// Initializes a new instance of the MainViewModel class. /// </summary> public MainViewModel(IDataService dataService) { _dataService = dataService; _dataService.GetData( (item, error) => { if (error != null) { // Report error here return; } WelcomeTitle = item.Title; }); } ////public override void Cleanup() ////{ //// // Clean up if needed //// base.Cleanup(); ////} }
它继承了ViewModelBase,其实它还是实现了 INotifyPropertyChanged, System.ComponentModel.INotifyPropertyChanging这些个东西
是不是没有发现Model,呵呵,WelcomeTitle 不就是Model吗?
今天到此为止,源码下载 如果对您有所帮助的话就顶个吧。