原文地址: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来实现,使用行为和消息。