一、Windows Phone 7 框架(PhoneApplicationFrame)和页面(PhoneApplicationPage)

在一个wp7应用程序运行的时候,程序的整个UI架构会由会有一个PhoneApplicationFrame和一个或者多个PhoneApplicationPage组成。PhoneApplicationFrame是一个顶级容器,里面容纳了PhoneApplicationPage,一个程序里面只有一个PhoneApplicationFrame,我们在App.xaml.cs里面看到的RootFrame就是当前程序的框架了。

下面的方法会对RootFrame完成初始化操作

 

  1. private void InitializePhoneApplication()  
  2.         {  
  3.             if (phoneApplicationInitialized)  
  4.                 return;  
  5.             RootFrame = new PhoneApplicationFrame();  
  6.             RootFrame.Navigated += CompleteInitializePhoneApplication;  
  7.             RootFrame.NavigationFailed += RootFrame_NavigationFailed;  
  8.             phoneApplicationInitialized = true;  
  9.         }  
  10.  
  11.         private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)  
  12.         {  
  13.             if (RootVisual != RootFrame)  
  14.                 RootVisual = RootFrame;  
  15.             RootFrame.Navigated -CompleteInitializePhoneApplication;  
  16.         } 

关于(PhoneApplicationFrame)和(PhoneApplicationPage)的关系可以用下面的一张图来表示

Windows Phone 7 框架和页面 _框架 

二、页面(PhoneApplicationPage)的导航

wp7页面的互相跳转的逻辑是用一个堆栈结构的容器来管理这些页面。如下图

 

Windows Phone 7 框架和页面 _页面 _02 

当应用程序中的页面调用 Navigate 时,当前页面会被放到后退堆栈上,并且系统将创建并显示目标页的新实例。当你在应用程序的页面之间进行导航时,系统会将多个条目添加到此堆栈。当页面调用 GoBack 时,或者当用户按手机的“返回”按键时,将放弃当前页面,并将堆栈顶部的页面从后退堆栈中弹出并进行显示。此后退导航会继续弹出并显示,直到堆栈中不再有条目。此时,点按手机的“返回”按键将终止应用程序。

这个堆栈容器我们是可以通过PhoneApplicationPage出操控的,操控的相关方法和属性如下:

属性
BackStack 获取一个 IEnumerable,它用于枚举后退导航历史记录中的条目。
CanGoBack 获取一个值,该值指示在后退导航历史记录中是否至少存在一个条目。

CanGoForward 获取一个值,该值指示在前进导航历史记录中是否至少存在一个条目。

 

方法

GoBack 导航到后退导航历史记录中的最新条目;如果后退导航时没有条目,则引发异常。

GoForward 导航到前进导航历史记录中的最新条目,如果前进导航时没有条目,则引发异常。对于Windows Phone,该方法始终引发异常,因为没有前进导航堆栈。 (从 Frame 继承。)
RemoveBackEntry 此方法用于从后退堆栈中移除最近的条目,如果没有要移除的条目,则引发InvalidOperationException。如果您想移除多个项目,则多次调用此方法。此 API 是同步的,因此必须从UI 线程调用。

 

事件
Navigated 当已找到导航的内容并且内容可用时发生。 (从 Frame 继承。)
Navigating 当请求新的导航时发生。 (从 Frame 继承。)
NavigationFailed 在导航到请求的内容过程中遇到错误时发生。 (从 Frame 继承。)
NavigationStopped 在通过调用 StopLoading()()()() 方法终止导航时发生,或者在当前导航进行过程中请求新的导航时发生。 (从 Frame 继承。)
Obscured 当 shell chrome 包含帧时发生。
OrientationChanged 当 Orientation 属性发生更改时发生。

 

三。下面用跟一个Demo来显示一下获取程序的 框架(PhoneApplicationFrame)和页面(PhoneApplicationPage)

扩展方法类

