构建基于WinRT的WP8.1 App 01:页面导航及页面缓存模式

时间:2022-09-18 09:46:37

本篇博文主要阐述基于Windows Runtime的Windows Phone 应用页面间导航相关知识,主要分为以下几个方面:

  • Window、Frame和Page概览
  • 页面间实现跳转
  • 处理物理后退键
  • 页面的缓存

Window、Frame和Page概览

基于WinRT的Windows Phone 8.1,每个App只有一个Window。

构建基于WinRT的WP8.1 App 01:页面导航及页面缓存模式

每个Window都有自己的Frame和导航栈, 以及自己的Page。

Window中有一个Frame,并且100%撑满可视区域,通常Frame也是100%撑满Window的可视区域。

所有的Page都被包含在Frame中,Frame负责页面间的导航。Page中包含的就是自己的内容了,包括Xaml文件和相关联的code-behind代码。

虽然应用的窗口一般都只会包含一个Frame,但是我们可以通过在Page中嵌入Frame,但是这种情况在手机应用上并不常见。

构建基于WinRT的WP8.1 App 01:页面导航及页面缓存模式

通常Frame在应用启动时创建,可以参考下面代码:

构建基于WinRT的WP8.1 App 01:页面导航及页面缓存模式

来简单分析一下上述代码,OnLaunched函数存在于App.xaml.cs文件中,包含一些启动的逻辑代码。OnLaunched函数中将Frame对象当前Window中,然后调用Frame.Navigate(Type,object)函数,创建一个Page的实例,并把Page放进Frame中。当向前或向后跳转Page时,Frame会记录跳转的历史,可以通过Frame.BackStack属性(返回类型:IList<PageStackEntry>)查看跳转导航的历史。

页面间实现跳转

当需要跳转到另一个页面时,调用Frame的Navigate函数。该函数把当前页面放到后退栈中,并且可以传递任何参数给新的页面。

构建基于WinRT的WP8.1 App 01:页面导航及页面缓存模式

构建基于WinRT的WP8.1 App 01:页面导航及页面缓存模式

另外我们可以在页面中放置Buttons, hyperlinks, appbar buttons 或者其他控件,通过代码移除当前Page,让用户跳转回到之前的页面。我们可以利用Frame.GoBack()函数实现。

构建基于WinRT的WP8.1 App 01:页面导航及页面缓存模式

下面来分析具体实现的原理:通常Windows Phone应用会维护一个跳转的历史栈,就像Web浏览器一样。应用通常启动至MainPage.xaml,所以它是栈的第一个项,当跳转到SecondPage.xaml后,SecondPage.xaml就被放进栈中,当调用Frame.GoBack时,SecondPage就会被从栈中弹出来,然后回到MainPage。

处理物理后退键

基于Silverlight的Windows Phone 用户体验中一个典型的特性是:当用户按下Back键时,用户知道这样会取消当前视图并回到之前的视图。在Windows Phone Silverlight中,物理Back键会引起App内部的向回跳转。如果用户当前在启动页面,基于Silverlight框架的Windows Phone App会被关闭。

而在基于Windows Runtime的Windows Phone App中,行为稍微有点不一样,默认情况下按下物理Back键会引起向后跳转到之前的App,而跟用户当前在哪个App的页面上没有关系。因此开发者需要重写这种默认的行为让它在App内部跳转。另外,如果用户在App的启动页面,按下物理Back键会引起跳转到之前的App,但是与Silverlight框架不同的是当前的App是被挂起,而不是被关闭

关于上述的内容,那么我们该如何对Back键进行处理呢?

如果使用空项目模板,那么新建的项目文件中没有任何Back键的处理代码,如果想实现简单的后退跳转,可以利用下面代码。

构建基于WinRT的WP8.1 App 01:页面导航及页面缓存模式

上述代码中,在App.xaml.cs文件中重写了BackPressed事件,在BackPressed事件中判断是否可以向前进行跳转,如果可以,返回到前一个页面。

如果使用非空项目模板进行创建项目(例如:Hub App或者Pivot App),新建的项目以及包含了正确的Back键处理,我们可以在项目的Common文件夹中的NavigationHelper类中找到相应处理函数。

另外也可以在某一个页面上单独处理Back键,具体处理方法和上述代码类似,这里就不再累赘重述了。

页面的缓存

构建基于WinRT的WP8.1 App 01:页面导航及页面缓存模式

首先我们来描述一个常用场景:当用户第一次访问某个页面时,页面是新的,没有数据带入。用户与页面交互,会填充一些数据。当向前导航到另一个页面然后再导航回来。通常用户期望页面和离开时是一样的状态。那么我们该如何保证页面和离开时是一样的状态呢?

我们可以利用Page的NavigationCacheMode属性。

当使用NavigationCacheMode.Disabled时,向前跳转时创建一个新的实例,原始页面的状态丢失。

当使用NavigationCacheMode.EnabledRequired时,缓存的页面可以重用,原始页面的状态保留。

下面详细描述一下NavigationCacheMode属性三个值的作用:

  • NavigationCacheMode.Disabled:不管向回还是向前跳转都会生成页面新的实例;
  • NavigationCacheMode.Enabled:页面被缓存,但是达到缓存上限时,缓存的实例还是会被丢弃(上限由Frame.CacheSize属性决定,默认情况下为10);
  • NavigationCacheMode.Required:页面被缓存,并且缓存的实例不受数量限制;

