WindowsPhone 8开发技巧与案例精解(txt+pdf+epub+mobi电子书下载)


发布时间:2020-05-24 17:09:39

点击下载

作者:周家安

出版社:机械工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

WindowsPhone 8开发技巧与案例精解

WindowsPhone 8开发技巧与案例精解试读:

前言

为什么写这本书

2010年10月,微软公司发布全新的智能手机操作系统——Windows Phone。该系统具有图标拖曳、滑动控制等一系列前卫功能,其具有的另一个重要功能——桌面动态磁贴,能方便人们进行触屏操作和查看与应用程序相关的最新消息,充分体现了人性化的特点。Windows Phone集企业应用和生活娱乐于一身,其具有的流畅、高效、良好的用户体验等特点吸引着众多.NET开发者。

2012年6月21日,微软公司正式发布了Windows Phone 8操作系统,该系统与新一代操作系统Windows 8具有相同的内核(NT内核),体现了微软公司希望将个人计算机、笔记本电脑、平板电脑以及移动终端等平台进行整合的发展目标。

在好奇心的驱使下,我下载并安装了Windows Phone SDK。待安装顺利完成后,我迫不及待地编写了第一个Windows Phone应用程序,竟然发现一切都是那么的熟悉。究其原因,有以下两点:

第一,Windows Phone SDK的两个主要工具——开发工具Visual Studio和设计工具Express Blend都是.NET开发者使用过的。Visual Studio自然不用说了,相信每位.NET开发者都不陌生,而另一个设计工具Express Blend,我们在使用WPF/Silverlight进行开发的时候可能也已经用到过了,它能够通过图形界面操作生成复杂的XAML代码,大大提高了开发效率。

第二,Windows Phone应用程序可以使用VB.NET、C#和C++语言进行程序开发,这使得开发团队可以进行更好的协作。举个例子,假设我们团队有3人,我比较习惯使用C#,另外两位成员则分别使用C#和C++。于是,我负责的内容是用C#来编写代码,而他们则分别使用C#和C++,最后,只要将大家写的代码集成在一起编译即可。

这两个因素为移动开发者进行开发提供了便利,使得更多的开发者可很方便地参与其中。

基于此,我考虑把我的开发经验分享出来,帮助大家更快入门。这就是本书的写作初衷。本书摒弃传统的理论说教方式,代之以实例引导,用直观的方式向读者展示如何在实际开发中运用各种技术。

本书的实例均使用C#语言编写,且是基于刚刚发布的Windows Phone 8 SDK展开的,同时,书中内容也兼容7.1版本的SDK。由于目前最新的SDK刚刚发布,所以许多API尚未完善。微软公司可能会发布后续更新。若有变动,我会在博客上补充说明。

读者对象

本书适合以下读者阅读:

有.NET等技术基础的开发人员。

有其他移动平台开发经验并有兴趣尝试Windows Phone开发的人员。

希望加入Windows Phone开发者阵营的初学者。

对Windows Phone感兴趣的业余爱好者。

开设Windows Phone开发相关课程的培训机构的学员或高等院校学生。

如何使用本书

本书共分11章,分别介绍了开发过程中要使用的各个知识点,具体如下:

第1章简单介绍开发工具以及Windows Phone应用程序项目的文件结构,并简要叙述应用程序清单文件的基本结构。

第2章从应用程序生命周期入手,介绍应用程序运行期间引发的各个事件,同时也涉及页面导航和状态管理等内容。

第3章讲解与用户界面布局(页面布局)有关的知识,如常用的Grid、StackPanel等布局控件。

第4章介绍常用控件的使用技巧。

第5章主要叙述与应用程序或操作系统相关的知识,例如修改应用程序初始屏幕、获取网络接口信息等。

第6章介绍启动器与选择器,如启动拨号屏幕拨打电话。

第7章介绍网络通信和推送通知服务。

第8章介绍如何在独立存储中进行文件I/O操作。

第9章讲述常见的数据绑定方法,同时介绍如何创建和操作本地数据库。

第10章讲述图形、动画以及多媒体播放。

第11章介绍三个简单的综合实例。

本书所阐述的每个知识点都有对应的实例,而且这些实例都是独立的,读者在开发工具中打开任何实例源码都能够单独运行并查看效果。因此,建议大家在阅读本书的时候把重点放在动手实践上面,对于本书的每一个实例,大家都可以仿照练习,每章后面附带的练习题同样也是以实际操作为主的。

在熟悉随书源码后,大家可以尝试修改源码,以形成新的实例程序,或者将几个实例合并为一个新程序。总而言之,大家可以灵活运用本书的实例源码。

