1. 背景

导航是为了实现不同界面的切换,是一种组织系统功能的方式。提供两种导航,一是基于View切换,二是基于ViewModel状态。

2. 基于View切换的导航

最常用导航方式。在该种导航中首先需要定义一个域(Region),然后注册所有需要的View。通过切换不同视图,可以实现导航。下面具体阐述:

2.1 定义域

一般使用ContentControl,ItemControl以及二者的子类定义域,同时为域命名,代码如下:

<ContentControl Grid.Row="1" Grid.ColumnSpan="2"
prism:RegionManager.RegionName="ContentRegion"/>

2.2 注册View

我们需要在DI容器中注册需要的View,如果直接使用DI容器的注册方法,注册的View只能够作为普通类使用。Prism提供各种容器的扩展方法RegisterTypeForNavigation,使用此方法注册后就可以实现导航,以Unity容器为例:

_unityContainer.RegisterTypeForNavigation<CalendarView>();

2.3 导航

类RegionManager提供方法RequestNavigate用于导航,有两种方式进行导航。

2.3.1 URI导航

用户只需调用该方法就可以实现导航,如下:

_regionManager.RequestNavigate("ContentRegion", calendarViewUri);

第一个参数是目标域名称,第二参数calendarViewUri是一个Uri类型的对象,该对象名称是需要导向View的名称。对象实例化方法是:

private static Uri calendarViewUri = new Uri("CalendarView", UriKind.Relative);

导航时还可以向目标View传递参数,同时也可以设置回调函数。

2.3.2 名字导航

可以直接将View名称传入方法RequestNavigate,

_regionManager.RequestNavigate("ContentRegion", "CalendarView");

使用这种方法好处是你可以导航至任意模块的View,前提是:

  • 已使用RegisterTypeForNavigation注册View;
  • View名或其别名需要在所有模块中唯一。

2.4 传递数据

这里涉及两个问题:

  1. 当前view如何传入数据?
  2. 目标view如何解析数据?

对于问题一,RequestNavigate方法提供方法重载,允许我们传入数据。传入的数据类型是NavigationParameters,这是一个IEnumerable类型,使用add方法添加参数,key-value形式。示例如下:

using Prism.Regions;
private readonly IRegionManager _regionManager;
//...
NavigationParameters para = new NavigationParameters();
para.Add("name", "ZZL");
_regionManager.RequestNavigate("ContentRegion", "HelloView", para);

对于问题二,还需要继续细分,目标view如何感知传递来的数据,知道以后又如何解析?Prism框架提供接口INavigationAware,与View对应的ViewModel只需实现接口就可以自动感知。该接口包含三个方法:

IsNavigationTarget

函数签名:

bool IsNavigationTarget(NavigationContext navigationContext);

指定当前View是否是导航目标,返回值为TRUE则导航至该View实例。如果不是则返回FALSE,RegionManager创建目标View的新实例。

OnNavigatedFrom

函数签名:

void OnNavigatedFrom(NavigationContext navigationContext);

从当前View离开时调用。

OnNavigatedTo

函数签名:

void OnNavigatedTo(NavigationContext navigationContext);

导航至该View时调用。一般如果重新进入View需要刷新或重置页面时,逻辑均需写在该方法中。传入参数navigationContext有一个属性Parameters,类型为NavigationParameters。迭代读取该属性就可以解析数据。示例如下:

using Prism.Mvvm;
using Prism.Regions;
namespace ModuleA.ViewModels
{
public class ViewAViewModel : BindableBase, INavigationAware
{
private string _name;
public string Name
{
get { return _name; }
set
{
SetProperty(ref _name, value);
}
} public ViewAViewModel()
{ } public void OnNavigatedTo(NavigationContext navigationContext)
{
NavigationParameters p = navigationContext.Parameters;
foreach (var item in p)
{
if(item.Key == "name")
Name = (string)item.Value;
}
} public bool IsNavigationTarget(NavigationContext navigationContext)
{
return true;
} public void OnNavigatedFrom(NavigationContext navigationContext)
{ }
}
}

三个方法的调用顺序是OnNavigatedFrom,IsNavigationTarget,OnNavigatedTo。

2.5 确认和取消导航

对于重要情况,有时需要提供确认导航功能。接口INavigationAware虽提供数据传递功能,方法IsNavigationTarget标明是否是导航目标,但是不能取消导航,

Prism提供INavigationAware的扩展接口IConfirmNavigationRequest,该接口提供一个额外方法ConfirmNavigationRequest实现确认导航机制。

public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
{
bool result = true;
if (MessageBox.Show("Do you to navigate?", "Navigate?", MessageBoxButton.YesNo) == MessageBoxResult.No)
result = false;
continuationCallback(result);
}

2.6 用后即焚

默认情况下所有已导航View实例一直保存在Region中,直至程序结束。而有些View在软件运行时使用频率低,这时就希望如果不使用该View时就将View实例销毁。Prism提供接口IRegionMemberLifetime实现“用后即焚”,该接口提供方法KeepAlive属性,如果返回FALSE,当View实例不显示时,就将该View的实例从Region中移除。下次需要使用则重新实例化View。

3. 基于状态的导航

在此类导航中,UI的更新是基于ViewModel状态变化以及用户交互。此类导航适用于:

  • View需要以不同样式或者格式显示同一数据
  • View需要基于View Model状态改变样式或者布局
  • View需要初始化有限的模态交互或非模态交互。

此类导航不适用于:

  • UI需要为用户显示不同数据;
  • UI需要执行不同任务。

