mvvm和mvvmlight框架介绍及在项目中的使用详解
上一篇我们已经介绍了如何使用nuget把mvvmlight应用到我们的wpf项目中。这篇我们来了解下一个基本的mvvmlight框架所必须的结构和运行模式。
mvvmlight安装之后,我们可以看到简易的框架布局,如上篇,生成了一个viewmodel文件夹,viewmodel层的内容都放在这边,除了main对象的viewmodel之外,还包含一个viewmodellocator文件,
用来注入当前的viewmodel全局实例。
如图:
1、view负责前端展示,与viewmodel进行数据和命令的交互。
2、viewmodel,负责前端视光武帝刘秀图业务级别的逻辑结构组织,并将其反馈给前端。
3、model,主要负责数据实体的结构处理,与viewmodel进行交互。
根据上述的分层,我们来进行编码。
先建立一个完整三层结构的目录,如图,包含model、view、viewmodel三层文件夹:
using galasoft.mvvmlight; using system; using system.collections.generic; using system.linq; using system.text; using system.threading.tasks; namespace mvvmlightdemo.model { public class welcomemodel : obrvableobject { private string introduction; /// <summary> /// 欢迎词 /// </summary> public string introduction { get { return introduction; } t { introduction = value; raipropertychanged(()=>introduction); } } }
很简单,仅仅是包含一个实体对象,这边注意的的是那他继承了一个父类:obrvableobject,这个父类的作用就是保证能够检测属性是否被改变。
它实现了inotifypropertychanged接口,通过触发propertychanged事件达到通知ui更改的目的;
所以我们在定义实体对象的时候,只需要调用raipropertychanged(propertyname)就可以进行属性更改通知了。
所以实体里面定义的每个属性都加上raipropertychanged(propertyname)的调用,就可以实现对ui的交互更新了。
using galasoft.mvvmlight;using mvvmlightdemo.model;using system;using system.collections.generic;using system.linq;using system.text;using system.threading.tasks;namespace mvvmlightdemo.viewmodel{ public class welcomeviewmodel:viewmodelba { /// <summary> /// 构造函数 /// </summary> public welcomeviewmodel() { welcome = new welcomemodel() { introduction = "hello world!" }; } #region 属性 private welcomemodel welcome; /// <summary> /// 欢迎词属性 /// </summary> public welcomemodel welcome { get { return welcome; } t { welcome = value; raipropertychanged(()=>welcome); } } #endregion }}
也很简单,包含了一个命名为welcome的welcomemodel属性,继承了viewbamodel父类,
viewbamodel同时继承 obrvableobject类和icleanup接口。所以他同样有inotifypropertychanged接口的能力,
能够通过触发propertychanged事件达到通知view的目的;
构造函数中对 welcome 属性进行了实例化。
<window x:class="mvvmlightdemo.view.welcomeview" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/prentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" title="welcomeview" height="300" width="300"> <grid> <stackpanel verticalalignment="center" horizontalalignment="center" > <textblock text="{binding welcome.introduction}" fontsize="30" ></textblock> </stackpanel> </grid> </window>
textblock 绑定了 welcome.introduction,所以应该显示welcome对象下的introduction属性。
这时候的viewmodel和view是没有任何关系的,所以我们在code-behind的构造函数中写上如下代码:
using mvvmlightdemo.viewmodel;using system.windows; namespace mvvmlightdemo.view { /// <summary> /// interaction logic for welcomeview.xaml /// </summary> public partial class welcomeview : window { public welcomeview() { initializecomponent(); this.datacontext = new welcomeviewmodel(); } }
把 welcomeviewmodel 赋值给当前视图的数据上下文。所以可以在当前视图中使用viewmodel中所有的公开属性和命令。
执行效果如下:
如果使用nuget安装的是完整的一个是mvvm light 框架,而非 mvvm light libraries only的时候,总是会带上viewmodellocator类,并且生成资源字典并加入到了全局资源中。
<application x:class="mvvmlightdemo.app" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/prentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" startupuri="view/welcomeview.xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" d1p1:ignorable="d" xmlns:d1p1="http://sche消防安全知识教育mas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="clr-namespace:mvvmlightdemo.viewmodel" > <application.resources> <resourcedictionary> <vm:viewmodellocator x:key="locator" d:isdatasource="true" /> </resourcedictionary> </application.resources> </application>
所以每次app初始化的时候,就会去初始化viewmodellocator类。
实际上他就是一个很基本的视图模型注入器。在构造器中把使用到的viewmodel统一注册,并生成单一实例。
然后使用属性把它暴露出来,每当我们访问属性的时候,就会返回相应的viewmodel实例。
/* in app.xaml: <application.resources> <vm:viewmodellocator xmlns:vm="clr-namespace:mvvmlightdemo" x:key="locator" /> </application.resources> in the view: datacontext="{binding source={staticresource locator}, path=viewmodelname}" you can also u blend to do all this with the tool's support. e /d/file/titlepic/ */ using galasoft.mvvmlight; using galasoft.mvvmlight.ioc; using microsoft.practices.rvicelocation; namespace mvvmlightdemo.viewmodel { /// <summary> /// this class contains static references to all the view models in the /// application and provides an entry point for the binding千手杀s. /// </summary> public class viewmodellocator { /// <summary> /// initializes a new instance of the viewmodellocator class. /// </summary> public viewmodellocator() { rvicelocator.tlocatorprovider(() => simpleioc.default); #region code example ////if (viewmodelba.isindesignmodestatic) ////{ //// // create design time view rvices and models //// simpleioc.default.register<idatarvice, designdatarvice>(); ////} ////el ////{ //// // create run time view rvices and models //// simpleioc.default.register<idatarvice, datarvice>(); ////} #endregion simpleioc.default.register<mainviewmodel>(); } #region 实例化 public mainviewmodel main { get { return rvicelocator.current.getinstance<mainviewmodel>(); } } #endregion public static void cleanup() { // todo clear the viewmodels } }
注意的是,这边把mvvmlight 自带的simpleioc作为默认的服务提供者,它是个简易的注入框架。
为了统一化,并且在设计的时候可以看到看到viewmodel的数据,这边用rvicelocator 又将simpleioc包裹了一层。
上面我们写了一个hello world,这时候就可以用这种方式改装了。
/* in app.xaml: <application.resources> <vm:viewmodellocator xmlns:vm="clr-namespace:mvvmlightdemo" x:key="locator" /> </application.resources> in the view: datacontext="{binding source={staticresource locator}, path=viewmodelname}" you can also u blend to do all this with the tool's support. e /d/file/titlepic/ */ using galasoft.mvvmlight; using galasoft.mvvmlight.ioc; using microsoft.practices.rvicelocation; namespace mvvmlightdemo.viewmodel { /// <summary> /// this class contains static references to all the view models in the /// application and provides an entry point for the bindings. /// </summary> public class viewmodellocator { /// <summary> /// initai志愿填报ializes a new instance of the viewmodellocator class. /// </summary> public viewmodellocator() { rvicelocator.tlocatorprovider(() => simpleioc.default); #region code example ////if (viewmodelba.isindesignmodestatic) ////{ //// // create design time view rvices and models //// simpleioc.default.register<idatarvice, designdatarvice>(); ////} ////el ////{ //// // create run time view rvices and models //// simpleioc.default.register<idatarvice, datarvice>(); ////} #endregion simpleioc.default.register<mainviewmodel>(); simpleioc.default.register<welcomeviewmodel>(); } #region 实例化 public mainviewmodel main { get { return rvicelocator.current.getinstance<mainviewmodel>(); } } public welcomeviewmodel welcome { get { return rvicelocator.current.getinstance<welcomeviewmodel>(); } } #endregion public 通假字大全static void cleanup() { // todo clear the viewmodels } }
注册完welcomeviewmodel实例之后,我们就可以在相应的view中使用了 ,原本的
public welcomeview() { initializecomponent(); this.datacontext = new welcomeviewmodel(); }
中的 this.datacontext = new welcomeviewmodel();
可以去掉了,直接在welcomeview中这样写:
datacontext=”{binding source={staticresource locator},path=welcome}”
如下图:
这样做的好处,一个是绑定化相对于简单粗暴的赋值方式,更合理。一个是在可视化窗口可以看到所绑定的数据,达到所见即所得的友好效果。
如下:
当我们改掉绑定到的数据,编译之后就会立马呈现:
服务端开发人员可以专心写viewmodel的业务逻辑代码,ui开发人员可以专注设计视图了,
同样 viewmodel可以绑定到不同的视图上,所以从这边就可以体现出他其中的三个重要特性:低耦合、可重用性、独立开发。
大家有没有发现viewmodellocator 类中还有个 clearnup()方法,主要目的用来清除viewmodel实例的。
viewmodelba继承了galasoft.mvvmlight.icleanup接口,并在自己的类中写好了cleanup()虚方法。所以我们在实例viewmodel类中可以重写cleanup()来达到清除当前实例的目的。
以上就是mvvmlight之modelview结构及全局视图模型注入器的详细内容,更多关于viewmodel结构及全局视图模型注入器的资料请关注www.887551.com其它相关文章!
本文发布于:2023-04-04 21:09:08,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/74395394954909d0c3e8b623633dedf8.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:MVVMLight项目Model View结构及全局视图模型注入器.doc
本文 PDF 下载地址:MVVMLight项目Model View结构及全局视图模型注入器.pdf
留言与评论(共有 0 条评论) |