在学习过程中,个人觉得养成勤于动手的习惯非常有必要,这样才能将从书中学到的知识运用到实际开发中。我相信这种学习方法的收效会非常明显。

勘误和支持

由于作者水平有限,而且编写本书的时间有限,书中难免会有一些不妥之处,也可能出现错误和不准确的叙述,望大家不吝赐教。大家可以通过以下两种途径进行反馈:将书中的错误以电子邮件的形式发送到csdev2012@foxmail.com,我会尽量为大家提供满意的回复;以博客留言的形式提出建议或反馈,我的博客地址为http://blog.csdn.net/tcjiaan,微博地址为http://weibo.com/tcjiaan。随书源码的下载地址为http://www.hzbook.com。

致谢

首先,真诚感谢机械工业出版社华章公司的杨绣国编辑,她在我写作过程中给予我无微不至的帮助,因为有了她的帮助我才能顺利完成书稿。

还要感谢我的父母和弟弟,他们给了我很大的鼓励;感谢我的朋友、在博客上支持我的各位网友和技术交流群中的各位群友,谢谢大家一直以来对我的支持。

谨以此书,献给广大Windows Phone开发者和所有关注Windows Phone发展的朋友们。周家安广东东莞第1章准备工作本章内容

安装Windows Phone SDK

初试Windows Phone应用程序开发

了解Windows Phone应用程序项目的目录和文件结构

了解清单文件

入口点Main()到哪里去了

练习题

在开始进行Windows Phone开发之前,必须要做好一些基本准备,如安装SDK及搭建开发环境等。

本章首先介绍如何核准我们的软硬件系统是否符合开发Windows Phone应用程序的要求。接着,通过新建一个简单的Windows Phone应用程序项目来使读者熟悉开发工具的使用方法。而后,介绍一般Windows Phone应用项目的基本结构,比如它包含哪些目录及哪些文件、都有什么用处等。同时,也会重点介绍一下清单文件,在实际开发中我们经常会使用它。最后,关注一下初学者可能都会遇到的问题——寻找Main()入口点。1.1 安装Windows Phone SDK

SDK有两种安装方法,即在线安装和离线安装。在线安装只需要下载一个很小的安装组件,该组件运行后会自动从微软公司官方服务器下载并安装所需内容;离线安装需先下载整个安装包的镜像文件(ISO文件),然后解压缩并运行安装程序,或在虚拟光驱中直接运行安装程序。

小提示 建议先下载离线安装包再进行安装,这样一来可以防止由于网络不稳定而造成的安装过程停滞或中断;二来,如果以后出现故障需要修复或重新安装,就不必再次下载了,可直接进行本地安装。

如果已经安装了Visual Studio专业版或更高级版本,安装该SDK后,会自动合并到Visual Studio中,成为其中的一个插件,而不必再安装Express版本的Visual Studio。

表1-1描述了安装Windows Phone SDK所需的配置与系统要求。1.2 初试Windows Phone应用程序开发

安装完SDK后,接着我们来体验一下Windows Phone开发。下面列出了新建Windows Phone应用程序项目的步骤。(1)在“开始”屏幕中,单击VS Express Windows Phone图标(如果当前未处于“开始”屏幕上,可按键盘上的Windows键快速进入“开始”屏幕),如图1-1所示,即可启动开发工具,启动后的Visual Studio主界面如图1-2所示。图 1-1 从“开始”屏幕中启动Visual Studio图 1-2 Visual Studio主界面(2)单击菜单栏中的“文件(FILE)”→“新建项目(New Project)”,弹出“新建项目”对话框。因为我们主要使用C#语言进行开发,所以,在左边列表的“已安装的模板(Installed)”下,展开Visual C#节点,选择Windows Phone,在中间的模板列表中选择Windows Phone Application,并在“名称”处输入项目名称,在“位置”处浏览并选择项目存放的目录,其他保持默认值,然后单击“确定”按钮,如图1-3所示。在接着弹出的对话框中保持默认所有项目设置,直接单击“确定”按钮,Visual Studio就会创建项目。图 1-3 “新建项目”对话框(3)项目创建成功后,为了辅助演示必须做一点修改。在设计器中单击“页面名称”的TextBlock控件,并在“属性”窗口中把Text属性的值改为“我的主页”,如图1-4所示。图 1-4 修改页面标题(4)单击工具栏上的“启动调试”按钮,或者按下键盘上的F5键,就可以运行程序了。首先,我们要等待模拟器的启动,启动完成后将自动执行程序。

小提示 模拟器的启动需要一定的时间,因此,每次调试完毕不必关闭模拟器,这样可以减少我们等待的时间。1.3 了解Windows Phone应用程序项目的目录和文件结构

