Windows Phone 7 – Navigation Framework原理概论

在学习Windows Phone 7开发时,如果你本身对Silverlight或WPF开发有些了解的话,Navigation Framework我相信一定是大家

会用到的部分。因此,这一篇是我自己在学习Windows Phone 7 Application开发时,我觉得需要花一些时间去好好搞懂他底层

原理的部分。

 

首先,Windows Phone 7的Application主要是基于Silverlight Page Model,提供用户可以导向指定的Page,更换不同的内容,

因此,你可以建立很多个页面(Page)在同一个框架(Frame)内进行浏览。那在FramePage二个的运作关系,往下就仔细说明。

 

在这里我不得不感谢一直支持我的卤面网版主,是他让我提起兴趣写了这么一篇文章,再次感谢卤面网,一个非常不错的wp7开发论坛,后面我也将再次向大家发布几篇高质量文章,请大家到卤面上找我吧,呵呵

    进入正题:

 

〉PhoneApplicationFrame与PhoneApplicationPage

通过过下图可以了解二者之间的关系,它们都是Microsoft.Phone.Controls Namespace里重要的组件:

(a) PhoneApplicationFrame ( PhoneApplicationFrame Class ):

一个WP7 Application会有一个Frame,该Frame专门来控制内部包括的Page、Control与其他的Element

负责控制整个WP Application呈现的方式,例如:Orientation Property、Render的范围等,更包括Status Bar与ApplicationBar。

以上是MSDN上的说明,PhoneApplicationFrame可以用的功能还包括:

a-1. PhoneApplicationPage之间的资料交换;

a-2. 结合App.xaml控制整个ApplicationPage内的内容与控件

a-3. 控制PhoneApplicationPage的切换

有几个Events要特别注意:NavigatedNavigatingNavigationFailedNavigationStopped,这四个是在进行Navigate过程时,

当ApplicationPage里提出Navigate()、GoBack()或GoForward()后,会将控制权移转至Frame透过四个Event来进行处理。

 

(b) PhoneApplicationPage ( PhoneApplicationPage Class ):

它是个Page类,Page类提供运行Navigation Framework的处理事件与服务。因此,在一些Sample Code看到的Navigate(),

其实都是通过Page类进行运作,往上抛转给PhoneApplicationFrame来进行导向的任务。PhoneApplicationPage会在产生一份

Xaml文件时,就被给予一个对应,它内容可以包括所有User Control里的资料,当然也有:pivot、chart等。另外,针对Orientation

的改变,即透过OrientationChanged该Event来负责。如果你的代码里针对方向有特别需要,该Event将会协助你处理不少事情。

 

 

上面叙述了关于整个Windows Phone Application运行的基本元素,接下来说明元素之间如何互相导向与移动,这是在实例

过程里,我觉得需要来了解的:

 

〉Page导航的重要元素– Navigation Framework

Windows Phone Applications是由Silverlight Pages所组合而成,为了让Pages之间可以互相浏览与串联,因此,存在了一个

Navigation Stack」。该Stack透过First in first out的概念储存了所有浏览过程的Page,协助按下Back键时回到目标的页面。

但在此,MSDN上也提到「过度使用Page,将可能造成Application储存了多余残留的Page资讯在navigation stack中,影响应

用程度的性能与可靠性」。

 

针对Page类处理导航任务,可以透过NavigationService.Navigate()、GoBack()或GoForward()来进行,然而这三个方法对于

Page的影响与运作流程,可以分成五个必要的Event Handler:

〉Loaded (代表每一次页面载入完成后,触发的事件。)

〉Unloaded (从目前该页面要导向另一个页面时,触发的事件。)

〉OnNavigatingFrom (通过NavigationService,要从目前页面离开过程时,触发该事件。)

〉OnNavigatedFrom (通过NavigationService,要从目前页面离开后,触发该事件。)

   OnNavigatingFrom与OnNavigatedFrom二个是先后顺序的关系,通常处理事件都会在OnNavigatedFrom里,这不代表

   你就不能加入在OnNavigatingFrom处理需要任务,只是OnNavigatingFrom故名思义,它是被触发于当目前页面不被在

   使用之前,此时,我们可以用于完成一些任务,例如:关闭目前正在播放的动画等。

〉OnNavigatedTo (透过NavigationService,前往新的页面时会自动触发新的页面的OnNavigatedTo事件。)

 

每一个XAML文件针对Page载入触发顺序,可以通过下图来加以说明:

(a) 从MainPage.xaml要前往SecondPage.xaml时,先触发了本身的OnNavgatingFrom与OnNavigatedFrom准备结束本页;

(b) 接着SecondPage.xaml触发OnNavigationTo事件,准备把本页要用的资料透过上一页转过来;

(c) MainPage.xaml完成NavigateService导向SecondPage.xaml后,触发Unloaded事件;

(d) 最后SecondPage.xaml触发Loaded事件开始载入该页面需要组件与内容;

 

至于二页资料要传过去的方法,可以参考该篇的介绍方法:< How to: Perform Page Navigation on Windows Phone >,

它透过NavigateService.Navigate()来传递参数在URL中,并且配合新的一页的OnNavigatedTo()来处理取得的资料。

上面运作的顺序,将会影响在处理Page交换时,资料的换手与储存。

 

当然,你也可以直接把页面之间要共享的资料内容,变成如下图的作法:

透过由App.xaml集中控管Page之间交换的信息,这样有一个好处只要透过App.xaml负责处理Application进入

deActive与Actived时要储存与取得信息的任务不需要每一个Page都去负责处理Tombstoning造成的影响。

 

另外,在使用Navigate时,我在其他文件里有看Sample会去对NavigateContext做一些处理与说明,那最后就来看看它是什么:

〉Page.NavigationContext

专门处理Navigation请求的内容,上述提及的透过Url传送参数的方法,就是把要传递的内容放置于该NavigationContext类别中。

透过QueryString属性来取得参数值。

 

====

以上是介绍WP7运作配合Navigation Framework的运用,这一篇其实蛮多基本的原理,撰写出来是为了让自己能够

更清楚他们运作原理的规则,才不会一直在开发上遇到一些根本的问题,而花费不少时间去走冤枉路。

学习WP7程式也有些时日,其实在整个开发过程里,遇到蛮多原理性的问题。由于我本身对Silverlight原理没有太深固的基础,

因此,很常会遇到不太明白为何画面没有办法正常出现或是导向失败,甚至连要如何透过Back离开自己开发的App也不明白。

这样的开发经验,其实让我感触深刻,特别将在学习整个Silverlight与WP7上学习的心得,通过该篇文章撰写一些必懂的一些概念。

 

补充 ]

〉WP7换页时的作法比较– PhoneApplicationPage.Content与PhoneApplicationPage.NavigationService

(a)使用Content来进行换页,其实原有的Page仍然存在,只是内容被转换成了新的一个画面,这样原先存在

     Page中的内容,将会被覆盖掉。按下Back键时,其画面不会回到上一个,而一直存在相同的页面。        

(b)使用NavigationService来换页,实际上是将Frame目前控件的Page指定另一个新的Page,原有的Page内容也会被

     保留下来。按下Back键时,就可以回到上一个Page。注意的是,Back键回去的Page是刚才被产生的instance,

     它并不是一个全新的Page。

 

〉PhoneApplicationFrame与RootVisual

打开App.xaml.cs里,也许你会发现这一段代码:

// Do not add any additional code to this method
private void CompleteInitializePhoneApplication( object sender, NavigationEventArgs e)
{
// Set the root visual to allow the application to render
if (RootVisual != RootFrame)
RootVisual = RootFrame;

// Remove this handler since it is no longer needed
RootFrame.Navigated -= CompleteInitializePhoneApplication;
}

不知道你是否跟我一样好奇,什么是RootVisual

其实在整个运作Application一开始,还没有真正载入Page或Frame的时候(也就是在程式出现splash screen的时间点),该Application是

没有主画面的,因此,可以看到当App.xaml在InitializePhoneApplication()方法时,写上了下面代码:

 // Do not add any additional code to this method
private void InitializePhoneApplication()
{
if (phoneApplicationInitialized)
return ;

// Create the frame but don't set it as RootVisual yet; this allows the splash
// screen to remain active until the application is ready to render.
RootFrame = new PhoneApplicationFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication;

// Handle navigation failures
RootFrame.NavigationFailed += RootFrame_NavigationFailed;

// Ensure we don't initialize again
phoneApplicationInitialized = true ;
}

在代码一开始初始化了一组RootFrame(也就是PhoneApplicationFrame),并且在RootFrame完成Navigated事件处理时,即调用

CompleteInitializePhoneApplication()事件处理者,该事件处理者就把RootFrame指定给RootVisu​​al,让应用程序得知主画面是谁。

然而,Frame成为了主画面,而PhoneApplicationPage只是Frame中的Content。

换句话说,RootVisual就是用来取得或设定主要应用程序的UI所以我们才可以透过Frame来控制所有的Page。但是,

它有一个先天的条件:「您只能从代码码设定RootVisual属性值一次,但是可不限次数地取得其值。」这点要特别注意。

 

〉离开WP7程序

虽然说这个标题不是什么太新鲜的话题了,但想大家都知道要从自己程序离开的话,直接透过丢出一个Exception来进行处理,

就可以离开自己的程式了,但也还有其他的方式。那就是透过「Microsoft.XNA.Game」这个Namespace,直接使用Game类别提供

的”Exit()”方法来离开。大家可以试看看。

 

 

 

〉Application Page Model of Windows Phone:

Application Page Model是WP7整个运作的关键,它与该篇介绍的Navigation Framework是互相关联的,因此,如果这篇内容,

有写的不够详细的地方,可以直接往Application Page Model这个关键字下去搜寻。另外,顺带一提,在MSDN文件里有看到

Page与Screen的定义,二者的差别在于:

 

  Page Screen
  A user-recognizable collection of persistent state. not a user-recognizable collection of persistent state
  as a Silverlight page that contains information, memorable content, or links to other pages. such as a pop-up window, dialog box, or splash screen .

〉选取MSDN上针对Navigation使用的建议:

A. Screens and Non-Navigational Transitions

    针对transient UI(短暂出现的UI),建议使用Pop-Up Control去呈现内容。学习BackKeyPress事件去隐藏PopUp(或Dialog box)的内容。

B. Multiple Content Views

    对于使用多个页面显示内容,建议可以使用多个DataContext元件来通过与用户的操作进行信息的互动与呈现。当然,你可以使用

    多个Page来使用会比较容易,但必须注意Back键的处理以免造成多余的stack信息被储存下来。

C. Saving State and Tombstoning

    建议注意代码储存目前状态的处理,由于程序可能被转换成tombstone,因此,可以透过NavigationContext API来保留目前状态或识

    别导向来往二边的状态与信息,进一步控制呈现的信息内容。  


我希望你能喜欢我的文章!如果你有更多想法,请到卤面网 wp7开发论坛(codewp7.com)问答区联系我,我会很高兴知道你在想什么。同时wp7交流QQ群172765887中,也能找到我的身影,感谢大家,也欢迎大家关注我的微薄(www.weibo.com/codewp7)




posted on 2012-03-07 23:50  yewenpeng  阅读(1149)  评论(0编辑  收藏  举报