Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight開發框架
本章節,我將通過示例介紹如何搭建mvvmlight開發環境。示例中的我會針對wpf代碼進行介紹,SL下有區別的地方我會注明,下載示例中會同時包含WPF和SL源代碼,但是只會提供VS2010版本的示例程序。
前提條件:按照前一章節安裝的模板和代碼片段,或者下載 MVVM Light Toolkit V3
開發環境:VS2010/Blend4
為了方便大家了解框架結構,我將不使用mvvm項目模板,而是從空白項目開始創建mvvm light項目,下面將以兩種使用mvmmlight框架的方式進行說明(以下示例針對WPF,SL操作步驟跟WPF基本一樣,不做過多說明,大家可以在文章最后下載代碼對照閱讀):
1、在VS2010中,文件\新建\WPF/SilverLight應用程序項目,項目名稱MvvmlightDataBinding.SL4/MvvmlightDataBinding.WPF4
2、添加mvvmlight引用,如果使用模板創建,會自動生成引用,而這里我們需要自己添加,這里我將MVVM Light Toolkit V3的源代碼附到了示例中,因此,直接添加項目引用就可以了,如果要支持Blend的功能,還需要添加 System.Windows.Interactivity.dll引用,如果安裝了Blend,在.net引用列表中能找到,沒有安裝Blend,在示例中解決方案目錄\Assemblies\GalaSoft.MvvmLight\External中能找到,添加后引用列表如下:

3、在解決方案瀏覽器中,右鍵項目名稱,添加新文件夾,文件夾名稱為ViewModel
4、在解決方案瀏覽器中,右鍵項目名稱,添加新文件夾,文件夾名稱為View
5、為MainWindow添加ViewModel,在解決方案瀏覽器中,右鍵ViewModel文件夾,添加新類,類名稱為MainViewModel,如果安裝了mvvmlight模板,選擇類模板為MvvmViewModel

自動創建的代碼如下:
namespace MvvmlightDataBinding.WPF4.ViewModel
{
public class MainViewModel : ViewModelBase
{
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel()
{
////if (IsInDesignMode)
////{
//// // Code runs in Blend --> create design time data.
////}
////else
////{
//// // Code runs "for real": Connect to service, etc...
////}
}
public override void Cleanup()
{
// Clean own resources if needed
base.Cleanup();
}
}
}
代碼很簡單,我去掉了類注釋,它是一個框架,繼承自ViewModelBase,如果沒裝類模板,可以直接復制以上代碼。
6、添加類ViewModelLocator,我們叫它ViewModel加載器,在解決方案瀏覽器中,右鍵項目名稱,添加新類,類名稱為 ViewModelLocator,如果安裝了mvvmlight模板,選擇類模板為MvvmViewModelLocator,自動創建的代碼如下:
{
public class ViewModelLocator
{
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
////if (ViewModelBase.IsInDesignModeStatic)
////{
//// // Create design time view models
////}
////else
////{
//// // Create run time view models
////}
}
/// <summary>
/// Cleans up all the resources.
/// </summary>
public static void Cleanup()
{
// Call ClearViewModelName() for each ViewModel.
}
}
}
在Cleanup方法下面添加MainViewModel加載方法,這里要用到我們安裝的代碼片段,在類的空白處輸入mvvm,在彈出的代碼提示中選擇mvvmlocatorproperty,如下:

然后按2次tab鍵,會自動MainViewModel加載方法,代碼片段要設置的地方有3個,他們以黃色背景高亮顯示,其他相關聯地方會自動保持與這3個地方一致,生成的方法如下:
private static MainViewModel _main;
/// <summary>
/// Gets the Main property.
/// </summary>
public static MainViewModel MainStatic
{
get
{
if (_main == null)
{
CreateMain();
}
return _main;
}
}
/// <summary>
/// Gets the Main property.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public MainViewModel Main
{
get
{
return MainStatic;
}
}
/// <summary>
/// Provides a deterministic way to delete the Main property.
/// </summary>
public static void ClearMain()
{
_main.Cleanup();
_main = null;
}
/// <summary>
/// Provides a deterministic way to create the Main property.
/// </summary>
public static void CreateMain()
{
if (_main == null)
{
_main = new MainViewModel();
}
}
#endregion
7、打開App.Xaml,先添加ViewModel命名控件引用,然后為ViewModelLocator添加一個全局的資源,app.xaml的內容如下:
xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x= "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm= "clr-namespace:MvvmlightDataBinding.WPF4.ViewModel"
xmlns:d= "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc= "http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable= "d"
StartupUri= "MainWindow.xaml">
< Application.Resources>
<!--全局 View Model 加載器-->
< vm:ViewModelLocator x:Key= "Locator"
d:IsDataSource= "True" />
< /Application.Resources>
< /Application>
8、打開MainWindow.xaml文件,首先為MainWindow設置DataContext為MainViewModel,當然也可以為Grid設置DataContext,只要我們使用的時候,他在視覺樹中可見的范圍內,MainWindow.xaml代碼如下:
xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x= "http://schemas.microsoft.com/winfx/2006/xaml"
Title= "MainWindow" Height= "250" Width= "300"
DataContext= "{Binding Main,Source={StaticResource Locator}}">
< Grid>
< TextBlock FontSize= "16" Text= "{Binding WelcomText}" />
< /Grid>
< /Window>
我在窗體中放了一個TextBlock,TextBlock的Text屬性綁定到WelcomText,這個WelcomText應該是 DataContext對象的WelcomText屬性,這里TextBlock從視覺樹最頂層也就是Window繼承DataContext綁定,因此這里綁定的WelcomText也就是MainViewModel的WelcomText屬性,因此我們需要在MainViewModel中添加 WelcomText屬性,修改MainViewModel代碼如下:
{
get;
set;
}
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel()
{
if (IsInDesignMode)
{
// Code runs in Blend --> create design time data.
WelcomText = "設計時的值";
}
else
{
// Code runs "for real": Connect to service, etc...
WelcomText = "運行時的值";
}
}
注意這里IsInDesignMode是判斷當前環境是否是設計模式,這在界面和邏輯分離時非常實用,比如當業務邏輯開發未完成時,界面設計人員也可以進行設計,這時只需在IsInDesignMode為True時創造一些測試數據就可以了,同時也實現了所見即所得的界面設計模式;示例中我們在設計時和運行時窗體顯示不同的值:
設計時截圖如下:

運行時截圖如下:

OK,到這里我們已經完成搭建Mvvmlight框架了,接著我們繼續看不使用ViewModelLocator來搭建Mvvm環境:
1~5步與前面搭建標準MvvmLight框架一樣。
6、這里我們不創建ViewModelLocator,直接打開app.xaml.cs,添加如下代碼:
{
base.OnStartup(e);
MainWindow = new MainWindow();
MainWindow.Show();
MainWindow.DataContext = new ViewModel.MainViewModel();
}
在App.xaml中去掉StarupUri屬性設置。
7、修改MainWindow.xaml,完整代碼如下:
xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x= "http://schemas.microsoft.com/winfx/2006/xaml"
Title= "MainWindow" Height= "350" Width= "525"
xmlns:vm= "clr-namespace:NormalMVVM.WPF4.ViewModel"
xmlns:d= "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc= "http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable= "d"
d:DataContext= "{d:DesignInstance Type=vm:MainViewModel, IsDesignTimeCreatable=True}">
< Grid>
< TextBlock HorizontalAlignment= "Center" VerticalAlignment= "Center" FontSize= "36" Text= "{Binding WelcomText}" />
< /Grid>
< /Window>
注意這里沒有使用全局的ViewModelLocator,要在設計時顯示ViewModel的內容,需要使用d:DataContext創建一個設計時的實例,這個實例只有在設計時有效,在運行時MainWindow仍然使用app.xaml.cs中動態創建的ViewModel
OK,運行示例,得到與前面示例相同的結果。
綜合看這兩種方法,第一個是將ViewModel定義為靜態的全局變量,第二個是動態創建,這里不談孰優孰劣,我覺得應該靈活運用,一個項目往往包含很多個View和ViewModel,全部都定義為靜態并不合適,因此我一般都是兩種方法混合使用
至此,我們應該已經知道搭建和使用mvvmlight框架了,下一章節將介紹mvvm下的數據綁定,以下是本章節的源代碼下載:
http://download.csdn.net/source/3246642
本文來自段子林的博客,原文地址:http://blog.csdn.net/duanzilin/archive/2011/05/03/6388593.aspx