Windows Phone应用程序项目的目录及文件结构与我们过去使用Visual Studio开发的其他应用程序项目类似,如图1-5所示为一个简单的Windows Phone应用程序项目模板的基本结构。图 1-5 应用程序项目目录和文件结构

❑解决方案与项目:一个解决方案可以包含一个或多个项目,而每个项目的类型可以不相同,仅仅按逻辑上的需求而组合在一起。

❑Properties目录:主要存放与项目属性相关的文件,如程序集信息、清单文件等。

〇AppManifest.xml文件:Silverlight的程序集清单文件模板,包含目标版本、程序集所在的.dll文件等。在最终生成的.xap文件包中,此文件将以AppManifest.xaml的文件名存在。

〇AssemblyInfo.cs文件:包含当前程序集的信息,如标题、版本等,一般可通过项目属性进行修改。

〇WMAppManifest.xml文件:Windows Phone应用程序清单文件,包含该Windows Phone应用程序的详细信息,如开发者信息以及该应用要使用到的系统功能信息等。

❑引用:项目使用到的.NET Framework中的类库或其他类库,或者引用解决方案中的其他项目。

❑.xaml文件和.cs文件:这两种文件是我们编写应用程序时最主要的操作对象,除了资源字典外,每个.xaml文件都有一个对应的.cs文件。.cs文件就是我们所熟悉的C#代码文件,本书的实例代码都是基于C#编写的。

❑其他文件:包括应用程序需要用到的资源文件,如图像文件、音/视频文件等。1.4 了解清单文件

由于本书的目标读者是具有一定的C#及.NET开发基础的人员,故上一节中仅简略描述了一般Windows Phone项目的基本目录和文件结构。本节将重点阐述Windows Phone应用程序清单文件。不过,尽管它对于应用的发布来说比较重要,但我们不必死记硬背,只要了解一下相关知识,心中有个大概轮廓即可。当你需要修改清单文件时,可以参照MSDN文档的相关说明来进行。

清单文件,其本质就是一个XML文件,它用于描述与我们开发的Windows Phone应用程序有关的信息,如应用类别、标题、作者、发布人、版本等。

在新建一个Windows Phone应用程序后,依次单击“解决方案资源管理器”→“项目”→“Properties文件夹”,即可找到清单文件WMAppManifest.xml。清单文件的大体结构如代码清单1-1所示。

代码清单 1-1

<?xml version="1.0" encoding="utf-8"?>

<Deployment xmlns="http://schemas.microsoft.com/windowsphone/2009/deployment" AppPlatformVersion="7.1">

<App xmlns="" ProductID="{14a1b536-ade5-4b31-aeb5-dc17802ed5bc}" Title="我的应用程序" RuntimeType="Silverlight" Version="1.0.0.0" Genre="apps.normal" Author="作者" Description="应用程序描述或简介" Publisher="发布者">

<!--应用程序图标-->

<IconPath IsRelative="true" IsResource="false">ApplicationIcon.png</IconPath>

<!--应用程序中需要使用到的功能,如网络。-->

<Capabilities>

<Capability Name="ID_CAP_GAMERSERVICES"/>

<Capability Name="ID_CAP_IDENTITY_DEVICE"/>

<Capability Name="ID_CAP_IDENTITY_USER"/>

<Capability Name="ID_CAP_LOCATION"/>

<Capability Name="ID_CAP_MEDIALIB"/>

<Capability Name="ID_CAP_MICROPHONE"/>

<Capability Name="ID_CAP_NETWORKING"/>

<Capability Name="ID_CAP_PHONEDIALER"/>

<Capability Name="ID_CAP_PUSH_NOTIFICATION"/>

<Capability Name="ID_CAP_SENSORS"/>

<Capability Name="ID_CAP_WEBBROWSERCOMPONENT"/>

<Capability Name="ID_CAP_ISV_CAMERA"/>

<Capability Name="ID_CAP_CONTACTS"/>

<Capability Name="ID_CAP_APPOINTMENTS"/>

</Capabilities>

<!--DefaultTask用于设置程序启动时应导航到的页面,即主页面。-->

<Tasks>

<DefaultTask Name="_default" NavigationPage="MainPage.xaml"/>

</Tasks>

<!--“开始”屏幕磁贴相关-->

<Tokens>

<PrimaryToken TokenID="MyAppToken" TaskName="_default">

<TemplateType5>

<BackgroundImageURI IsRelative="true" IsResource="false">Background.

png</BackgroundImageURI>

<Count>0</Count>

<Title>MyApp</Title>

</TemplateType5>

</PrimaryToken>