另外也可以使用NavigationHelper类保存/恢复页面状态。通常我们在Page的OnNavigatedTo函数事件中调用NavigationHelper的LoadState函数恢复页面状态,在Page的OnNavigatedFrom函数事件中调用NavigationHelper的SaveState函数保存页面状态。

参考文章

构建基于WinRT的WP8.1 App 01:页面导航及页面缓存模式的更多相关文章

  1. 构建基于WinRT的WP8&period;1 App 03:Page控件

    单页面模板 通常利用Visual Studio 2013创建的最简单的WP8.1应用是Blank App,它只包含一个不带任何UI的页面,并且没有任何状态管理的逻辑. 该不带任何UI的页面称为Blan ...

  2. 构建基于WinRT的WP8&period;1 App 02:数据绑定新特性

    基于WinRT的Windows Phone 8.1以及Windows 8.1中Xaml数据绑定增加了一些新特性. FallBackValue属性:FallBackValue在绑定的值属性值不存在时,可 ...

  3. wp8&period;1 Study1: 页面导航&amp&semi;页面间值传递

    摘要:wp8.1与wp8中很多API是不一样了,wp8.1把以前wp7.x时的api去掉了,更多与win8.1的API相似.比如以下的页面导航和页面之间的值传递 1.页面导航 利用Frame.Navi ...

  4. 基于Html5的移动端APP开发框架

    快速增长的APP应用软件市场,以及智能手机的普及,手机应用:Native(原生)APP快速占领了APP市场,成为了APP开发的主流,但其平台的不通用性,开发成本高,多版本开发等问题,一直困扰着专业AP ...

  5. maven-bundle-plugin插件&comma; 用maven构建基于osgi的web应用

    maven-bundle-plugin 2.4.0以下版本导出META-INF中的内容到MANIFEST.MF中 今天终于把maven-bundle-plugin不能导出META-INF中的内容到Ex ...

  6. 构建基于Javascript的移动web CMS——模板

    在上一篇<构建基于Javascript的移动CMS--Hello,World>讲述了墨颀 CMS的大概组成,并进行了一个简单的演示样例,即Hello,World.这一次,我们将把CMS简单 ...

  7. 开发一个基于 Android系统车载智能APP

    很久之前就想做一个车载相关的app.需要实现如下功能: (1)每0.2秒更新一次当前车辆的最新速度值. (2)可控制性记录行驶里程. (3)不连接网络情况下获取当前车辆位置.如(北京市X区X路X号) ...

  8. 使用PowerApps快速构建基于主题的轻业务应用 &mdash&semi;&mdash&semi; 入门篇

    作者:陈希章 发表于 2017年12月12日 前言 在上一篇文章 基于Office 365的随需应变业务应用平台 中我提到,随着随需应变的业务需要,以及技术的发展,业务应用的开发的模式也有了深刻的变化 ...

  9. 构建基于阿里云OSS文件上传服务

    转载请注明来源:http://blog.csdn.net/loongshawn/article/details/50710132 <构建基于阿里云OSS文件上传服务> <构建基于OS ...

随机推荐

  1. &period;NET Core中遇到奇怪的线程死锁问题:内存与线程数不停地增长

    一个 asp.net core 站点,之前运行在Linux 服务器上,运行一段时间后有时站点会挂掉,在日志中记录很多“EMFILE too many open files”的错误: Microsoft ...

  2. 【转】Struts1&period;x系列教程(5):HTML标签库

    转载地址:http://www.blogjava.net/nokiaguy/archive/2009/01/archive/2009/01/archive/2009/01/archive/2009/0 ...

  3. getOutputStream&lpar;&rpar; has already been called for this response异常的原因和解决方法

    今天在调试一个小web项目时,验证码不显示了,而且后台报错 getOutputStream() has already been called for this response 经过查找得知: 在t ...

  4. jQuery学习-事件之绑定事件(六)

    在jQuery中,为了屏蔽event对象在各浏览器中的差异性,它使用了自定的Event对象,如下:  1 jQuery.Event = function( src, props ) {  2      ...

  5. Hibernate三大类查询总结

    Hibernate目前总共分为三大类查询:cretiria,hql,本地sql [以下篇章搜集于网络,感谢作者] 第一:关于cretiria的查询 具有一个直观的.可扩展的条件查询API是Hibern ...

  6. GOF23种设计模式概括

    GOF23种设计模式分为三种: 创建型模式[工厂方法模式]结构型模式[(类)适配器模式]行为型模式[ 解释器模式,模板方法模式]   创建型模式Creational Patterns抽象工厂模式abs ...

  7. uva-10487-枚举

    题意:给你一个集合,每俩个数相加得到一个和s,输入s1,问离s1最近的s是多少 二分,注意如果二分出相等,那一定是最近的数,要不然就比较最后mid和mid-1的数 #include <strin ...

  8. Android中线程间通信原理分析:Looper,MessageQueue,Handler

    自问自答的两个问题 在我们去讨论Handler,Looper,MessageQueue的关系之前,我们需要先问两个问题: 1.这一套东西搞出来是为了解决什么问题呢? 2.如果让我们来解决这个问题该怎么 ...

  9. Core引用Jquery文件

    静态文件放在wwwroot里边 不然浏览器会报错文件不存在.

  10. 54&period; Spiral Matrix&lpar;矩阵,旋转打印&rpar;

    Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...