MVVM Light须要注意的10个问题

从使用XAML技术基础開始(实际上并非非常久曾经)。我便关注MVVM(Model – View – ViewModel)模式。偶然接触到MVVM Light不久后便喜欢上它的工作方式。

不光我包含业余和专业开发者在内的非常多开发者都喜欢这个函数库。

依照开发者意愿,MVVM Light 不是一个框架而是函数库,该函数库注重于探究建立一个MVVM结构而且提供一些额外的帮助类以便于应用。

MVVM Light在发展过程中改变了非常多。非常多元素被增加又有非常多元素被舍弃。但一直保留了高速、易用的轻量级架构。作者Laurent Bugnion,关注于倾听MVVM Light用户的声音,合并特性请求并帮助开发人员。当和一些跟我一起的开发人员聊天的时候。我数次发现某些MVVM Light中的元素他们都没听说过在其他地方也是如此。

我跟用户讨论的时候也学到了非常多MVVM Light的新东西。回想一番后便有了写博客的想法。并以经常使用的“10个关于……”作为标题,这里会告你比較easy忽视的10个MVVM Light隐藏的宝玉。

1、 MVVM Light 安装

这个问题比較显而易见。可是在通过NuGet安装会失去一些长处。MVVM的MSI安装方式不仅给你安装上二进制文件,同一时候也能在VS中提供project、项目模板和非常多snippets。万一VS2012更新2删除了你的模板,能够从C:\Program Files (x86)\Laurent Bugnion (GalaSoft)\Mvvm Light Toolkit\Vsix中又一次安装VSIX。这样就能在VS中获取project模板。

2、 构造器注入

该功能很强大。实际上是多数依赖注入(DI)架构的特性。MVVM Light在应用程序开启后(应用程序生命周期内)使用SimpleIoc注冊viewmodel和service类。构造器注入是指在类的构造函数中能够指定參数,当该类被实例化,SimpleIoc就试探查找同样类型的注冊类作为參数。假设能查找到,这个实例就作为构造函数的參数被注入。以下这个样例,演示在ViewModelLocator中注冊navigation service.

Code Snippet

SimpleIoc.Default.Register<INavigationService, NavigationService>();

我们打算在控制反转(IOC)容器中注冊INavigationService。当它创建实例,我们希望它的类型是NavigationService。眼下IOC 容器中该“记录”并没有实例。当首次从容器中获取时才干被实例化。有时候当你注冊后立刻想创建实例,SimpleIoc重载函数Register<T>就可以实现该功能。

Code Snippet

1. SimpleIoc.Default.Register<INavigationService, NavigationService>(true);

只将參数输入为true就能立刻创建实例,如今。我们打算在MainViewModel中使用NavigationService。

Code Snippet

1. ///<summary>

2. /// Initializes a new instance of the MainViewModel class.

3. ///</summary>

4. public MainViewModel(INavigationService navigationService)

5. {

6.

7. }

SimpleIoc 会查找注冊的INavigationService 类型而且在构造函数中注入它。这节省了我们手工接触IOC容器和索取正确实例的麻烦。

警告:要注意,在IOC容器中注冊类的顺序很重要,特别是使用重载函数创建实例时。

假设在NavigationService 被注冊之前创建MainViewModel 。那就会得到空引用的异常。

3. 替代SimpleIoc

SimpleIoc库执行的非常棒,是一个非常酷的轻量级的MVVM Light加入物,并且它的确非常轻量级。它是非常有用的方案可是对于比較大的应用就不那么好用了(或者你像我一样打算试一下替代它有多困难)。在这个样例中我会用AutoFac替代SimpleIoc,AutoFac是一个非常有名且强大的IOC service。

首先,我们要获取AutoFac库和extra库以像SimpleIoc一样使用ServiceLocator。因此不论从控制台还是用户界面为AutoFac加入CommonServiceLocator extra。AutoFac库是被依赖库因此要安装正确。

使用全新的Windows Phone8项目開始MVVM Light项目模板。

Code Snippet

1. Install-Package Autofac.Extras.CommonServiceLocator

只须要被改动代码的一个地方在ViewModeeLocator。

在这个新的ViewModelLocator构造函数中,我凝视了原先SimpleIoc代码方便于两者对照。

Code Snippet

1. static ViewModelLocator()

