ViewModelLocator
這里先鼓舞下士氣,ViewModelLocator很簡單,甚至可以去掉,它不是Mvvm必須的。在初學Mvvm時,一般都是使用NuGet安裝
MvvmLight框架,總是會帶上那么一個ViewModelLocator,並且還加入到了全局資源中,到底是干嗎的?
public class ViewModelLocator
{
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<AppViewModel>();
}
public AppViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<AppViewModel>();
}
}
public static void Cleanup()
{
// TODO Clear the ViewModels
}
}
上面就是一個具有基本功能的試圖模型定位器,它的作用就是訪問ViewModel,你想用哪個ViewModel就在這里找,構造函數中首先注冊一個AppViewModel類型
然后通過Main
屬性暴露出來,當我們訪問Main屬性的時候,就會把AppViewModel的實例返回,注意SimpleIoc默認是
單實例的,返回的是同一個Main
。
注意:在構造該對象時,我們將MvvmLight自帶的SimpleIoc容器指定作為默認服務提供者,
這里為什么要使用ServiceLocator又將SimpleIoc容器包裹一層,
其實在運行時,我們直接使用SimpleIoc也是沒有問題的,
這里主要是考慮到一個設計時的顯示效果,
設計時就能在設計窗口看到ViewModel中的數據。
接下來我們看如何使用ViewModelLocator,在使用NuGet安裝MvvmLight時,會自動給我們的App.xaml
加入一個Resource
<Application x:Class="MvvmDemo.App" 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"
d1p1:Ignorable="d"
xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mvvmDemo="clr-namespace:MvvmDemo" StartupUri="Views/AppView.xaml">
<Application.Resources>
<mvvmDemo:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
</Application.Resources>
</Application>
ViewModelLocator就作為一個全局資源引用到了程序中,注意在App類初始化時,就會去初始化ViewModelLocator。
這樣我們在界面上就可以使用全局資源找到對應的ViewModel。
<Window x:Class="MvvmDemo.Views.AppView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:validationRules="clr-namespace:MvvmDemo.ValidationRules"
xmlns:converter="clr-namespace:MvvmDemo.Converter"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:command="http://www.galasoft.ch/mvvmlight"
Title="AppView" Height="300" Width="300" DataContext="{Binding Source={StaticResource Locator},Path=Main}">
</Window>
這里將AppView的DataContext設置為全局靜態資源中的Main,此時,在VS的可視化窗口中,就會看到數據已經綁定上。
總結一下:這里我們首先有一個ViewModelLocator,然后又是資源,又是Binding,其實目的就是為了在設計時,能夠
將數據友好的顯示,即時看到效果。我們完全可以把這個ViewModelLocator刪除,在AppView的構造函數中,將DataContext
設置為AppViewModel
public AppView()
{
this.DataContext=new AppViewModel();
}
當然呢,這種做法很粗魯,設計時也不會看到綁定的數據。ViewModelLocator的作用就是這么點,也不是很復雜。
SimpleIoc
這個需要了解一下IOC是什么,這兒有一篇很好的文章,也很生動。
IOC的內容很大,在Mvvm中自帶了一個Ioc容器,SimpleIoc,之所以叫SimpleIoc,是因為它的確很簡單,僅僅是作為
對象容器來使用的。例如在設計時的數據可視化效果中,向View的DataContext提供對應的ViewModel。
實際開發中,我們會使用更加靈活的Ioc,例如:MEF,園子里有很不錯的教程。