Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架

openkk 12年前
     <p>本章节,我将通过示例介绍如何搭建mvvmlight开发环境。示例中的我会针对wpf代码进行介绍,SL下有区别的地方我会注明,下载示例中会同时包含WPF和SL源代码,但是只会提供VS2010版本的示例程序。</p>    <p>前提条件:按照前一章节安装的模板和代码片段,或者下载 MVVM Light Toolkit V3</p>    <p>开发环境:VS2010/Blend4</p>    <p>为了方便大家了解框架结构,我将不使用mvvm项目模板,而是从空白项目开始创建mvvm light项目,下面将以两种使用mvmmlight框架的方式进行说明(以下示例针对WPF,SL操作步骤跟WPF基本一样,不做过多说明,大家可以在文章最后下载代码对照阅读):</p>    <p>1、在VS2010中,文件\新建\WPF/SilverLight应用程序项目,项目名称MvvmlightDataBinding.SL4/MvvmlightDataBinding.WPF4</p>    <p>2、添加mvvmlight引用,如果使用模板创建,会自动生成引用,而这里我们需要自己添加,这里我将MVVM Light Toolkit V3的源代码附到了示例中,因此,直接添加项目引用就可以了,如果要支持Blend的功能,还需要添加 System.Windows.Interactivity.dll引用,如果安装了Blend,在.net引用列表中能找到,没有安装Blend,在示例中解决方案目录\Assemblies\GalaSoft.MvvmLight\External中能找到,添加后引用列表如下:</p>    <p></p>    <img title="Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架" border="0" alt="Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架" src="https://simg.open-open.com/show/b70f98aa8859abfc238a25ec1f96ef34.jpg" width="367" height="620" />    <p> </p>    <p>3、在解决方案浏览器中,右键项目名称,添加新文件夹,文件夹名称为ViewModel</p>    <p>4、在解决方案浏览器中,右键项目名称,添加新文件夹,文件夹名称为View</p>    <p>5、为MainWindow添加ViewModel,在解决方案浏览器中,右键ViewModel文件夹,添加新类,类名称为MainViewModel,如果安装了mvvmlight模板,选择类模板为MvvmViewModel</p>    <p></p>    <p> </p>    <img style="width:636px;height:356px;" title="Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架" border="0" alt="Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架" src="https://simg.open-open.com/show/530d010b1c9e03ae4f652f748f002c7b.jpg" />    <p> </p>    <p>自动创建的代码如下:</p>    <div>     <span style="color:#0000ff;">using</span> GalaSoft.MvvmLight;     <br />     <br />     <span style="color:#0000ff;">namespace</span> MvvmlightDataBinding.WPF4.ViewModel     <br /> {     <br />          <span style="color:#0000ff;">public</span>      <span style="color:#0000ff;">class</span> MainViewModel : ViewModelBase     <br />     {     <br />              <span style="color:#008000;">/// <summary></span>     <br />              <span style="color:#008000;">/// Initializes a new instance of the MainViewModel class.</span>     <br />              <span style="color:#008000;">/// </summary></span>     <br />              <span style="color:#0000ff;">public</span> MainViewModel()     <br />         {     <br />                  <span style="color:#008000;">////if (IsInDesignMode)</span>     <br />                  <span style="color:#008000;">////{</span>     <br />                  <span style="color:#008000;">////    // Code runs in Blend --> create design time data.</span>     <br />                  <span style="color:#008000;">////}</span>     <br />                  <span style="color:#008000;">////else</span>     <br />                  <span style="color:#008000;">////{</span>     <br />                  <span style="color:#008000;">////    // Code runs "for real": Connect to service, etc...</span>     <br />                  <span style="color:#008000;">////}</span>     <br />         }     <br />     <br />              <span style="color:#0000ff;">public</span>      <span style="color:#0000ff;">override</span>      <span style="color:#0000ff;">void</span> Cleanup()     <br />         {     <br />                  <span style="color:#008000;">// Clean own resources if needed</span>     <br />     <br />                  <span style="color:#0000ff;">base</span>.Cleanup();     <br />         }     <br />     }     <br /> }    </div>    <p> </p>    <p>代码很简单,我去掉了类注释,它是一个框架,继承自ViewModelBase,如果没装类模板,可以直接复制以上代码。</p>    <p>6、添加类ViewModelLocator,我们叫它ViewModel加载器,在解决方案浏览器中,右键项目名称,添加新类,类名称为 ViewModelLocator,如果安装了mvvmlight模板,选择类模板为MvvmViewModelLocator,自动创建的代码如下:</p>    <div>     <span style="color:#0000ff;">namespace</span> MvvmlightDataBinding.WPF4.ViewModel     <br /> {      <br />          <span style="color:#0000ff;">public</span>      <span style="color:#0000ff;">class</span> ViewModelLocator     <br />     {     <br />              <span style="color:#008000;">/// <summary></span>     <br />              <span style="color:#008000;">/// Initializes a new instance of the ViewModelLocator class.</span>     <br />              <span style="color:#008000;">/// </summary></span>     <br />              <span style="color:#0000ff;">public</span> ViewModelLocator()     <br />         {     <br />                  <span style="color:#008000;">////if (ViewModelBase.IsInDesignModeStatic)</span>     <br />                  <span style="color:#008000;">////{</span>     <br />                  <span style="color:#008000;">////    // Create design time view models</span>     <br />                  <span style="color:#008000;">////}</span>     <br />                  <span style="color:#008000;">////else</span>     <br />                  <span style="color:#008000;">////{</span>     <br />                  <span style="color:#008000;">////    // Create run time view models</span>     <br />                  <span style="color:#008000;">////}</span>     <br />         }     <br />     <br />              <span style="color:#008000;">/// <summary></span>     <br />              <span style="color:#008000;">/// Cleans up all the resources.</span>     <br />              <span style="color:#008000;">/// </summary></span>     <br />              <span style="color:#0000ff;">public</span>      <span style="color:#0000ff;">static</span>      <span style="color:#0000ff;">void</span> Cleanup()     <br />         {     <br />                  <span style="color:#008000;">// Call ClearViewModelName() for each ViewModel.</span>     <br />         }     <br />     }     <br /> }    </div>    <p> </p>    <p>在Cleanup方法下面添加MainViewModel加载方法,这里要用到我们安装的代码片段,在类的空白处输入mvvm,在弹出的代码提示中选择mvvmlocatorproperty,如下:</p>    <p></p>    <img title="Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架" border="0" alt="Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架" src="https://simg.open-open.com/show/e362346d2c9db1a07ae21d4cac70bc05.jpg" width="286" height="265" />    <p> </p>    <p>然后按2次tab键,会自动MainViewModel加载方法,代码片段要设置的地方有3个,他们以黄色背景高亮显示,其他相关联地方会自动保持与这3个地方一致,生成的方法如下:</p>    <div>     #region MainViewModel     <br />              <span style="color:#0000ff;">private</span>      <span style="color:#0000ff;">static</span> MainViewModel _main;     <br />     <br />              <span style="color:#008000;">/// <summary></span>     <br />              <span style="color:#008000;">/// Gets the Main property.</span>     <br />              <span style="color:#008000;">/// </summary></span>     <br />              <span style="color:#0000ff;">public</span>      <span style="color:#0000ff;">static</span> MainViewModel MainStatic     <br />         {     <br />                  <span style="color:#0000ff;">get</span>     <br />             {     <br />                      <span style="color:#0000ff;">if</span> (_main ==      <span style="color:#0000ff;">null</span>)     <br />                 {     <br />                     CreateMain();     <br />                 }     <br />     <br />                      <span style="color:#0000ff;">return</span> _main;     <br />             }     <br />         }     <br />     <br />              <span style="color:#008000;">/// <summary></span>     <br />              <span style="color:#008000;">/// Gets the Main property.</span>     <br />              <span style="color:#008000;">/// </summary></span>     <br />         [System.Diagnostics.CodeAnalysis.SuppressMessage(     <span style="color:#ff00ff;">"Microsoft.Performance"</span>,     <br />                  <span style="color:#ff00ff;">"CA1822:MarkMembersAsStatic"</span>,     <br />             Justification =      <span style="color:#ff00ff;">"This non-static member is needed for data binding purposes."</span>)]     <br />              <span style="color:#0000ff;">public</span> MainViewModel Main     <br />         {     <br />                  <span style="color:#0000ff;">get</span>     <br />             {     <br />                      <span style="color:#0000ff;">return</span> MainStatic;     <br />             }     <br />         }     <br />     <br />              <span style="color:#008000;">/// <summary></span>     <br />              <span style="color:#008000;">/// Provides a deterministic way to delete the Main property.</span>     <br />              <span style="color:#008000;">/// </summary></span>     <br />              <span style="color:#0000ff;">public</span>      <span style="color:#0000ff;">static</span>      <span style="color:#0000ff;">void</span> ClearMain()     <br />         {     <br />             _main.Cleanup();     <br />             _main =      <span style="color:#0000ff;">null</span>;     <br />         }     <br />     <br />              <span style="color:#008000;">/// <summary></span>     <br />              <span style="color:#008000;">/// Provides a deterministic way to create the Main property.</span>     <br />              <span style="color:#008000;">/// </summary></span>     <br />              <span style="color:#0000ff;">public</span>      <span style="color:#0000ff;">static</span>      <span style="color:#0000ff;">void</span> CreateMain()     <br />         {     <br />                  <span style="color:#0000ff;">if</span> (_main ==      <span style="color:#0000ff;">null</span>)     <br />             {     <br />                 _main =      <span style="color:#0000ff;">new</span> MainViewModel();     <br />             }     <br />         }     <br />     <br /> #endregion    </div>    <p> </p>    <p>7、打开App.Xaml,先添加ViewModel命名控件引用,然后为ViewModelLocator添加一个全局的资源,app.xaml的内容如下:</p>    <div>     <     <span style="color:#808000;">Application x:Class=</span>     <span style="color:#ff00ff;">"MvvmlightDataBinding.WPF4.App"</span>     <span style="color:#808000;"><br />              xmlns=</span>     <span style="color:#ff00ff;">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>     <span style="color:#808000;"><br />              xmlns:x=</span>     <span style="color:#ff00ff;">"http://schemas.microsoft.com/winfx/2006/xaml"</span>     <span style="color:#808000;"><br />              xmlns:vm=</span>     <span style="color:#ff00ff;">"clr-namespace:MvvmlightDataBinding.WPF4.ViewModel"</span>     <span style="color:#808000;"><br />              xmlns:d=</span>     <span style="color:#ff00ff;">"http://schemas.microsoft.com/expression/blend/2008"</span>     <span style="color:#808000;"><br />              xmlns:mc=</span>     <span style="color:#ff00ff;">"http://schemas.openxmlformats.org/markup-compatibility/2006"</span>     <span style="color:#808000;"><br />              mc:Ignorable=</span>     <span style="color:#ff00ff;">"d"</span>     <span style="color:#808000;"><br />              StartupUri=</span>     <span style="color:#ff00ff;">"MainWindow.xaml"</span>>     <br />   <     <span style="color:#808000;">Application.Resources</span>>     <br />          <span style="color:#008000;"><!--全局 View Model 加载器--></span>     <br />     <     <span style="color:#808000;">vm:ViewModelLocator x:Key=</span>     <span style="color:#ff00ff;">"Locator"</span>     <span style="color:#808000;"><br />           d:IsDataSource=</span>     <span style="color:#ff00ff;">"True"</span>     <span style="color:#808000;"> /</span>>     <br />   <     <span style="color:#808000;">/Application.Resources</span>>     <br /> <     <span style="color:#808000;">/Application</span>>    </div>    <p> </p>    <p>8、打开MainWindow.xaml文件,首先为MainWindow设置DataContext为MainViewModel,当然也可以为Grid设置DataContext,只要我们使用的时候,他在视觉树中可见的范围内,MainWindow.xaml代码如下:</p>    <div>     <     <span style="color:#808000;">Window x:Class=</span>     <span style="color:#ff00ff;">"MvvmlightDataBinding.WPF4.MainWindow"</span>     <span style="color:#808000;"><br />         xmlns=</span>     <span style="color:#ff00ff;">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>     <span style="color:#808000;"><br />         xmlns:x=</span>     <span style="color:#ff00ff;">"http://schemas.microsoft.com/winfx/2006/xaml"</span>     <span style="color:#808000;"><br />         <span style="color:#0000ff;">Title</span>=</span>     <span style="color:#ff00ff;">"MainWindow"</span>     <span style="color:#808000;"> Height=</span>     <span style="color:#ff00ff;">"250"</span>     <span style="color:#808000;"> Width=</span>     <span style="color:#ff00ff;">"300"</span>     <span style="color:#808000;"><br />         DataContext=</span>     <span style="color:#ff00ff;">"{Binding Main,Source={StaticResource Locator}}"</span>>     <br />   <     <span style="color:#808000;">Grid</span>>     <br />     <     <span style="color:#808000;">TextBlock FontSize=</span>     <span style="color:#ff00ff;">"16"</span>     <span style="color:#808000;"> Text=</span>     <span style="color:#ff00ff;">"{Binding WelcomText}"</span>     <span style="color:#808000;">/</span>>     <br />   <     <span style="color:#808000;">/Grid</span>>     <br /> <     <span style="color:#808000;">/Window</span>>    </div>    <p> </p>    <p>我在窗体中放了一个TextBlock,TextBlock的Text属性绑定到WelcomText,这个WelcomText应该是 DataContext对象的WelcomText属性,这里TextBlock从视觉树最顶层也就是Window继承DataContext绑定,因此这里绑定的WelcomText也就是MainViewModel的WelcomText属性,因此我们需要在MainViewModel中添加 WelcomText属性,修改MainViewModel代码如下:</p>    <div>                  <span style="color:#0000ff;">public</span>      <span style="color:#0000ff;">string</span> WelcomText     <br />         {     <br />                  <span style="color:#0000ff;">get</span>;     <br />                  <span style="color:#0000ff;">set</span>;     <br />         }     <br />              <span style="color:#008000;">/// <summary></span>     <br />              <span style="color:#008000;">/// Initializes a new instance of the MainViewModel class.</span>     <br />              <span style="color:#008000;">/// </summary></span>     <br />              <span style="color:#0000ff;">public</span> MainViewModel()     <br />         {     <br />                  <span style="color:#0000ff;">if</span> (IsInDesignMode)     <br />             {     <br />                      <span style="color:#008000;">// Code runs in Blend --> create design time data.</span>     <br />                 WelcomText =      <span style="color:#ff00ff;">"设计时的值"</span>;     <br />             }     <br />                  <span style="color:#0000ff;">else</span>     <br />             {     <br />                      <span style="color:#008000;">// Code runs "for real": Connect to service, etc...</span>     <br />                 WelcomText =      <span style="color:#ff00ff;">"运行时的值"</span>;     <br />             }     <br />         }    </div>    <p> </p>    <p>注意这里IsInDesignMode是判断当前环境是否是设计模式,这在界面和逻辑分离时非常实用,比如当业务逻辑开发未完成时,界面设计人员也可以进行设计,这时只需在IsInDesignMode为True时创造一些测试数据就可以了,同时也实现了所见即所得的界面设计模式;示例中我们在设计时和运行时窗体显示不同的值:</p>    <p>设计时截图如下:</p>    <p></p>    <p></p>    <img title="Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架" border="0" alt="Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架" src="https://simg.open-open.com/show/90f86862e8ceb850f5860777e3d2e651.jpg" width="304" height="249" />    <p></p>    <p>运行时截图如下:</p>    <p></p>    <img title="Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架" border="0" alt="Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架" src="https://simg.open-open.com/show/12f86d5a2f2442889423361de7c66231.jpg" width="300" height="250" />    <p> </p>    <p>OK,到这里我们已经完成搭建Mvvmlight框架了,接着我们继续看不使用ViewModelLocator来搭建Mvvm环境:</p>    <p>1~5步与前面搭建标准MvvmLight框架一样。</p>    <p>6、这里我们不创建ViewModelLocator,直接打开app.xaml.cs,添加如下代码:</p>    <div>     <span style="color:#0000ff;">protected</span>      <span style="color:#0000ff;">override</span>      <span style="color:#0000ff;">void</span> OnStartup(StartupEventArgs e)     <br />         {     <br />                  <span style="color:#0000ff;">base</span>.OnStartup(e);     <br />     <br />             MainWindow =      <span style="color:#0000ff;">new</span> MainWindow();     <br />             MainWindow.Show();     <br />             MainWindow.DataContext =      <span style="color:#0000ff;">new</span> ViewModel.MainViewModel();     <br />         }    </div>    <p> </p>    <p>在App.xaml中去掉StarupUri属性设置。</p>    <p>7、修改MainWindow.xaml,完整代码如下:</p>    <div>     <     <span style="color:#808000;">Window x:Class=</span>     <span style="color:#ff00ff;">"NormalMVVM.WPF4.MainWindow"</span>     <span style="color:#808000;"><br />         xmlns=</span>     <span style="color:#ff00ff;">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>     <span style="color:#808000;"><br />         xmlns:x=</span>     <span style="color:#ff00ff;">"http://schemas.microsoft.com/winfx/2006/xaml"</span>     <span style="color:#808000;"><br />         <span style="color:#0000ff;">Title</span>=</span>     <span style="color:#ff00ff;">"MainWindow"</span>     <span style="color:#808000;"> Height=</span>     <span style="color:#ff00ff;">"350"</span>     <span style="color:#808000;"> Width=</span>     <span style="color:#ff00ff;">"525"</span>     <span style="color:#808000;"><br />         xmlns:vm=</span>     <span style="color:#ff00ff;">"clr-namespace:NormalMVVM.WPF4.ViewModel"</span>     <span style="color:#808000;"><br />         xmlns:d=</span>     <span style="color:#ff00ff;">"http://schemas.microsoft.com/expression/blend/2008"</span>     <span style="color:#808000;"><br />         xmlns:mc=</span>     <span style="color:#ff00ff;">"http://schemas.openxmlformats.org/markup-compatibility/2006"</span>     <span style="color:#808000;"><br />         mc:Ignorable=</span>     <span style="color:#ff00ff;">"d"</span>     <span style="color:#808000;"><br />         d:DataContext=</span>     <span style="color:#ff00ff;">"{d:DesignInstance Type=vm:MainViewModel, IsDesignTimeCreatable=True}"</span>>     <br />   <     <span style="color:#808000;">Grid</span>>     <br />     <     <span style="color:#808000;">TextBlock HorizontalAlignment=</span>     <span style="color:#ff00ff;">"Center"</span>     <span style="color:#808000;"> VerticalAlignment=</span>     <span style="color:#ff00ff;">"Center"</span>     <span style="color:#808000;"> FontSize=</span>     <span style="color:#ff00ff;">"36"</span>     <span style="color:#808000;"> Text=</span>     <span style="color:#ff00ff;">"{Binding WelcomText}"</span>     <span style="color:#808000;">/</span>>     <br />   <     <span style="color:#808000;">/Grid</span>>     <br /> <     <span style="color:#808000;">/Window</span>>    </div>    <p>注意这里没有使用全局的ViewModelLocator,要在设计时显示ViewModel的内容,需要使用d:DataContext创建一个设计时的实例,这个实例只有在设计时有效,在运行时MainWindow仍然使用app.xaml.cs中动态创建的ViewModel</p>    <p>OK,运行示例,得到与前面示例相同的结果。</p>    <p>综合看这两种方法,第一个是将ViewModel定义为静态的全局变量,第二个是动态创建,这里不谈孰优孰劣,我觉得应该灵活运用,一个项目往往包含很多个View和ViewModel,全部都定义为静态并不合适,因此我一般都是两种方法混合使用</p>    <p>至此,我们应该已经知道搭建和使用mvvmlight框架了,下一章节将介绍mvvm下的数据绑定,以下是本章节的源代码下载:</p>    <p>http://download.csdn.net/source/3246642</p>    <p>本文来自段子林的博客,原文地址:http://blog.csdn.net/duanzilin/archive/2011/05/03/6388593.aspx</p>