本篇是MvvmLight框架使用入门的第三篇。从本篇开始,所有代码将通过Windows 10的Universal App来演示。我们将创建一个Universal App并应用MvvmLight框架。

  首先通过VS2015创建一个名为UniversalApp的空工程(工程类型为Universal Windows),然后通过NuGet获取MvvmLight,这里需要注意的是,我们选择MvvmLightLib仅下载DLL文件,因为MvvmLight还未对Universal App做适配,并不会自动创建ViewModel以及ViewModelLocator等文件。

  在创建UniversalApp完成后,将上一篇创建的HelloMvvmLight工程中的ViewModel文件夹整个拷贝到UWP工程里(注意修改namespace)。这样MainViewModel以及ViewModelLocator文件就有了。

接着在App.xaml的Resources中添加对ViewModelLocator的引用:

    <Application.Resources>
<ResourceDictionary>
<vm:ViewModelLocator x:Key="Locator" />
</ResourceDictionary>
</Application.Resources>

  这里需要注意保持namespace和ViewModel的namespace一致:xmlns:vm="using:UniversalApp.ViewModel"

  再下一步就是修改MainPage.xaml文件,将xaml的内容修改如下:

    <Page.DataContext>
<Binding Path="Main" Source="{StaticResource Locator}"></Binding>
</Page.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Title}"></TextBlock>
<Button Grid.Row="1" Command="{Binding ChangeTitleCommand}">Click Me!</Button>
</Grid>

  至此,一个简单的使用了MvvmLight框架的Uinversal App就完成了。

  按下Ctrl+F5,一个Win10风格的窗体就出现了。(细心的童鞋会发现Button默认不再撑开了)

  当然本篇不会只有这点东西,我们会进一步介绍MvvmLight框架在Universal App下的使用。

  接下来我们增加第二个页面,来看一下MvvmLight对页面间导航的支持。

  第一步新建PageTwoViewModel类:

    public class PageTwoViewModel
{
private INavigationService _navigationService; public ICommand GoBackCommand { get; set; } public PageTwoViewModel(INavigationService navigationService)
{
_navigationService = navigationService;
GoBackCommand = new RelayCommand(()=> { _navigationService.GoBack(); });
}
}

  INavigationService是MvvmLight为了抽象各类型的工程(WPF,Silverlight,Windows Runtime)不同的导航方法,而设计的接口,定义如下:

    public interface INavigationService
{
string CurrentPageKey { get; } void GoBack(); void NavigateTo(string pageKey); void NavigateTo(string pageKey, object parameter);
}

  通过string字符串确认唯一页面来进行跳转和返回,并可以传递object类型的参数。

  ViewModelLocator类注册PageTwoViewModel,以及创建INavigationService的实例并关联各Page。

        public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<MainViewModel>();
SimpleIoc.Default.Register<PageTwoViewModel>(); var navigationService = this.CreateNavigationService();
SimpleIoc.Default.Register<INavigationService>(() => navigationService);
} private INavigationService CreateNavigationService()
{
var navigationService = new NavigationService();
navigationService.Configure("MainPage", typeof(MainPage));
navigationService.Configure("PageTwo", typeof(PageTwo)); return navigationService;
} public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
} public PageTwoViewModel PageTwo
{
get
{
return ServiceLocator.Current.GetInstance<PageTwoViewModel>();
}
}
}

  至于为什么只要在PageTwoViewModel的构造函数参数中带有INavigationService,即可由IOC自动获取实例navigationService则超出了本文讨论的范围,有兴趣的同学自行学习。

  构建PageTwo.xaml页面并关联至PageTwoViewModel。

    <Page.DataContext>
<Binding Path="PageTwo" Source="{StaticResource Locator}"></Binding>
</Page.DataContext>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Text="Page Two"></TextBlock>
<Button Grid.Row="1" Command="{Binding GoBackCommand}">Go Back</Button>
</Grid>
</Grid>

  修改MainViewModel类,增加GotoNextCommand等方法。同时我们可以看到手动获取navigationService对象的方法。

    public class MainViewModel : ViewModelBase
{
private string title; public string Title
{
get { return title; }
set { Set(ref title , value); }
} public ICommand ChangeTitleCommand { get; set; } public ICommand GotoNextCommand { get; set; } public MainViewModel()
{
Title = "Hello World";
ChangeTitleCommand = new RelayCommand(ChangeTitle);
GotoNextCommand = new RelayCommand(GotoNext);
} private void GotoNext()
{
var navigationService = ServiceLocator.Current.GetInstance<INavigationService>();
navigationService.NavigateTo("PageTwo");
} private void ChangeTitle()
{
Title = "Hello MvvmLight";
}
}

  MainPage.xaml仅仅是增加了一个GotoNext的Button:

<Button Grid.Row="2" Command="{Binding GotoNextCommand}">Go to Next!</Button>

  大功告成,按下Ctrl+F5试试吧。

  使用MvvmLight框架中的INavigationService来进行页面导航,虽然相对使用Frame导航稍稍增加了工作量,但具有以下几点好处:

  1.   不依赖具体的工程实现(WPF,Sliverlight,Windows Runtime)。
  2.   View和ViewModel不直接产生依赖,双方通过中介INavigationService打交道。也就是说ViewModel中不会出现Windows.UI.Xaml.Controls的namespace。
  3.   将跳转的实现代码从View转移到ViewModel,使得单元测试可以脱离View,完全的通过ViewModel的UT即可测试跳转的逻辑。

MvvmLight框架使用入门(三)的更多相关文章

  1. MvvmLight框架使用入门(四)

    本篇我们着重介绍ViewModelBase,演示Set和RaisePropertyChanged方法的使用,以及就Cleanup方法释放资源展开讨论. ICleanup 接口.实现该接口的ViewMo ...

  2. MvvmLight框架使用入门(5)

    上一次写MvvmLight框架使用入门(4)的时候还在用Visual Studio 2015,我儿子也不会过来盖上我的XPS……重启这个系列一方面是因为最近又开始写UWP的东西了,另一个是因为Mvvm ...

  3. MvvmLight框架使用入门(一)

    MvvmLight是比较流行的MVVM框架,相对较为简单易用.可能正因为简单,对应的帮助文档不多,对初学者就不够友好了.这里会用几篇随笔,就个人对MvvmLight的使用经验,来做一个入门的介绍. 第 ...

  4. MvvmLight框架使用入门(二)

    上一篇我们简单对MvvmLight做了介绍.罗列了三个DLL中,各个命名空间下主要类的定义及大致作用.因为只是范范的概论,对于从未接触过MvvmLight的萌新来说,根本就是在晃点他们.不过万事开头难 ...

  5. MyBatis框架之入门(三)

    使用原始dao层进行开发 UserMapper层接口 public interface UserMapper { /** * 通过id查询用户 * @param id * @return */ Use ...

  6. 实体框架 (EF) 入门 => 三、CodeFirst 支持的完整特性列表

    KeyAttribute 设置主键.如果为int类型,将自动设置为自增长列. 系统默认以Id或类名+Id作为主键.StringLengthAttribute 可设置最大最小长度以及验证提示信息等.最大 ...

  7. Mybatis框架基础入门(三)--Mapper动态代理方式开发

    使用MyBatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper动态代理开发方法. 原始Dao开发方法需要程序员编写Dao接口和Dao实现类,此方式开发Dao,存在以下问题: Dao方 ...

  8. 【原创】NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战

    前言 本文将演示一个iOS客户端程序,通过UDP协议与两个典型的NIO框架服务端,实现跨平台双向通信的完整Demo.服务端将分别用MINA2和Netty4进行实现,而通信时服务端你只需选其一就行了.同 ...

  9. Thinkphp入门三—框架模板、变量(47)

    原文:Thinkphp入门三-框架模板.变量(47) [在控制器调用模板] display()   调用当前操作名称的模板 display(‘名字’)  调用指定名字的模板文件 控制器调用模板四种方式 ...

随机推荐

  1. 简单的TCP代理服务器

    我之前的一篇文章(http://www.cnblogs.com/MikeZhang/archive/2012/03/07/socketRedirect.html )中介绍过用python写的一个简单的 ...

  2. Docker,win10

    win10:docker下载地址 直接下载docker ,no docker toolbox https://get.daocloud.io/toolbox/ 下载完成,双击安装,next知道完成安装 ...

  3. HTTP代理器Fiddler(三)

    HTTP代理神器Fiddler Fiddler是一款强大Web调试工具,它能记录所有客户端和服务器的HTTP请求. Fiddler启动的时候,默认IE的代理设为了127.0.0.1:8888,而其他浏 ...

  4. 基于 Lucene 的桌面文件搜索

    开源2010年,自己在学习 Lucene 时开发的一款桌面文件搜索工具,这么多年过去了,代码一直静静存放在自己的硬盘上,与其让其沉睡,不如分享出来. 这款工具带有明显的模仿 Everything 的痕 ...

  5. Spring集成的Quartz 并发

    以前经常在任务调度程序中使用Spring集成的Quartz,这种方式可以用简单的声明式配置即可实现定时任务,并结合了Spring自身的Bean的管理功能,非常方便.配置样本如下: <bean i ...

  6. c#,读取二维码

    /// <summary>/// 读取二维码/// 读取失败,返回空字符串/// </summary>/// <param name="filename&quo ...

  7. open方法读写文件

    vb使用open方法读写文件 (一)打开和关闭文件 1.顺序文件 打开顺序文件,我们可以使用Open语句.它的格式如下: Open pathname For [Input |Output |Appen ...

  8. android手机 ping 虚拟机ubuntu的ip地址

    今天使用android手机往虚拟机上ubuntu 上搭建的nginx 和rtmp服务器推送东西的时候,怎么都推不上去. 后来在windows下的cmd里: # adb shell # ping 192 ...

  9. c# 后台调用接口接收传过来的json

    public string GetRequestTest(string url) { HttpWebRequest httpWebRequest = (HttpWebRequest)WebReques ...

  10. MyBatis 提供的内置类型别名