2. {

3.     var container = newContainerBuilder();

4.

5.     //ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

6.     ServiceLocator.SetLocatorProvider(() => new AutofacServiceLocator(container.Build()));

7.

8.     if (ViewModelBase.IsInDesignModeStatic)

9.     {

10.         //SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();

11.         container.RegisterType<Design.DesignDataService>().As<IDataService>();

12.     }

13.     else

14.     {

15.         //SimpleIoc.Default.Register<IDataService, DataService>();

16.         container.RegisterType<DataService>().As<IDataService>();

17.     }

18.

19.     //SimpleIoc.Default.Register<MainViewModel>();

20.     container.RegisterType<MainViewModel>();

21. }

我们声明了ContainerBuilder,把它设置为LocatorProvider。如今容器被用于注冊我们须要的全部东西。通过注冊创建实例的SimpleIoc重载。在AutoFac中呈现例如以下。

Code Snippet

1. container.RegisterInstance(newDataService()).As<IDataService>();

就这样。构造器注入可以像原来的SimpleIoc正确执行。

4. Built-in messages

MVVM Light的messager能将类注冊为Listeners而且可以将消息发送给这些类。这通常应用在viewmodel之间,一般我会创建各种类型的消息来发送,可是MVVM Light本身创建了非常多messages供我们调用。

消息GenericMessage<T>(T content)能包括全部的类型。

Code Snippet

1. Messenger.Default.Send(newGenericMessage<string>("my message"));

消息NotificationMessage(string notification)包括notification,能被用于发送notification给notification工厂用以用合适的方式显示消息。

Code Snippet

1. try

2. {

3.     //try something

4. }

5. catch (Exception ex)

6. {

7.     Messenger.Default.Send(newNotificationMessage(ex.Message));

8. }

NotificationMessage<T>(T notification)可能相同是你须要的。

另外一个是 NotificationMessageAction(string notification, Action callback) 基于 NotificationMessage 可是你能加入回调行为。该行为会在消息被接收时启动。它也有类似于implementation的一般实现。

DialogMessage(string content, Action<MessageBoxResult> callback) 这个消息是让用户输入并在參数MessageBoxResult中返回结果。

MessageBoxResult是System.Windows中的枚举。

Code Snippet

1. publicenumMessageBoxResult

2. {

3.   None = 0,

4.   OK = 1,

5.   Cancel = 2,

6.   Yes = 6,

7.   No = 7,

8. }

Code Snippet

1. Messenger.Default.Send(newDialogMessage("Are you sure?

", result =>

2.     {

3.         if (result == MessageBoxResult.Yes)

4.         {

5.             //do something

6.         }

7.     }));

DialogMessage 继承于GenericMessage<string>。

PropertyChangedMessage 是使用在RaisePropertyChanged 的实现,多用于多个viewmodel须要响应属性变化时。

Code Snippet

1. publicstring WelcomeTitle

2. {

3.     get

4.     {

5.         return _welcomeTitle;

6.     }

7.

8.     set

9.     {

10.         if (_welcomeTitle == value)

11.         {

12.             return;

13.         }

14.

15.         Messenger.Default.Send(newPropertyChangedMessage<string>(_welcomeTitle, value, "WelcomeTitle"));

16.

17.         _welcomeTitle = value;

18.         RaisePropertyChanged(WelcomeTitlePropertyName);

19.     }

20. }

特别注意注冊监听者。尝试使用尽可能多的不同消息类型是有意义的。你并不想让一个错误的监听者收到消息由于它可能恰好听到同样的信息。例如以下所看到的注冊监听者。

Code Snippet

1. Messenger.Default.Register<PropertyChangedMessage<string>>(this, message =>

2.     {

3.         var a = message.NewValue;

4.         //do something

5.     } );

5. Portable libraries

MVVM Light在不论什么基于XAML平台都有效。而且眼下迎来了便携版,便携版单独的类库在NuGet上。

Code Snippet

1. Install-Package Portable.MvvmLightLibs

假设你决定使用便携版,要确定你解决方式中每个项目都要使用MVVM Light类库引用。它跟经常使用的MVVM Light类库并不共用。当你使用了PCL版本号。你可把你的viewmodel在单独的、便携式的类库中和他们分享比方,Windows Store 或者Windows Phone app。

6. Event to Command behavior

MVVM Light有ICommand的实现叫做RelayCommand,可用于绑定行为。比方XAML中的button有命令属性可用于绑定在ICommand类型的datacontext。因此当button被点击后ICommand会被启动。不幸的并不是全部XAML的UI元素都有可绑定的属性用于他们可以触发的事件并且这是EventToCommand执行的地方。通过EventToCommand 你能绑定XAML UI元素全部事件到相应viewmodel中的ICommand实现中。

