MvvmLigth框架利器之INavigationService

标题有点唬人哈,其实是我自己按照平时UWP/WP项目开发的使用经验给INavigationService加封的,由于网络中关于Mvvmlight框架的INavigationService的资料比较少,所以在此做个笔记,一来记录知识以防忘记,二来希望对用到INavigationService的朋友有所帮助。

Mvvmlight在平时开发中最常用到的利器有五个:

1、ViewModelBase VM鼻祖
2、RelayCommand命令
3、Messenger消息通
4、DispatcherHelper 多线程处理
5、INavigationService导航服务
 
ViewModelBase VM基类,里面提供了VM中常用的方法。

RelayCommand命令,这东西在UWP出来之前使用率是很高的,UI上的Command绑定VM方法是必须用到RelayCommand,用来解耦很是方便实用,不过UWP中基本就用不到它了,UWP中的UI事件可以直接绑定到方法名,RelayCommand便从此可以在UWP项目代码中退隐江湖了。

Messenger消息通知,这个谁用谁知道,不过建议大家用的时候仔细考虑下要做的Action是否超出了VM本身的职责,不然不要滥用,不然项目逻辑太过于分散。Messenger的设计初衷就是用来使VM与View能够相互通信,VM告诉View我事情做完了接下来你要接着做你的事情,这种情况下才适合使用Messenger,千万不要在VM内部滥用Messenger。

DispatcherHelper多线程处理,这个用来帮助我们在非UI线程上处理UI线程对象的帮助类,也非常好用。

前四个本文章内不做过多的讲解,本文的主要内容是INavigationService的使用。

INavigationService导航服务,这家伙是为了项目解耦、平台自适应而诞生的。它的作用主要是用来导航界面(这不是废话么),但最重要的是它能在VM中直接发起导航界面来完成导航。让导航脱离具体的Page对象,减少了VM与View的耦合,而且还不受平台的限制,使用它进行导航,即使平台之间各自导航的方法各异,也完全不受影响。


好处都说了多么多,那具体该怎么使用呢?想要使用INavigationService需要先在SimpleIoc.Default中注册一个NavigationService对象,NavigationService对象继承与INavigationService,提供了常用的导航方法如下:

public void GoBack();
public void NavigateTo(string pageKey);
public virtual void NavigateTo(string pageKey, object parameter);


而NavigateTo导航方法中需要提供的是string类型的参数,通过该参数与Configure属性中具体的Page映射关系来确定要导航到哪一页。打开ViewModelLocator类文件在Ioc容器中注册NavigationService对象,具体代码如下:

public ViewModelLocator()
{
    ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
 
    //注册VM
    SimpleIoc.Default.Register<MainPageViewModel>();
    SimpleIoc.Default.Register<Page1ViewModel>();
    SimpleIoc.Default.Register<Page2ViewModel>();
 
    //注册导航服务对象
    SimpleIoc.Default.Register(InitNavigationService);
 
}
 
/// <summary>
/// 创建NavigationService对象
/// </summary>
/// <returns>NavigationService</returns>
protected INavigationService InitNavigationService()
{
    var service = new NavigationService();
 
    service.Configure(typeof(MainPageViewModel).FullName, typeof(MainPage));
    service.Configure(typeof(Page1ViewModel).FullName, typeof(Page1));
    service.Configure(typeof(Page2ViewModel).FullName, typeof(Page2));
 
    return service;
}


注册NavigationService对象和注册VM是一样的,我们通过InitNavigationService()方法来返回一个NavigationService实例对象,并在Configure中注册页面与key之间的映射,这里推荐使用typeof(MainPageViewModel).FullName的方式设置key,好处不言而喻,防止用的时候写错QAQ


添加完key/Page映射,注册完NavigationService对象后,在ViewModelLocator类中添加一个用来获取刚才注册的NavigationService对象的属性

/// <summary>
/// 导航服务器
/// </summary>
public INavigationService NavigationService => ServiceLocator.Current.GetInstance<INavigationService>();


至此,配置的工作已完成,使用的时候很简单,直接根据key去导航,如下:


//进行导航
ViewModelLocator.Default.NavigationService.NavigateTo(typeof(Page1ViewModel).FullName, "这里也可以填写参数");


虽然可以填写参数,但是不建议在此传递参数,为什么呢?因为在此传参的话,Page中就必须重写OnNavigatedTo方法来获取该参数,这样就会增加VM与View之间的耦合度。


既然使用了MvvmLight框架那么这种情况是不允许让它发生的。很简单,MvvM的设计模式的一个核心理念就是数据驱动界面,把数据的地位放到第一位,任何界面的变化都是由于数据发生了变化,而不是以前的事件驱动机制使用事件来操作数据的变化。从而MVVM中诞生了数据绑定、集合数据变更通知等一些技术。


这里推荐大家在传递数据时不妨考虑直接去修改数据,你传递过去不也是为了给一个对象赋值么?所以在这里可以给要跳转的界面的VM中的某个属性赋值,然后让UI再去绑定这个属性,属性值变化了,UI当然也会跟着变化,这就是数据驱动机制。


所以传参可以这样:

//为要跳转界面的VM 的属性赋值
ViewModelLocator.Default.Page2ViewModel.NavigateParameter = "我是参数";
ViewModelLocator.Default.NavigationService.NavigateTo(typeof(Page2ViewModel).FullName);


效果图:


本文出自:53078485群大咖Aran,欢迎您的加入!


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值