MvvmLight - 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,园子里有很不错的教程。
((((((((((下面是一篇转自知乎的文章,解释的也很详细)))))))))))))))))))))))))
我不是程序员只是个软件测试,业余对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的更多相关文章
- Nuget包CommonServiceLocator从1.0.3升级到2.0.4时MvvmLight的ViewModelLocator初始化SimpleIoc.Default格式不匹配问题
原文:Nuget包CommonServiceLocator从1.0.3升级到2.0.4时MvvmLight的ViewModelLocator初始化SimpleIoc.Default格式不匹配问题 把旧 ...
- UWP开发之Mvvmlight实践一:如何在项目中添加使用Mvvmlight(图文详解)
最近一直在做UWP开发,为了节省成本等等接触到MVVMlight,觉得有必要发点时间研究它的用法与实现原理才行.如果有问题的地方或者有好的建议欢迎提出来. 随着移动开发的热门,Mvvmlight在An ...
- ViewModelLocator
ViewModelLocator 这里先鼓舞下士气,ViewModelLocator很简单,甚至可以去掉,它不是Mvvm必须的.在初学Mvvm时,一般都是使用NuGet安装 MvvmLight框架,总 ...
- 【MVVMLight小记】二.开发一个简单图表生成程序附源码
上一篇文章介绍了怎样快速搭建一个基于MVVMLight的程序http://www.cnblogs.com/whosedream/p/mvvmlight1.html算是简单入门了下,今天我们来做一个稍许 ...
- 【MVVMLight小记】一.快速搭建一个基于MVVMLight的silverlight小程序
写了篇MVVM小记http://www.cnblogs.com/whosedream/p/mvvmnote1.html,说好要写点MVVMLight的东西,所以接着写,以便和大家共勉. 我假设你已经有 ...
- 管窥MVVMLight Command参数绑定和事件传递
前言 由于在实际项目中,业务功能的增加导致软件开发规模在逐渐变大,所以我准备找个Silverlight框架来组织当前项目中的文件,以期能够让后续的业务功能增添和维护更加容易一些.无意中,我在这篇文章中 ...
- MvvmLight 绑定
添加MvvmLight引用,通过Nuget: 加载nuget以后会有ViewModelLocator.cs: 新建自己的ViewModel,继承ViewModelBase: View 通过资源引用Vi ...
- MVVMLight leaning note
Learning Note For MvvmLight MvvmLight quitstart refer link1 : MVVMLight HelloWorld *** mc:Ignorable ...
- MvvmLight for Xamarin.Forms
一.Xamarin.Forms 不使用框架时的绑定 需要注意的是BindingContent,不是DataContent <ContentPage xmlns="http://xama ...
随机推荐
- Spring boot整合Mongodb
最近的项目用了Mongodb,网上的用法大多都是七零八落的没有一个统一性,自己大概整理了下,项目中的相关配置就不叙述了,由于spring boot的快捷开发方式,所以spring boot项目中要使用 ...
- OCP 12c最新考试原题及答案(071-4)
4.(4-11) choose two:View the Exhibit and examine the data in the PRODUCT_INFORMATION table.Which two ...
- 为什么要使用rem
为什么要使用rem 今天2019年4月16号更新,模仿网易移动端的的写法: html { font-size: 13.33333vw } @media screen and (max-width:32 ...
- kali linux之msf客户端渗透
在无法通过网络边界的情况下转而攻击客户端----进行社会工程学攻击,进而渗透线上业务网络 含有漏洞利用代码的web站点--利用客户端漏洞 含有漏洞利用代码的doc,pdf等文档----诱使被害者执行p ...
- 二,php的错误处理
php处理错误的三种方式: 简单的die()语句: 自定义错误和错误触发器:错误日志: 1,简单的die()语句 if(!file_exists("aaa.txt")){ die( ...
- 微信小程序之WebSocket
本文版权归 OSChina jsongo0 所有,转载请标明出处,以示尊重! 原文:https://my.oschina.net/jsongo/blog/757871 为什么需要websocket?传 ...
- openstack中安装包与组件
keystone openstack-keystone:验证服务,openstack 中的所有组件的验证以及用户验证,权限,目录等服务. python-openstackclient:命令行,安装以后 ...
- 2016级算法第四次上机-B ModricWang的序列问题
1019 ModricWang的序列问题 思路 此题题意非常清晰,给定一个序列,求出最长上升子序列的长度.从数据规模来看,需要\(O(nlogn)\) 的算法. \(O(nlongn)\) 求最长上升 ...
- 本科生毕业论文->计算机类(1)
写在前面:作为一个计算机类学生,本文只是面向计算机类本科论文进行了一些小经验总结,每个学校的论文要求不一致,具体的参考规范可以看学校的通知,毕业论文作为毕业的一个重要审核标准,写好毕业论文是非常重要的 ...
- Python爬虫:常用的浏览器请求头User-Agent(转)
原文地址:https://blog.csdn.net/mouday/article/details/80182397 user_agent = [ "Mozilla/5.0 (Macinto ...