首先我们须要在XAML页面中加入两个namespaces

First we’ll need two namespaces in our XAML page

Code Snippet

1. xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

2. xmlns:command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP8"

以下介绍我们打算在stackpanel中使用的Tap事件。

Code Snippet

1. <StackPanel Grid.Row="0" Orientation="Horizontal">

2.     <i:Interaction.Triggers>

3.         <i:EventTrigger EventName="Tap">

4.             <command:EventToCommand Command="{Binding GoToCommand}" CommandParameter="Edit" />

5.         </i:EventTrigger>

6.     </i:Interaction.Triggers>

第三行指出了我们想处理的事件,注意这是一个string所以要意识到(是否)错误。第四行绑定命令行为而且将參数传给了ICommand实现。

Code Snippet

1. privateRelayCommand<string> _goToCommand;

2. publicRelayCommand<string> GoToCommand

3. {

4.     get { return _goToCommand jQuery15206875578026641675_1366095632942 (_goToCommand = newRelayCommand<string>(NavigateAway)); }

5. }

方法NavigateAway 例如以下所看到的。

Code Snippet

1. privatevoid NavigateAway(string parameter)

參数以使用XAML中的单词“Edit”,我们甚至能够在第4行中从事件到命令直接传递事件參数。例如以下所看到的

Code Snippet

1. <command:EventToCommand PassEventArgsToCommand="True" Command="{Binding GoToCommand}" />

Windows Store applications并没有创造性的拥有这些行为,因此你不能使用EventToCommand除非从NuGet安装了Win8nl toolkit。

Joost Van Schaik在WinRT中创建了他自己的行为实现,感谢他的成果(还有非常多其它人在这个项目中给予帮助)我们如今能在WinRT中使用EventToCommand。

7. DispatcherHelper

自从.net4.5我们就有了await/asynckeyword而且成了同步使用的良好的一员。也就意味着假设我们打算更新UI线程的活动我们须要使用Dispatcher类以在UI线程中调用我们的行为。普通情况下我们并不须要在自己的viewmodel类中使用Dispatcher。MVVM Light包括DispatcherHelper能在须要的时候运行UI 线程行为。

Code Snippet

1. DispatcherHelper.CheckBeginInvokeOnUI(() =>

2.     {

3.         //do something

4.     });

DispatcherHelper在App.xaml.cs或者InitializePhoneApplication(WP8项目)方法中被初始化。

DispatcherHelper相同有个RunAsync ,跟CheckBeginInvokeOnUI的不同是CheckBeginInvokeOnUI首先检查是否已经在UI线程上了,假设在线程上就运行行为,假设不在UI线程上就调用RunAsync方法。

8. Blendable

MVVM Light有完整的Blend支持,也就是你能够从viewmodel拖放属性到view以生成binding,或者你能在设计时生成基于datacontext的数据。我并不数序Blend所以也不再详述。仅仅要心中记着MVVM Light能够在Blend中构建就能够了。

9. Open Source

这点你可能知道可是MVVM Light是全然开源的。假设打算下载源码查找地址http://mvvmlight.codeplex.com/ 。

10. Laurent is on Twitter and he’s a nice guy

Laurent Bugnion,MVVM Light的创始者,也在Twitter上https://twitter.com/LBugnion

Laurent Bugnion, the founder of MVVM Light, is on Twitter! 他非常善聊也非常渴望帮助不论什么须要帮助的人。

Conclusion

总结

MVVM Light是一个带有些许宝石伟大的库。

在这篇文章中我讨论了8个能够让开发人员生活简单的有趣话题,我保留了2个额外的项目,由于10这个数字比8要好。

原文地址:点击打开链接

