这里先鼓舞下士气,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,园子里有很不错的教程

((((((((((下面是一篇转自知乎的文章,解释的也很详细)))))))))))))))))))))))))

我不是程序员只是个软件测试,业余对WPF C#感兴趣也自学了点,正好mvvmlight也自学过,半吊子我也不能回答的很专业,请包涵。希望下面高人能有更好的解释。
SimpleIoc 是一个简单依赖注入容器, 至于什么是依赖注入可以在百度经验找到很通俗的解释。微软还有自己的类似的框架叫MEF,两者用起来异曲同工,甚至我觉得MEF更简洁强大。


查看SimpoleIoc的定义就会知道SimpleIoc其实实现了IServiceLocator,SimpleIoc就是一个
IServiceLocator。而ServiceLocator这个是一个静态类是用来获取当前使用中的IServiceLocator的。
SimpleIoc的作用是,所有通过SimpleIoc的GetInstance方法创建的实例,都会自动从容器里自动组装。
自动组装什么意思看下面例子。

比方说你有个服务MyDataService,这个服务是用来获取数据的,而这个服务是实现自IDataService这个接口。
然后你有个MainViewModel,他的构造函数是 MainViewModel(IDataService dataSevice)

一般情况下你要 创建MainViewModel的实例你还得手动把一个具体的IDataService也创建好传入。
而用SimpleIoc帮你组装的话你就不需要这么做了。

你将实现了接口的服务向下面这样注册到SimpleIoc里。
SimpleIoc.Default.Register<IDataService, MyDataService>();
然后将MainViewModel也注册到SimpleIoc里。
SimpleIoc.Default.Register<MainViewModel>();


后通过 SimpleIoc.Default.GetInstance<MainViewModel>()
就可以直接创建一个实例,SimpleIoc在发现
MainViewModel的构造函数有参数的时候会自动去找所有注册到SimpleIoc的类型看哪个符合这个参数类型,如果之前已经创建过这个类型就
直接拿缓存传入,如果没有就立刻创建一个实例传入并缓存。这就是注入,你的ViewModel需要什么样的具体服务是Simploc在帮你创建传入的,这
样你的ViewModel就不依赖具体的Service了。

我之前还翻译了StackOverFollow上的一个关于SimpleIoc用法的提问,贴出来希望能帮到你。
SimpleIoc crib sheet:
1) You register all your interfaces and objects in the ViewModelLocator
你需要将所有的接口和对象注册到ViewModelLocator
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>();
SimpleIoc.Default.Register<SecondViewModel>();
}
public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
}
2)
Every object is a singleton by default. To resolve an object so that
it's not a singleton you need to pass a unique value to the GetInstance
call:
默认Ioc
Getinstance获取的所有的对象都是单例的。如果想要每次getinstance都是独一无二的对象那么你需要在GetInstance的时候传
入唯一的值来标志这个对象,也就是String
key,你可以使用Guid创建这个唯一的标识,Guid.NewGuid()每次调用都会产生唯一的值。
SimpleIoc.Default.GetInstance<MainViewModel>(Guid.NewGuid().ToString());
3) To register a class against an interface:
将一个类注册到对应接口
SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
4) To register a concrete object against an interface:
将一个具体对象注册到对应接口
SimpleIoc.Default.Register<IDataService>(myObject);
5) To register a concrete type:
注册一个具体的类
SimpleIoc.Default.Register<MainViewModel>();
6) To resolve an object from an interface:
根据接口返回对象
SimpleIoc.Default.GetInstance<IDataService>();
7) To resolve an object directly (does buildup and dependency resolution):
返回一个具体类对象,并依赖注入。
注:
例如 MainViewModel的构造函数是MainViewModel(IDataService
dataservice),那么这次GetInstance<MainViewModel>()会同时从Ioc里将
MainViewModel依赖的具体IDataService传进去。
SimpleIoc.Default.GetInstance<MainViewModel>();
8) MVVM makes doing design-time data really easy:
用MVVM做设计时数据非常简单
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
}
else
{
SimpleIoc.Default.Register<IDataService, DataService>();
}
If
you're in design-time mode it will automatically register your
design-time services, making it really easy to have data in your
viewmodels and views when working in the VS designer.
如果你在设计时模式,ioc会自动注册设计时服务,这样你的viewmodels在未编译的状态下就填充了设计时数据,可以在设计器上直接观察。
Hope this helps.
希望这些能帮到你。
https://www.zhihu.com/question/36338698
来自 <c# - how to use MVVMLight SimpleIoc?>

