一、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());
}
}
單擊的效果