上一篇我們簡單對MvvmLight做了介紹。羅列了三個DLL中,各個命名空間下主要類的定義及大緻作用。因為隻是範範的概論,對于從未接觸過MvvmLight的萌新來說,根本就是在晃點他們。不過萬事開頭難麼,本篇則會以Hello World般的簡單例子,來給萌新們當頭一擊,教會他們使用MvvmLight最最基礎的部分。
首先還是動手練習,打開免費又強大的Visual Studio 2015 Community,建立一個WPF Application。不建立Win10的Universal App是因為MvvmLight V5.2還不能給Universal App自動添加ViewModel等代碼(我們下次自己加)。不使用8.1 Runtime App是因為我沒在自己電腦上裝8.1的SDK ^o^。
建立的WPF Application是一個簡單至極的空項目,僅有App.xaml和MainWindow.xaml兩個檔案。XAML檔案空空如也。

然後我們通過NuGet添加MvvmLight的類庫,完成之後多出ViewModel檔案夾,包含以下兩個檔案:
MainViewModel.cs
ViewModelLocator.cs
另外App.xaml裡将ViewModelLocator作為資源添加全局的Application.Resources裡:
<Application.Resources>
<ResourceDictionary>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" xmlns:vm="clr-namespace:HelloMvvmLight.ViewModel" />
</ResourceDictionary>
</Application.Resources>
非常遺憾沒有像Windows Phone工程那樣貼心的在MainWindow裡添加對MainViewModel的DataContext綁定,心情很糟糕的我們隻有自己來了,順便給MainViewModel裡加上HelloWord的字樣呗,完成後運作如下圖:
下面我們來大緻講解MvvmLight在程式中起到的作用。
MainWindow對應的ViewModel是MainViewModel,通常我們是在MainWindow的XAML或cs檔案裡new一個ViewModel的執行個體,指派給DataContext。但在MvvmLight中,建立執行個體的工作,交給了ViewModelLocator這個類。
在類ViewModelLocator裡,我們注冊了MainViewModel,并通過屬性Main來擷取執行個體。
public class ViewModelLocator
{
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<MainViewModel>();
}
public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
public static void Cleanup()
{
// TODO Clear the ViewModels
}
}
之前提到安裝MvvmLight庫時App.xaml添加了ViewModelLocator執行個體的資源,在XAML中以StaticResource key的形式擷取,Binding到MainWindow的DataContext。
<Window.DataContext>
<Binding Path="Main" Source="{StaticResource Locator}"></Binding>
</Window.DataContext>
使用ViewModelLocator有啥好處呢?
首先View和ViewModel之間不再直接引用,而是通過ViewModelLocator關聯。
其次儲存在ViewModelLocator裡的ViewModel類似于單例的存在,可以在全局引用綁定。
同時避免了某些情況下頻繁建立ViewModel,卻未做好資源釋放造成的記憶體洩漏。(這裡并不是說所有的ViewModel都必須放到ViewModelLocator)
下面我們來看下Command是如何綁定的,通知PropertyChanged以及ViewModelBase類 。
我們添加一個Button,然後通過Command來把文字修改為Hello MvvmLight。
ViewModel的代碼:
public class MainViewModel : ViewModelBase
{
private string title;
public string Title
{
get { return title; }
set { Set(ref title , value); }
}
public ICommand ChangeTitleCommand { get; set; }
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel()
{
Title = "Hello World";
ChangeTitleCommand = new RelayCommand(ChangeTitle);
}
private void ChangeTitle()
{
Title = "Hello MvvmLight";
}
}
MainWindow的XAML:
<Window x:Class="HelloMvvmLight.MainWindow"
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:local="clr-namespace:HelloMvvmLight"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<Binding Path="Main" Source="{StaticResource Locator}"></Binding>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Title}"></TextBlock>
<Button Grid.Row="1" Command="{Binding ChangeTitleCommand}"></Button>
</Grid>
</Window>
MvvmLight很貼心的為我們實作了RelayCommand類,該類繼承自ICommand接口。直接在XAML裡綁定就可以了。當然如果是沒有提供Command屬性的控件,就需要用到Blend來添加behavior了(可以期待後續篇章介紹)。
MvvmLight的ViewModelBase很有意思,繼承了INotifyPropertyChanged接口,并提供了一個Set方法來給屬性指派,簡單了解就是不用自己在ViewModel實作INotifyPropertyChanged,然後在屬性指派時通知了。當然MvvmLight也提供了手動通知的方法:
protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null);
protected virtual void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression);
至此一個最簡單的使用MvvmLight架構的程式已經完成了。因為是入門寫的比較簡單,請各位大牛輕踩。
代碼在這裡