1.MVVMLight 分析:
在示例demo中我们看到,界面上引用 Text="{Binding WelcomTitle}",WPF中的绑定如果没有ElementName或Source,则默认绑定自身或者继承父级的DataContext
<TextBlock FontSize="36"
FontWeight="Bold"
Foreground="Purple"
Text="{Binding WelcomeTitle}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextWrapping="Wrap" />
根据以上分析,我们在Window对象(顶级容器)找到了: DataContext="{Binding Main, Source={StaticResource Locator}}"
可见其绑定的是来自资源文件的 Locator 对象 的Main属性
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
通过以上资源文件<ResourceDirectory.MergedDirectionaries...</ResourceDirectory.MergedDirectionaries> 说明是合并了当前资源文件,默认的资源文件为App.xaml,因此我们只能在默认资源文件和当前的资源文件中找Locator的定义。
<Application.Resources>
<!--Global View Model Locator-->
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
</Application.Resources>
通过查找,我们在App.xaml中找到了以上定义,英文注释说这是一个全局的视图模型Locator,不错,前面我们也看到了,它放在Window容器中。
根据以上<vm:ViewModelLocator x:key="Locator" d:IsDataSource="True" />可以看出其类的定义为ViewModelLocator,vm表明其定义在vm对应的命名空间中:
xmlns:vm="clr-namespace:MvvmLightNetDemo.ViewModel" 不错,我们找到了,下面去这个命名空间中看一下这个类的定义:
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
using MvvmLightNetDemo.Model;
namespace MvvmLightNetDemo.ViewModel
{
/// <summary>
/// This class contains static references to all the view models in the
/// application and provides an entry point for the bindings.
/*
这个类包含的静态引用是为应用程序和所有的绑定提供一个入口
*/
/// <para>
/// See http://www.mvvmlight.net
/// </para>
/// </summary>
public class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
}
else
{
SimpleIoc.Default.Register<IDataService, DataService>();
}
SimpleIoc.Default.Register<MainViewModel>();
}
/// <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 ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
/// <summary>
/// Cleans up all the resources.
/// </summary>
public static void Cleanup()
{}
}
}
通过以上代码可以看到,ViewModelLocator这个类中定义一个MainViewModel 类型的属性Main 返回的是MainViewModel实例
通过调用ServiceLocator.Current.GetInstance<MainModel>() 实例化。
这里的ServiceLocator便是MVVMLight 框架的关键,起着依赖注入的功能。
我们再看看MainViewModel类的定义:
public class MainViewModel : ViewModelBase
{
private readonly IDataService _dataService;
public const string WelcomeTitlePropertyName = "WelcomeTitle";
private string _welcomeTitle = string.Empty;
public string WelcomeTitle
{
get
{
return _welcomeTitle;
}
set
{
Set(ref _welcomeTitle, value);
}
}
public MainViewModel(IDataService dataService)
{
_dataService = dataService;
_dataService.GetData(
(item, error) =>
{
if (error != null)
{
return;
}
WelcomeTitle = item.Title;
});
}}
这个类定义也十分简单,通过构造器依赖注入了IDataService 接口对象dataService,接口定义如下:
public interface IDataService
{
void GetData(Action<DataItem, Exception> callback);
}
通过这个接口的定义可以看到,它只有一个包含委托方法Action<DataItem,Exception> callback 参数的GetData方法,这里用到了DataItem参数 作为委托方法的参数,
再看看这个接口的实现类:
public class DataService : IDataService
{
public void GetData(Action<DataItem, Exception> callback)
{
// Use this to connect to the actual data service
var item = new DataItem("Welcome to MVVM Light");
callback(item, null);
}
}
这个类实现了接口方法GetData,并为回调方法提供了数据DataItem实例,在看看DataItem定义
public class DataItem
{
public string Title
{
get;
private set;
}
public DataItem(string title)
{
Title = title;
}
}