</Tokens>

</App>

</Deployment>

需要编辑的内容都包含在App节点下。清单文件不需要改动太多,上述代码清单中的粗体部分为经常或可能会修改的内容,其中,大部分可以通过项目属性窗口编辑,但有些内容可能需要通过直接编辑清单文件来完成。

App节点的常用属性及相关说明如表1-2所示。

App节点的子元素及相关说明如表1-3所示。

在实际开发中,可以直接双击清单文件,通过图形化界面编辑清单文件,如图1-6所示。图 1-6 清单文件图形化编辑界面1.5 入口点Main()到哪里去了

细心的读者一定会发现,每个C#应用程序都有一个入口点——Main方法,但在App.xaml.cs中,为什么没有看到Main()方法呢?难道Windows Phone应用程序没有入口点?

新建一个Windows Phone应用程序项目时,不要改动任何代码,在Visual Studio里面直接生成一个应用程序(快捷键为F6),待状态栏提示“生成成功”时,再打开应用程序项目所在的路径:<你的项目路径>\obj\Debug,会看到里面有4个动态生成的文件:App.g.cs、App.g.i.cs、MainPage.g.cs和MainPage.g.i.cs,但依然没有Main()。因此,我们不妨猜想,Main()方法有可能在运行时被动态调用了,也就是说被隐藏掉了。所以,我们可以把App.xaml.cs的App构造函数当作Main()方法来看待。1.6 练习题

本章主要介绍了Windows Phone开发的一些基本知识,因此,本章的动手实践练习非常轻松:请读者搭建好开发环境后,自行新建一个Windows Phone应用程序项目,然后依次打开项目中的文件,大致看一下项目模板默认生成的代码,熟悉一下项目结构。第2章整体认识Windows Phone本章内容

通过输出调试信息掌握Windows Phone应用程序的生命周期

如何进行导航

处理导航相关的事件

在页面之间传递数据

URI映射

在导航中“前进”或“后退”

必要时屏蔽“回退”键

在导航历史中移除记录

保存和恢复应用程序状态

……

在第1章中介绍了如何搭建Windows Phone开发环境,使大家对应用程序项目的结构有了一个总体认知,同时还简单介绍了清单文件。在本章中,将进一步理解Windows Phone应用程序开发的整体思路。

本章通过10个实例,一步一步引导大家从整体上理解Windows Phone应用程序的执行模型,以及页面之间的导航、数据的传递、状态的读写等相关知识。相信通过本章实例的演练,大家会对应用程序的生命周期有一个比较直观的感性认识。2.1 通过输出调试信息掌握Windows Phone应用程序的生命周期背景知识

所谓应用程序生命周期,我们可以简单地将其理解为一个应用程序实例从开始运行到最后终止的整个过程。在这个过程中,应用程序做了哪些事情,对用户的哪些操作进行了响应,引发了哪些事件等都会对生命周期有一定的影响。

由于手机应用程序具有特殊性,即每次只允许一个应用程序在前台运行,因此,理解应用程序生命周期将有助于我们在应用程序的切换过程中保存和恢复状态数据。Windows Phone应用程序的生命周期可以通过4个事件来描述。表2-1显示了这4个事件的详情及其触发事件。

对于这4个事件,目前可能还会有些不清楚,要理解它们,最好的办法就是通过实际调试输出来对其进行仔细观察和研究。实例演练

注意 在本书的实例程序中,如没有特别说明,项目类型都是Silverlight for Windows Phone应用程序。

下面的实例将在“输出”窗口中输出调试信息,通过观察这些调试信息,读者可以更清楚地理解应用程序的生命周期。

新建应用程序项目后,进行以下操作:(1)打开App.xaml.cs,在文件头部using列表中引入System.Diagnostics命名空间。

using System.Diagnostics;(2)在Application_Launching、Application_Activated、Application_Deactivated、Application_Closing等4个事件处理方法中分别用Debug类输出信息,显示这些事件在什么时候被引发,这样有助于我们进行观察。其形式与下面的代码类似。

private void Application_Launching(object sender,LaunchingEventArgs e)

{

Debug.WriteLine(string.Format("{0}-Launching事件被触发",DateTime.Now.ToLongTimeString()));

}(3)在App类的构造方法中加入以下代码:

Debug.WriteLine(string.Format("{0}-App被实例化",DateTime.Now.ToLongTimeString()));(4)启动调试,并注意观察“输出”窗口。你可以通过以下操作来测试:

1)在应用程序运行后,看看“输出”窗口中Launching事件是否被触发;

2)在确认Launching事件已触发后,再单击设备模拟器上的“开始”按钮,切换到“开始”屏幕,看看“输出”窗口中哪些事件被触发了;