Extensions.cs

 

  1. using System.Windows;  
  2. using System.Windows.Media;  
  3. using System.Collections.Generic;  
  4. using System.Linq;  
  5.  
  6. namespace PageDemo  
  7. {  
  8.     public static class Extensions  
  9.     {  
  10.         /// <summary> 
  11.         /// 获取该元素的可见树里面所有的子元素  
  12.         /// </summary> 
  13.         /// <param name="element">可见元素</param> 
  14.         public static IEnumerable<DependencyObject> GetVisualDescendants(this DependencyObject element)  
  15.         {  
  16.             return GetVisualDescendantsAndSelfIterator(element).Skip(1);  
  17.         }  
  18.         /// <summary> 
  19.         /// 获取该元素的可见树里面所有的子元素以及该元素本身  
  20.         /// </summary> 
  21.         /// <param name="element">可见元素</param> 
  22.         public static IEnumerable<DependencyObject> GetVisualDescendantsAndSelfIterator(DependencyObject element)  
  23.         {  
  24.             Queue<DependencyObject> remaining = new Queue<DependencyObject>();  
  25.             remaining.Enqueue(element);  
  26.  
  27.             while (remaining.Count > 0)  
  28.             {  
  29.                 DependencyObject obj = remaining.Dequeue();  
  30.                 yield return obj;  
  31.  
  32.                 foreach (DependencyObject child in obj.GetVisualChildren())  
  33.                 {  
  34.                     remaining.Enqueue(child);  
  35.                 }  
  36.             }  
  37.         }  
  38.         /// <summary> 
  39.         /// 获取该元素的可见树里面下一级的子元素  
  40.         /// </summary> 
  41.         /// <param name="element">可见元素</param> 
  42.         public static IEnumerable<DependencyObject> GetVisualChildren(this DependencyObject element)  
  43.         {  
  44.             return GetVisualChildrenAndSelfIterator(element).Skip(1);  
  45.         }  
  46.         /// <summary> 
  47.         /// 获取该元素的可见树里面下一级的子元素以及该元素本身  
  48.         /// </summary> 
  49.         /// <param name="element">可见元素</param> 
  50.         public static IEnumerable<DependencyObject> GetVisualChildrenAndSelfIterator(this DependencyObject element)  
  51.         {  
  52.             yield return element;  
  53.  
  54.             int count = VisualTreeHelper.GetChildrenCount(element);  
  55.             for (int i = 0; i < count; i++)  
  56.             {  
  57.                 yield return VisualTreeHelper.GetChild(element, i);  
  58.             }  
  59.         }  
  60.     }  

测试获取程序页面类

Test.cs

 

  1. using System.Windows;  
  2. using Microsoft.Phone.Controls;  
  3. using System.Linq;  
  4. using System.Collections.Generic;  
  5.  
  6. namespace PageDemo  
  7. {  
  8.     public class Test  
  9.     {  
  10.         /// <summary> 
  11.         /// 获取当前的程序展示的页面  
  12.         /// </summary> 
  13.         public static PhoneApplicationPage Page  
  14.         {  
  15.             get { return (Application.Current.RootVisual as PhoneApplicationFrame).GetVisualDescendants().OfType<PhoneApplicationPage>().FirstOrDefault(); }  
  16.         }  
  17.         /// <summary> 
  18.         /// 获取所有的框架下的页面  
  19.         /// </summary> 
  20.         public static List<PhoneApplicationPage> Pages  
  21.         {  
  22.             get { return (Application.Current.RootVisual as PhoneApplicationFrame).GetVisualDescendants().OfType<PhoneApplicationPage>().ToList<PhoneApplicationPage>(); }  
  23.         }  
  24.         /// <summary> 
  25.         /// 获取程序所有的UI元素  
  26.         /// </summary> 
  27.         public static List<DependencyObject> Elements  
  28.         {  
  29.             get { return (Application.Current.RootVisual as PhoneApplicationFrame).GetVisualDescendants().ToList<DependencyObject>(); }  
  30.         }  
  31.     }  

 

 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Button Content="Button" Height="72" HorizontalAlignment="Left" Margin="139,176,0,0" Name="button1" VerticalAlignment="Top" Width="160" Click="button1_Click" />
        </Grid> 

 

 

  1. private void button1_Click(object sender, RoutedEventArgs e)  
  2.         {  
  3.             if (Test.Page != null)  
  4.             {  
  5.                 MessageBox.Show(Test.Page.ToString());  
  6.             }  
  7.         } 

单击的效果

 

Windows Phone 7 框架和页面 _页面 _03