8. Prism导航的更多相关文章

  1. Prism 的 TabControl 导航

    基于Prism 7.1 最近工作中可能会用到TabControl所以作为小菜的我提前预习了一下,结果并没有我想的那么简单,于是乎 各种网上查,本来用wpf的人就不多 prism 的可查的资料就更少的可 ...

  2. Prism 4 文档 ---第8章 导航

        作为同用户具有丰富的交互的客户端应用程序,它的用户界面(UI)将会持续不断的更新来反映用户工作的当前的任务和数据.用户界面可以进行一段时间相当大的变化作为用户交互的应用程序中完成各种任务.通过 ...

  3. Prism for WPF 搭建一个简单的模块化开发框架(六)隐藏菜单、导航

    原文:Prism for WPF 搭建一个简单的模块化开发框架(六)隐藏菜单.导航 这个实际上是在聊天之前做的,一起写了,也不分先后了 看一下效果图,上面是模块主导航,左侧是模块内菜单,现在加一下隐藏 ...

  4. 从PRISM开始学WPF(八)导航Navigation-更新至Prism7.1

    原文:从PRISM开始学WPF(八)导航Navigation-更新至Prism7.1 0x6Navigation [7.1updated] Navigation 在wpf中并没有变化 Basic Na ...

  5. 从PRISM开始学WPF(八)导航Navigation?

    原文:从PRISM开始学WPF(八)导航Navigation? 0x6Navigation Basic Navigation Prism中的Navigation提供了一种类似导航的功能,他可以根据用户 ...

  6. Xamarin.Forms + Prism,整理页面导航跳转流程

    3个Page,Page1 -> Page2 -> Page3 -> Page2 -> Page1. PageViewModel实现接口:INavigatingAware, IN ...

  7. Silverlight项目笔记4:初识Prism以及IoC

    1.Prism Prism是由微软Patterns & Practices团队开发的针对WPF和Silverlight的MVVM框架. Prism的几个关键点: (1)启动器类UnityBoo ...

  8. Prism简介

    Prism是由微软Patterns & Practices团队开发的项目,目的在于帮助开发人员构建松散耦合的.更灵活.更易于维护并且更易于测试的WPF应用或是Silverlight应用以及Wi ...

  9. MVVMLight Toolkit在Windows Phone中的使用扩展之一:在ViewModel中实现导航,并传递参数

    MVVMLight是MVVM开发模式在Windows Phone平台下的一个开发框架,关于MVVMLight的基础使用,已经有人写的很好了,可以参照:MVVM.MVVMLight.MVVMLight ...

随机推荐

  1. WebStrom配置TypeScript开发环境

    安装NodeJS node.js下载地址:https://nodejs.org/en/download/ 安装TypeScript npm install typescripot -g 新建tscon ...

  2. GAN网络之入门教程(五)之基于条件cGAN动漫头像生成

    目录 Prepare 在上篇博客(AN网络之入门教程(四)之基于DCGAN动漫头像生成)中,介绍了基于DCGAN的动漫头像生成,时隔几月,序属三秋,在这篇博客中,将介绍如何使用条件GAN网络(cond ...

  3. VSCODE 配置eslint规则和自动修复

    全局安装eslint 打开终端,运行npm install eslint -g全局安装ESLint. vscode安装插件 vscode 扩展设置 依次点击 文件 > 首选项 > 设置 { ...

  4. volatile型变量语义讲解一 :对所有线程的可见性

    volatile型变量语义讲解一 :对所有线程的可见性 一.volatile变量语义一的概念 当一个变量被定义成volatile之后,具备两个特性: 特性一:保证此变量对所有线程的可见性.这里的&qu ...

  5. 实验 6:OpenDaylight 实验——OpenDaylight 及 Postman 实现流表下发

    一.实验目的 熟悉 Postman 的使用:熟悉如何使用 OpenDaylight 通过 Postman 下发流表. 二.实验任务 流表有软超时和硬超时的概念,分别对应流表中的 idle_timeou ...

  6. 2016年 实验四  B2B模拟实验

    实验四  B2B模拟实验 [实验目的] ⑴.掌握B2B中供应商的供求信息发布.阿里商铺开设和订单交易等过程. ⑵.掌握B2B中采购商的采购信息的发布.交易洽谈.网上支付和收货等过程. [实验条件] ⑴ ...

  7. 【Linux编译环境的搭建】Linux都没有,怎么学Linux编程?

    本文准备从0开始,一步步搭建一套属于自己的多节点Linux系统环境,这将是后续学Linux.用Linux.Linux环境编程.应用和项目部署.工具实验等一系列学习和实践的基石,希望对小伙伴们有帮助. ...

  8. spring boot:shardingsphere+druid多数据源整合seata分布式事务(spring boot 2.3.3)

    一,为什么要给shardingsphere配置多数据源? 1,shardingjdbc默认接管了所有的数据源, 如果我们有多个非分表的库时,则最多只能设置一个为默认数据库, 其他的非分表数据库不能访问 ...

  9. 全文检索Solr集成HanLP中文分词【转】

    以前发布过HanLP的Lucene插件,后来很多人跟我说其实Solr更流行(反正我是觉得既然Solr是Lucene的子项目,那么稍微改改配置就能支持Solr),于是就抽空做了个Solr插件出来,开源在 ...

  10. python 虚拟环境安装

    windows虚拟环境的搭建 安装 # 建议使用pip3安装到python3环境下 pip3 install virtualenv pip3 install virtualenvwrapper-win ...