3)单击设备模拟器上的“后退”按钮,返回到应用程序,再观察“输出”窗口中Activated事件是否发生;

4)继续后退,查看是否触发了Closing事件。

注意 在代码中加入当前时间,只是为了方便观察。

以上过程的完整代码如代码清单2-1所示。其中,加粗的部分是我们需要编写的代码,其他为项目模板自动生成的代码。

代码清单 2-1

using System;

using System.Collections.Generic;

using System.Linq;

...

using Microsoft.Phone.Controls;

using Microsoft.Phone.Shell;

using System.Diagnostics;

namespace Sample_2_1

{

public partial class App:Application

{

///<summary>

///提供对电话应用程序根框架的轻松访问

///</summary>

///<returns>电话应用程序的根框架</returns>

public PhoneApplicationFrame RootFrame{get;private set;}

///<summary>

///Application对象的构造函数

///</summary>

public App()

{

//未捕获异常的全局处理程序

UnhandledException+=Application_UnhandledException;

//标准Silverlight初始化

InitializeComponent();

//特定于电话的初始化

InitializePhoneApplication();

//调试时显示图形分析信息

if(System.Diagnostics.Debugger.IsAttached)

{

//显示当前帧速率计数器

Application.Current.Host.Settings.EnableFrameRateCounter=true;

...

Debug.WriteLine(string.Format("{0}-App被实例化。",DateTime.Now.

ToLongTimeString()));

}

//应用程序启动(例如,从“开始”菜单启动)时执行的代码

//此代码在重新激活应用程序时不执行

private void Application_Launching(object sender,LaunchingEventArgs e)

{

Debug.WriteLine(string.Format("{0}-Launching事件被触发。",DateTime.

Now.ToLongTimeString()));

}

//激活应用程序(置于前台)时执行的代码

//此代码在首次启动应用程序时不执行

private void Application_Activated(object sender,ActivatedEventArgs e)

{

Debug.WriteLine(string.Format("{0}-Activated事件被触发。",DateTime.

Now.ToLongTimeString()));

}

//停用应用程序(发送到后台)时执行的代码

//此代码在应用程序关闭时不执行

private void Application_Deactivated(object sender,DeactivatedEventArgs e)

{

Debug.WriteLine(string.Format("{0}-Deactivated事件被触发。",DateTime.

Now.ToLongTimeString()));

}

//应用程序关闭(例如,用户单击“后退”)时执行的代码

//此代码在停用应用程序时不执行

private void Application_Closing(object sender,ClosingEventArgs e)

{

Debug.WriteLine(string.Format("{0}-Closing事件被触发。",DateTime.Now.

ToLongTimeString()));

}

//导航失败时执行的代码

private void RootFrame_NavigationFailed(object sender,NavigationFailedEventArgs e)

{

if(System.Diagnostics.Debugger.IsAttached)

{

//导航已失败;强行进入调试器

System.Diagnostics.Debugger.Break();

}

}

...

#region电话应用程序初始化

//避免双重初始化

private bool phoneApplicationInitialized=false;

//请勿向此方法中添加任何代码

private void InitializePhoneApplication()

{

if(phoneApplicationInitialized)

return;

//创建框架但先不将它设置为RootVisual;这允许初始

//屏幕保持活动状态,直到准备呈现应用程序时

RootFrame=new PhoneApplicationFrame();

RootFrame.Navigated+=CompleteInitializePhoneApplication;

...

//删除此处理程序,因为不再需要它

RootFrame.Navigated-=CompleteInitializePhoneApplication;

}

#endregion

}

}

为了尽可能地改进程序性能、提高用户体验,在实际开发中,读者务必要注意以下几点:

❑在处理Launching事件时,尽量避免访问网络或读取大量数据。

❑应该在Deactivated事件触发时保存重要的状态信息,并在Activated事件触发时恢复。

❑与Launching事件对应,在处理Closing事件时,也不宜做过多复杂的处理,以免用户等待退出应用程序的时间过长。

完整的实例代码请参考随书源码中的\第2章\Sample_2_1。2.2 如何进行导航背景知识

在Windows Phone的开发中,页面之间的导航与Web开发中的导航或切换其实是一个意思。在Windows Phone系统中,按照不同用途,应用程序会有多个页面,页面之间的切换就是通过导航来完成的。

页面导航由XAML的URI来标识,并且使用相对路径,如/testPage.xaml,“/”表示是根目录,这是相对于当前应用程序项目而言的。假如项目中包含有子文件夹,而当前页面处于该文件夹中,如果希望导航到上一层目录中去,则其URI路径会形如/../test.xaml。再比如,在项目根目录下建了一个子文件夹,名为Links,Links里面有一个页面a.xaml,那么,如果要从主页导航到a.xaml页面,则其URI为/Links/a.xaml。

HyperlinkButton控件专为导航而设,它类似于HTML中的a元素,可以直接通过XAML代码设置导航目标,而且不需要编写额外的后台处理代码,只要把NavigateUri属性设置为目标URI即可。其他控件(如Button)也可以实现导航,但需要自行编写代码。实例演练

本实例一方面介绍了使用HyperlinkButton或手动编码的导航方式,另一方面演示了从子目录的页面中导航到根目录的主页面的方法,运行效果图如图2-1所示。图 2-1 页面导航示意图

本实例的实现步骤如下:(1)新建Windows Phone应用程序项目。(2)除了默认生成的MainPage.xaml外,在“解决方案资源管理器”中右击当前项目节点,从弹出的菜单中依次选择“添加”→“新建项”,然后添加一个页面Music.xaml,并把页面中名为PageTitle的TextBlock控件的Text属性改为“我的音乐”。(3)在当前项目节点上右击,依次选择“添加”→“新建文件夹”,从而新建一个文件夹,并为其命名为Sub。在Sub文件夹下再添加一个页面Photo.xaml,把页面中名为PageTitle的TextBlock控件的Text属性值改为“我的相册”。在Photo.xaml中,从“工具箱”中拖放出一个HyperlinkButton,并把它的NavigateUri属性设置为/../MainPage.xaml,设置Content属性为“返回主页”。(4)回到MainPage.xaml中,把名为PageTitle的TextBlock控件的Text属性改为“我的主页”,并分别拖放一个HyperlinkButton控件和一个Button控件到其中,设置HyperlinkButton控件的NavigateUri属性为/Music.xaml,选中Button控件,并双击,这样就为按钮的Click事件生成了事件处理方法。然后输入如下代码:

private void btnPhoto_Click(object sender,RoutedEventArgs e)

{

this.NavigationService.Navigate(new Uri("/Sub/Photo.xaml",UriKind.Relative));

}

PhoneApplicationPage类的NavigationService属性返回一个System.Windows.Navigation.NavigationService对象实例,并通过调用Navigate方法导航到目标页。(5)运行程序,查看效果。

完整的实例代码请参考随书源码中的\第2章\Sample_2_2。2.3 处理导航相关的事件背景知识

页面导航过程会引发表2-2所示的3个事件,其实它们是3个方法。由于这些方法是从Page类继承过来的,处理时只需要重写这3个方法即可。实例演练

表2-2所列举的内容有点抽象,下面通过实例来帮助大家直观地理解OnNavigatedFrom、OnNavigatedTo、OnNavigatingFrom这3个方法。实例运行效果如图2-2所示。图 2-2 处理导航事件的实例

本实例在处理上述3个事件时,会使用MessageBox类的Show方法给出相应的提示,这样可以通过弹出的对话框来把握这几个事件何时触发。在实例中,为便于理解,会把看不见的概念形象化。

实例的实现步骤如下:(1)新建Windows Phone应用程序项目。(2)新增一个页面Me.xaml。(3)回到主页面,从“工具箱”中拖放一个HyperlinkButton到主页面。代码如下所示。

<HyperlinkButton Content="我的个人资料" NavigateUri="/Me.xaml"/>(4)切换到代码实例,重写OnNavigatedTo、OnNavigatedFrom和OnNavigatingFrom这3个方法,完善后台代码。其代码如代码清单2-2所示。

代码清单 2-2

public partial class MainPage:PhoneApplicationPage

{

//构造函数

public MainPage()

{

InitializeComponent();

}

//页面航导事件

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)

{

base.OnNavigatedTo(e);

MessageBox.Show("来到我的主页。");

}

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)