MvvmLight - ViewModelLocator的更多相关文章

  1. Nuget包CommonServiceLocator从1.0.3升级到2.0.4时MvvmLight的ViewModelLocator初始化SimpleIoc.Default格式不匹配问题

    原文:Nuget包CommonServiceLocator从1.0.3升级到2.0.4时MvvmLight的ViewModelLocator初始化SimpleIoc.Default格式不匹配问题 把旧 ...

  2. UWP开发之Mvvmlight实践一:如何在项目中添加使用Mvvmlight(图文详解)

    最近一直在做UWP开发,为了节省成本等等接触到MVVMlight,觉得有必要发点时间研究它的用法与实现原理才行.如果有问题的地方或者有好的建议欢迎提出来. 随着移动开发的热门,Mvvmlight在An ...

  3. ViewModelLocator

    ViewModelLocator 这里先鼓舞下士气,ViewModelLocator很简单,甚至可以去掉,它不是Mvvm必须的.在初学Mvvm时,一般都是使用NuGet安装 MvvmLight框架,总 ...

  4. 【MVVMLight小记】二.开发一个简单图表生成程序附源码

    上一篇文章介绍了怎样快速搭建一个基于MVVMLight的程序http://www.cnblogs.com/whosedream/p/mvvmlight1.html算是简单入门了下,今天我们来做一个稍许 ...

  5. 【MVVMLight小记】一.快速搭建一个基于MVVMLight的silverlight小程序

    写了篇MVVM小记http://www.cnblogs.com/whosedream/p/mvvmnote1.html,说好要写点MVVMLight的东西,所以接着写,以便和大家共勉. 我假设你已经有 ...

  6. 管窥MVVMLight Command参数绑定和事件传递

    前言 由于在实际项目中,业务功能的增加导致软件开发规模在逐渐变大,所以我准备找个Silverlight框架来组织当前项目中的文件,以期能够让后续的业务功能增添和维护更加容易一些.无意中,我在这篇文章中 ...

  7. MvvmLight 绑定

    添加MvvmLight引用,通过Nuget: 加载nuget以后会有ViewModelLocator.cs: 新建自己的ViewModel,继承ViewModelBase: View 通过资源引用Vi ...

  8. MVVMLight leaning note

    Learning Note For MvvmLight MvvmLight quitstart refer link1 : MVVMLight HelloWorld *** mc:Ignorable ...

  9. MvvmLight for Xamarin.Forms

    一.Xamarin.Forms 不使用框架时的绑定 需要注意的是BindingContent,不是DataContent <ContentPage xmlns="http://xama ...

随机推荐

  1. 【selenium专题】元素定位之多层框架和窗口

    本节知识点 多层框架或窗口切换样式:WebDrvier.switchto().TargetLocator Interface WebDriver.TargetLocator下所有可切换对象 参考API ...

  2. nowcoder(牛客网)OI测试赛3 解题报告

    昨天因为胡搞了一会儿社团的事情,所以错过(逃过)了nowcoder的测试赛..... 以上,听说还是普及组难度qwq,而且还有很多大佬AK(然而我这么蒻肯定还是觉得有点难度的吧qwq) 不过我还是日常 ...

  3. Python一篇学会多进程

    阅读目录 1. Process 2. Lock 3. Semaphore 4. Event 5. Queue 6. Pipe 7. Pool 序. multiprocessing python 中的多 ...

  4. [ActionScript 3.0] 翻牌效果,运用语法rotationY,PerspectiveProjection

    package { import com.tweener.transitions.Tweener; import flash.display.Bitmap; import flash.display. ...

  5. 极光开发者沙龙 JIGUANG MEETUP —— 移动应用性能优化实践

    活动背景 移动互联网时代,各大互联网公司都已将自己的产品和服务全面移动化,各类新产品功能都会优先在移动 App 上尝试. 应用性能作为影响用户体验最重要的因素,在开发过程中显得尤为重要. 用户网络环境 ...

  6. fastcgi main

    main函数里 当kill -TERM pid 时, http://redfoxli.github.io/php-fpm-signals.html  这篇文章 说是 1)master主进程接收到sig ...

  7. 2019.2.15 t2

    考虑倒过来计算最短路径长度,设dis[u]表示在最坏情况下,点u到最近的一 个出口的最短路,则p个出口的dis值都是0,答案即为dis[0]. #include <cstdio> #inc ...

  8. 理解webpack中的publicPath

    outPut中的publicPath 默认值: 空字符串. publicPath是非常有必要配置的,他是项目中引入静态资源(js.css)时的基础路径. 例如: outPut.publicPath = ...

  9. 获取dataGridView双击时判断双击的是下面的行,还是列头

    private void dataGridView1_DoubleClick(object sender, EventArgs e) { Point hit = this.dataGridView1. ...

  10. 获取指定<文字行数>的<高度>是多少 TextKit

    - (CGSize)maxLineSizeWithLines:(NSInteger)lines constraintSize:(CGSize)size attributes:(NSDictionary ...