一、Windows Phone 7 框架(PhoneApplicationFrame)和頁面(PhoneApplicationPage)
在一個wp7應用程序運行的時候,程序的整個UI架構會由會有一個PhoneApplicationFrame和一個或者多個PhoneApplicationPage組成。PhoneApplicationFrame是一個頂級容器,里面容納了PhoneApplicationPage,一個程序里面只有一個PhoneApplicationFrame,我們在App.xaml.cs里面看到的RootFrame就是當前程序的框架了。
下面的方法會對RootFrame完成初始化操作
private void InitializePhoneApplication()
{
if (phoneApplicationInitialized)
return;
RootFrame = new PhoneApplicationFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication;
RootFrame.NavigationFailed += RootFrame_NavigationFailed;
phoneApplicationInitialized = true;
}
private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
{
if (RootVisual != RootFrame)
RootVisual = RootFrame;
RootFrame.Navigated -= CompleteInitializePhoneApplication;
}
關於(PhoneApplicationFrame)和(PhoneApplicationPage)的關系可以用下面的一張圖來表示
二、頁面(PhoneApplicationPage)的導航
wp7頁面的互相跳轉的邏輯是用一個堆棧結構的容器來管理這些頁面。如下圖

當應用程序中的頁面調用 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
using System.Windows;
using System.Windows.Media;
using System.Collections.Generic;
using System.Linq;
namespace PageDemo
{
public static class Extensions
{
/// <summary>
/// 獲取該元素的可見樹里面所有的子元素
/// </summary>
/// <param name="element">可見元素</param>
public static IEnumerable<DependencyObject> GetVisualDescendants(this DependencyObject element)
{
return GetVisualDescendantsAndSelfIterator(element).Skip(1);
}
/// <summary>
/// 獲取該元素的可見樹里面所有的子元素以及該元素本身
/// </summary>
/// <param name="element">可見元素</param>
public static IEnumerable<DependencyObject> GetVisualDescendantsAndSelfIterator(DependencyObject element)
{
Queue<DependencyObject> remaining = new Queue<DependencyObject>();
remaining.Enqueue(element);
while (remaining.Count > 0)
{
DependencyObject obj = remaining.Dequeue();
yield return obj;
foreach (DependencyObject child in obj.GetVisualChildren())
{
remaining.Enqueue(child);
}
}
}
/// <summary>
/// 獲取該元素的可見樹里面下一級的子元素
/// </summary>
/// <param name="element">可見元素</param>
public static IEnumerable<DependencyObject> GetVisualChildren(this DependencyObject element)
{
return GetVisualChildrenAndSelfIterator(element).Skip(1);
}
/// <summary>
/// 獲取該元素的可見樹里面下一級的子元素以及該元素本身
/// </summary>
/// <param name="element">可見元素</param>
public static IEnumerable<DependencyObject> GetVisualChildrenAndSelfIterator(this DependencyObject element)
{
yield return element;
int count = VisualTreeHelper.GetChildrenCount(element);
for (int i = 0; i < count; i++)
{
yield return VisualTreeHelper.GetChild(element, i);
}
}
}
}
測試獲取程序頁面類
Test.cs
using System.Windows;
using Microsoft.Phone.Controls;
using System.Linq;
using System.Collections.Generic;
namespace PageDemo
{
public class Test
{
/// <summary>
/// 獲取當前的程序展示的頁面
/// </summary>
public static PhoneApplicationPage Page
{
get { return (Application.Current.RootVisual as PhoneApplicationFrame).GetVisualDescendants().OfType<PhoneApplicationPage>().FirstOrDefault(); }
}
/// <summary>
/// 獲取所有的框架下的頁面
/// </summary>
public static List<PhoneApplicationPage> Pages
{
get { return (Application.Current.RootVisual as PhoneApplicationFrame).GetVisualDescendants().OfType<PhoneApplicationPage>().ToList<PhoneApplicationPage>(); }
}
/// <summary>
/// 獲取程序所有的UI元素
/// </summary>
public static List<DependencyObject> Elements
{
get { return (Application.Current.RootVisual as PhoneApplicationFrame).GetVisualDescendants().ToList<DependencyObject>(); }
}
}
}
<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>
private void button1_Click(object sender, RoutedEventArgs e)
{
if (Test.Page != null)
{
MessageBox.Show(Test.Page.ToString());
}
}
單擊的效果