{

base.OnNavigatedFrom(e);

MessageBox.Show("已经离开我的主页。");

}

protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)

{

base.OnNavigatingFrom(e);

MessageBox.Show("即将离开我的主页。");

}

}

至此,实例应用程序已经完成,可以按F5键调试运行。

完整的实例代码请参考随书源码中的\第2章\Sample_2_3。2.4 在页面之间传递数据背景知识

通过导航到达目标页面时,有时候可能需要向目标页面传递一些简单的信息,就好像在做Web开发时,如果用户单击列表页面中的某个超链接,导航到一个详细页面,那么在加载详细页面时,要通过列表页传递过来的ID号来判断用户要查看的是哪条记录的详细信息,以便到数据库中查询该记录,从而向用户展示相应的视图,比如/detail.aspx?id=1325。

在Windows Phone页面导航中的参数传递,其概念和原理与Web页面是一样的,这也是从Silverlight中继承过来的。假设现在有一个应用程序,其主页面是MainPage.xaml,希望当用户单击页面上的按钮时,可跳转到List.xaml中去,而在页面List.xaml中需要知道相应的ID值,以便筛选并确认应该显示哪个列表信息。因此,我们这样设置导航URI:/List.xaml?id=7658,在List.xaml页面中会根据传过来的id值决定向用户显示哪些内容。

