MVVM Light 开始

原文地址:http://jesseliberty.com/2011/01/04/wpfs-mvvm-light-toolkit-soup-to-nuts-part-i/

只是意译,很多没必要的话就不费口舌了。

 

MVVM提供了一个WP7开发的最好的模式。目前MVVM有很多优秀的框架,使MVVM的开发变得更加容易。我个人更喜欢MVVM Light,因此目前将专注于它。

 

安装步骤:

CodePlex的地址为:http://mvvmlight.codeplex.com/ 

也可以从其官网上下载:http://www.galasoft.ch/mvvm/

下载最新版本安装即可。我这里安装的是MVVM Light Toolkit V4 beta 1,安装后就可以在VS2010里看到MVVM Light的模板了。

 

现在开始创建一个MVVM应用,了解一些基本的信息。以后将讨论一些更有趣的话题,比如behaviors 和 messages。

 

创建应用

打开VS2010并点击“新建项目”,选择MVVM Light(WP71)模板。现在大部分WP手机已经升级到mango了,当然您也可以用WP7的模板。

 

项目名称随便写一个,我这里就用默认的MvvmLight1了。然后编译运行,回放按下应用显示出“Welcome to MVVM Light”。OK。

 

查看View和ViewModel

模板自动添加了以下目录:Model、ViewModel和默认的一些cs代码。

打开MainViewModel.cs,会发现几个字符串属性:WelcomeTitle这些作为属性绑定到MainPage.xaml,

   1: <StackPanel x:Name="TitlePanel"
   2:                     Grid.Row="0"
   3:                     Margin="24,24,0,12">
   4:             <TextBlock x:Name="ApplicationTitle"
   5:                        Text="{Binding ApplicationTitle}"
   6:                        Style="{StaticResource PhoneTextNormalStyle}" />
   7:             <TextBlock x:Name="PageTitle"
   8:                        Text="{Binding PageName}"
   9:                        Margin="-3,-8,0,0"
  10:                        Style="{StaticResource PhoneTextTitle1Style}" />
  11:         </StackPanel>
  12:  
  13:         <!--ContentPanel - place additional content here-->
  14:         <Grid x:Name="ContentGrid"
  15:               Grid.Row="1">
  16:  
  17:             <TextBlock Text="{Binding WelcomeTitle}"
  18:                        Style="{StaticResource PhoneTextNormalStyle}"
  19:                        HorizontalAlignment="Center"
  20:                        VerticalAlignment="Center"
  21:                        FontSize="40" 
  22:                        TextWrapping="Wrap" 
  23:                        TextAlignment="Center" />
  24:         </Grid>

必须把MainViewMedel设置成MainPage.xaml的DataContext,这是在页面开始的<phone:PhoneApplicationPage>节里定义的:

DataContext="{Binding Main, Source={StaticResource Locator}}"

   1:  <phone:PhoneApplicationPage
   2:                              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:                              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:                              xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
   5:                              xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
   6:                              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   7:                              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   8:                              xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:GalaSoft_MvvmLight_Command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP71" x:Class="MvvmLight1.MainPage"
   9:                              FontFamily="{StaticResource PhoneFontFamilyNormal}"
  10:                              FontSize="{StaticResource PhoneFontSizeNormal}"
  11:                              Foreground="{StaticResource PhoneForegroundBrush}"
  12:                              SupportedOrientations="Portrait"
  13:                              Orientation="Portrait"
  14:                              mc:Ignorable="d"
  15:                              d:DesignWidth="480"
  16:                              d:DesignHeight="768"
  17:                              shell:SystemTray.IsVisible="True"
  18:                              DataContext="{Binding Main, Source={StaticResource Locator}}">

 

请注意这是通过StaticResource Locator定义的。

 

ViewModelLocator

ViewModelLocator是MVVM Light的核心,值得研究一下它是如何工作的。这是一个好办法,但不是唯一的办法,您可以设置一个View(MainPage)和它的Model(MainViewModel)之间的联系。

 

这个静态资源Lacator定义在App.xaml里:

   1: <Application.Resources>
   2:         <!--Global View Model Locator-->
   3:         <vm:ViewModelLocator x:Key="Locator"
   4:                              d:IsDataSource="True" />
   5:     </Application.Resources>

最终,在ViewModelLocator.cs文件里(在你创建项目的时候已经自动创建到ViewModel目录里了)你可以找到ViewModelLocator的构造函数,里面注册了MainViewModel的类型:

   1: SimpleIoc.Default.Register<MainViewModel>();

这样就把MainPage的View和它的ViewModel联系起来了。

 

添加第二个页面时,还要做一些工作,但是这些代码已经放到code-snippets里了,可以很方便的输入。

 

添加第二个页面

现在更深入一些,添加第二个页面。

 

首先右键单击项目,添加一个新文件夹Views,右键添加项,选择MVVM Page (WP7),命名为Page2.xaml.

现在查看Page2.xaml的<phone:PhoneApplicationPage>节,可见其DataContex:

DataContext="{Binding ViewModelName, Source={StaticResource Locator}}"

 

我们还需要为其创建它的ViewModel。在ViewModel目录里添加项,选择MvvmViewModel (WP7),命名为Page2ViewModel.cs

 

在ViewModel里添加以下public属性:

   1: public string ApplicationTitle
   2: {
   3:    get
   4:    {
   5:       return "MVVM LIGHT";
   6:    }
   7: }
   8:  
   9: public string PageName
  10: {
  11:    get
  12:    {
  13:       return "Page 2";
  14:    }
  15: }
  16:  
  17: public string Welcome
  18: {
  19:    get
  20:    {
  21:       return "Welcome to Page 2";
  22:    }
  23: }

现在把它们连接起来。修改Page2.xaml的DataContext属性,将其改为Page2.

DataContext="{Binding Page2, Source={StaticResource Locator}}"

 

使用Code Snippets

 

打开ViewModelLocator.cs,查看其构造函数,这里你可以使用mvvmlocatorproperty 代码段了,定位到构造函数外面输入mvvmlocatorproperty,按两下Tab,修改ViewModel的名字,注意,因为已经有了static ViewModelLocator()这个构造函数,自动生成的会重复,把里面的语句拷出来粘贴到原来的构造函数中即可。修改后的代码如下:

   1: static ViewModelLocator()
   2:         {
   3:             ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
   4:  
   5:             if (ViewModelBase.IsInDesignModeStatic)
   6:             {
   7:                 SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
   8:             }
   9:             else
  10:             {
  11:                 SimpleIoc.Default.Register<IDataService, DataService>();
  12:             }
  13:  
  14:             SimpleIoc.Default.Register<MainViewModel>();
  15:             
SimpleIoc.Default.Register<Page2ViewModel>();
  16:         }
  17: /// <summary>
  18:         /// Gets the Page2ViewModel property.
  19:         /// </summary>
  20:         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
  21:             "CA1822:MarkMembersAsStatic",
  22:             Justification = "This non-static member is needed for data binding purposes.")]
  23:         public Page2ViewModel Page2
  24:         {
  25:             get
  26:             {
  27:                 return ServiceLocator.Current.GetInstance<Page2ViewModel>();
  28:             }
  29:         }

 

下一步:用Behavior和Message实现导航

剩下的就是在第一页上,添加一个按钮,导航到第二页。当然在Code Behind里很简单,你可能会说:不就是用这个么?NavigationService.Navigate(new System.Uri("/Page2.xaml", System.UriKind.Relative));

这当然可以,但我们想用MVVM来实现,使用行为和消息。

posted @ 2011-12-22 12:26  yan_xiaodi  阅读(12007)  评论(2编辑  收藏  举报