MVVM Light须要注意的10个问题的更多相关文章

  1. WPF学习10:基于MVVM Light 制作图形编辑工具(1)

    图形编辑器的功能如下图所示: 除了MVVM Light 框架是一个新东西之外,本文所涉及内容之前的WPF学习0-9基本都有相关介绍. 本节中,将搭建编辑器的界面,搭建MVVM Light 框架的使用环 ...

  2. 【MVVM Light】新手初识MVVM,你一看就会

    一.前言 作为一个初入软件业的新手,各种设计模式与框架对我是眼花缭乱的.所以当我接触到这些新知识的时候就希望自己能总结几个步骤,以便更好更方便的在日常工作中进行使用. MVVM顾名思义就是Model- ...

  3. MVVM Light中的Message

    比喻:像漂流瓶一样发送一个Message,任何人有兴趣就可以拾起来. MVVM Light中的Message的使用分为三个步骤: 1.创建一个类,包含要传递的Message. 2.在ViewModel ...

  4. MVVM Light 笔记

    4.关于子视图, MVVMLight Using Two Views:http://www.codeproject.com/Articles/323187/MVVMLight-Using-Two-Vi ...

  5. WPF学习12:基于MVVM Light 制作图形编辑工具(3)

    本文是WPF学习11:基于MVVM Light 制作图形编辑工具(2)的后续 这一次的目标是完成 两个任务. 本节完成后的效果: 本文分为三个部分: 1.对之前代码不合理的地方重新设计. 2.图形可选 ...

  6. WPF学习11:基于MVVM Light 制作图形编辑工具(2)

    本文是WPF学习10:基于MVVM Light 制作图形编辑工具(1)的后续 这一次的目标是完成 两个任务. 画布 效果: 画布上,选择的方案是:直接以Image作为画布,使用RenderTarget ...

  7. 【MVVM Light】Messager的使用

    一.前言       在MVVM编程的模式中,有时候我们会遇到一个很尴尬的情况: 若干个xaml.cs都复用一个ViewModel,当ViewModel想传递一个特定的消息给某一个xaml.cs的时候 ...

  8. MVVM Light 一个窗口承载两个视图

    MVVM Light 一个窗口承载两个视图   原文地址:http://www.codeproject.com/Articles/323187/MVVMLight-Using-Two-Views 本文 ...

  9. Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架

    Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架   本章节,我将通过示例介绍如何搭建mvvmlight开发环境.示例中的我会针对wpf ...

随机推荐

  1. Leetcode 线性表 Swap Nodes in Pairs

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie Swap Nodes in Pairs Total Accepted: 12511 Tota ...

  2. 异步的两种写法: async 与 BeginInvoke

    现在要实现异步只要用关键字async/await就可以轻松实现,在此之前需要用到委托/回调等一堆东西. 对一下是对比写法: class Program { delegate string SendMe ...

  3. WCF技术剖析之二十一:WCF基本异常处理模式[中篇]

    原文:WCF技术剖析之二十一:WCF基本异常处理模式[中篇] 通过WCF基本的异常处理模式[上篇], 我们知道了:在默认的情况下,服务端在执行某个服务操作时抛出的异常(在这里指非FaultExcept ...

  4. oncreate 测量尺寸

    在android中,在oncreate里面只是将布局信息设置好,并没有进行布局,因此是没法进行测量view或者屏幕的长高,可以通过下面的observer来观察,当view布局完成之后会回调下面的两个接 ...

  5. Eclipse用法和技巧五:生成说明文档2

    上面一篇文章里面我们介绍了一种生成可以被JDK提取到,生成JavaDoc的添加注释方法.下面再补充一种生成这种注释的方法,上图: 步骤一:光标移动到需要添加注释的语句旁边,快捷键:shift + al ...

  6. SIMPASS技术解析

    一.什么叫SIMPASS SIMpass技术融合了DI卡技术和SIM卡技术,或者称为双界面SIM卡.SIMpass是一种多功能的SIM卡,支持接触与非接触两个工作接口,接触界面实现SIM功能,非接触界 ...

  7. mysql 密码过期问题 password_expired

    mysql> select user,host,password_expired from mysql.user; +-----------------+----------------+--- ...

  8. 怎样查看apk须要支持的Android版本号

    假设有一个apk,须要知道他最低安装支持的Android版本号是什么,应该怎样查看呢? 直接将apk后缀名改为rar或者zip,拉出AndroidManifest.xml?不行,AndroidMani ...

  9. 逻辑与(&&、&)和逻辑或(||、|)

    这四个逻辑运算符,大家都知道,但是有时候会凌乱,这里用程序来解释一下,以免忘了.(根据大家反应说:这文章没有解释清楚它们的区别.用法,其实文章主要说的是,如果将这四个运算符用于条件判断,那么它们会是什 ...

  10. vue.js+boostrap

    vue.js+boostrap最佳实践 一.为什么要写这篇文章 最近忙里偷闲学了一下vue.js,同时也复习了一下boostrap,发现这两种东西如果同时运用到一起,可以发挥很强大的作用,boostr ...