在目标页面中,应当重写OnNavigatedTo方法,并从PhoneApplicationPage的Navigation-Context属性返回一个System.Windows.Navigation.NavigationContext类的实例,再通过该NavigationContext对象的QueryString字典集合取得传递过来的URI参数,由于它是一个IDictionary<string,string>,因此需要使用参数名来检索。实例演练

本实例中有两个页面,主页面中放置了一个文本框,用于输入参数值,这个值在导航到第二个页面时传递,即其URI为/SecondPage.xaml?data=XXXXX,运行效果如图2-3所示。图 2-3 从“我的主页”传递参数到“页面二”

实例实现步骤如下:(1)新建一个Windows Phone应用程序项目。(2)在MainPage.xaml设计器中,从“工具箱”里拖放一个TextBox控件到其中,并命名为txtData,设置其Text属性为空;再拖放一个Button控件,命名为btnGo。添加按钮的Click事件处理代码,如代码清单2-3所示。

代码清单 2-3

private void btnGo_Click(object sender,RoutedEventArgs e)

{

if(this.txtData.Text=="")

{

return;

}

//导航到页面二,并传递参数

this.NavigationService.Navigate(new Uri("/SecondPage.xaml?data="+this.

txtData.Text,UriKind.Relative));

}(3)新建一个页面,设置其名为SecondPage.xaml,从“工具箱”中拖放两个TextBlock控件到其中,其中一个命名为textBlockDisplay,用于显示从主页面传过来的参数值。(4)在SecondPage.xaml.cs中重写OnNavigatedTo方法,接收主页传递的参数。其代码如代码清单2-4所示。

代码清单 2-4

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)

{

base.OnNavigatedTo(e);

//从NavigationContext对象的QueryString字典集合中取得传递

//过来的数据

string data=this.NavigationContext.QueryString["data"];

if(!string.IsNullOrEmpty(data))

{

this.textBlockDisplay.Text=data;

}

}

从NavigationContext.QueryString字典集合中取出的参数就是导航URI中“?”(英文字符的问号)后面的内容,多个参数用字符“&”连接,例如a=123&b=456,“=”左边的是参数名,右边是参数值。我们从参数字典集合中取出参数就是根据参数名来检索的,因此,参数列表中,参数名必须唯一,不能出现重复。(5)按F5键运行程序。

完整的实例代码请参考随书源码中的\第2章\Sample_2_4。2.5 URI映射背景知识

前面虽然提到了通过URI参数在页面导航中传递数据的方法,但如果遇到的是多个参数呢?这时候,需要考虑的因素可能会很多,如果还是使用XAML代码来设置URI,那么需要考虑到&字符的转义问题。另外,过于复杂的URI不便于管理,所以此时URI映射就可以发挥它的作用了,这样一来可以用它把复杂的URI变成简洁的、易于记忆的形式;二来它可以在一定程度上提高安全性。

举个例子来帮助理解,假设正在访问一个URI为/ask/2/3765的页面,而这个URI是通过映射呈现的,实际访问的URI是/askItem.xaml?type=2&id=3765,那么,很显然,前一种URI形式更易于理解和于记忆。

将上面的例子抽象出来,可以得到这样的映射规则,即:/ask/{type}/{id}映射的是/askItem.xaml?type={type}&id={id}。认真观察会发现,{type}和{id}只是占位符,应用程序先从/ask/{type}/{id}中找出这两个占位符,如果URI为/ask/2/3765,则{type}的值就是2,{id}的值就是3765,如果用相同的占位符名字替换/askItem.xaml?type={type}&id={id}中的占位符的值,可得到实际的URI,即为/askItem.xaml?type=2&id=3765。

其实,在/ask/{type}/{id}中,应用程序只关心{type}和{id}的值,其他字符则被忽略,这里的ask是为了帮助理解,以便让我们知道这个URI是导航到askItem.xaml页面的。对于符号“/”,它有两个作用,一是“/”不需要转义,而且在URI中如此表示也很符合我们的习惯;第二个作用是最重要的,即用于有效分隔每个占位符,就拿上面的例子来说,若是写成{type}{id},其URI就变成了/ask/23765,如此一来,应用程序就不知道怎么匹配参数了,{type}要如何确定呢?是2还是23?或者是237?而{id}就更无法识别了,是23765还是3765,或者是765?

实现URI映射主要是通过设置PhoneApplicationFrame类的UriMapper属性来完成的,UriMapper有一个UriMappings属性,它是一个集合,可以向其中添加UriMapping类的实例,UriMapping的Uri属性是映射后的URI,即/ask/{type}/{id},而MappedUri则为要访问的真实URI,即/askItem.xaml?type={type}&id={id}。实例演练

本实例与前面的导航实例相似,只是增加了URI映射。在主页面中允许输入3个参数,如空间坐标X、Y、Z,通过URI映射技术,很方便地把这3个参数传递到了第二个页面上,运行效果如图2-4所示。图 2-4 将第一个页面输入的内容传到第二个页面

实例实现步骤如下:(1)新建一个Windows Phone应用程序项目。(2)完成MainPage.xaml的布局,其代码如下:

<phone:PhoneApplicationPage

x:Class="Sample_2_5.MainPage"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"

xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"

FontFamily="{StaticResource PhoneFontFamilyNormal}"

FontSize="{StaticResource PhoneFontSizeNormal}"

Foreground="{StaticResource PhoneForegroundBrush}"

SupportedOrientations="Portrait" Orientation="Portrait"

shell:SystemTray.IsVisible="True">

<!--LayoutRoot是包含所有页面内容的根网格-->

<Grid x:Name="LayoutRoot" Background="Transparent">

<Grid.RowDefinitions>

<RowDefinition Height="Auto"/>

<RowDefinition Height="*"/>

</Grid.RowDefinitions>

<!--TitlePanel包含应用程序的名称和页标题-->

<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">

<TextBlock x:Name="ApplicationTitle" Text="我的应用程序" Style="{StaticResource PhoneTextNormalStyle}"/>

<TextBlock x:Name="PageTitle" Text="我的主页" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>

</StackPanel>

<Grid Grid.Row="1" Margin="0,15">

<Grid.RowDefinitions>

<RowDefinition Height="Auto"/>

<RowDefinition Height="Auto"/>

<RowDefinition Height="Auto"/>

<RowDefinition Height="Auto"/>

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="*"/>

<ColumnDefinition Width="3*"/>

</Grid.ColumnDefinitions>

<TextBlock Grid.Column="0" Grid.Row="0" Text="X:"HorizontalAlignment="Center" VerticalAlignment="Center"/>

<TextBlock Grid.Column="0" Grid.Row="1" Text="Y:"HorizontalAlignment="Center" VerticalAlignment="Center"/>

<TextBlock Grid.Column="0" Grid.Row="2" Text="Z:"HorizontalAlignment="Center" VerticalAlignment="Center"/>

<TextBox x:Name="txtX" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Stretch"/>

<TextBox x:Name="txtY" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Stretch"/>

<TextBox x:Name="txtZ" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Stretch"/>

<Button x:Name="btnOK" Grid.ColumnSpan="2" Grid.Row="3" Content="转到第二个页面" Click="btnOK_Click"/>

</Grid>

</Grid>

</phone:PhoneApplicationPage>

上面代码中,页面中放置了3个TextBlock控件,3个TextBox控件。TextBlock控件负责显示静态文本(即提示文字),TextBox控件允许用户输入内容,名为btnOK的Button控件用于确认提交。(3)处理按钮的单击事件,其代码如下:

private void btnOK_Click(object sender,RoutedEventArgs e)

{

if(txtX.Text==""||txtY.Text==""||txtZ.Text=="")

{

return;

}

string MyUri=string.Format("/second/{0}/{1}/{2}",txtX.Text,txtY.Text,txtZ.Text);

this.NavigationService.Navigate(new Uri(MyUri,UriKind.Relative));

}(4)新建一个页面,并命名为Second.xaml,其布局代码如代码清单2-5所示。

代码清单 2-5

<phone:PhoneApplicationPage

x:Class="Sample_2_5.Second"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"

xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

FontFamily="{StaticResource PhoneFontFamilyNormal}"

FontSize="{StaticResource PhoneFontSizeNormal}"

Foreground="{StaticResource PhoneForegroundBrush}"

SupportedOrientations="Portrait" Orientation="Portrait"

mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"

shell:SystemTray.IsVisible="True">

<Grid>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="*"/>

<ColumnDefinition Width="3*"/>

</Grid.ColumnDefinitions>

<Grid.RowDefinitions>

<RowDefinition Height="auto"/>

<RowDefinition Height="auto"/>

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载