1. Windows Phone 8.1 的应用框架
一个应用拥有 1 个 Window,一个 Window 包含 1 个 Frame,一个 Frame 包含 多个 Page。
获取 Frame 的方法为:
Frame rootFrame = Window.Current.Content as Frame;
用 Page 填充 Frame 的方法为:
rootFrame.Navigate(typeof(MainPage))
2. Windows Phone 8.1 与 Windows Phone 8.0 导航的不同
(1)“返回键”的默认行为是返回到上一个应用(没有上一个应用则返回桌面),并不是上一个页面。
若想要实现返回上一个页面的操作,则需要改写 HardwareButtons.BackPressed 事件:
public App(){ this.InitializeComponent(); this.Suspending += this.OnSuspending; HardwareButtons.BackPressed += HardwareButtons_BackPressed;}private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e){ Frame rootFrame = Window.Current.Content as Frame; if( rootFrame != null && rootFrame.CanGoBack ) { rootFrame.GoBack(); e.Handled = true; }}
或者只对某个 Page 改写:
protected override void OnNavigatedTo(NavigationEventArgs e){ HardwareButtons.BackPressed += HardwareButtons_BackPressed;}private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e){ e.Handled = true; if( Frame.CanGoBack ) Frame.GoBack();}protected override void OnNavigatedFrom(NavigationEventArgs e){ HardwareButtons.BackPressed -= HardwareButtons_BackPressed;}
(2)导航方法改为 Frame.Navigate。
导航时不再需要填写下一个页面的 Uri,而是直接使用页面的类型,并且可以直接将 Object 传递到下一个页面:
Frame.Navigate(typeof(Page2), "From MagePage.");
当然,这就需要下一个页面对传递过来的 Object 进行拆箱:
protected override void OnNavigatedTo(NavigationEventArgs e){ myTextBlock.Text = (string)e.Parameter;}
应用可以获取之前的导航历史记录(不包括当前页面),Frame.BackStack 返回的是 IList<PageStackEntry>:
ListbackStack = new List ();foreach( var item in Frame.BackStack ){ backStack.Add(item.SourcePageType.Name);}myListView.ItemsSource = backStack;
可以轻松移除导航历史中的某项:
var backStack = Frame.BackStack;backStack.RemoveAt(Frame.BackStackDepth - 1);if( Frame.CanGoBack ) Frame.GoBack();
应用默认不对页面进行缓存,若要缓存当前页面则可以设置页面 NavigationCacheMode 属性:
public MainPage(){ this.InitializeComponent(); this.NavigationCacheMode = NavigationCacheMode.Required;}
同样可以更改 App.xaml.cs 里 OnLaunched 方法的 CacheSize:
protected override void OnLaunched(LaunchActivatedEventArgs e){ Frame rootFrame = Window.Current.Content as Frame; if( rootFrame == null ) { rootFrame = new Frame(); // TODO: 将此值更改为适合您的应用程序的缓存大小 rootFrame.CacheSize = 1;if( e.PreviousExecutionState == ApplicationExecutionState.Terminated ) { } Window.Current.Content = rootFrame; } if( rootFrame.Content == null ) { if( rootFrame.ContentTransitions != null ) { this.transitions = new TransitionCollection(); foreach( var c in rootFrame.ContentTransitions ) { this.transitions.Add(c); } } rootFrame.ContentTransitions = null; rootFrame.Navigated += this.RootFrame_FirstNavigated; if( !rootFrame.Navigate(typeof(MainPage), e.Arguments) ) { throw new Exception("Failed to create initial page"); } } Window.Current.Activate();}
如果你新建的项目不是空白项目,则会在项目中发现一个 Common 文件夹,而该文件夹中会有一个 NavigationHelper 类。
该类会帮你解决应用的导航问题,使用方法:
(1) 在某处创建一个 NavigationHelper 实例(如页面的构造函数中),并注册 LoadState 和 SaveState 事件的回调。
public MyPage(){ this.InitializeComponent(); var navigationHelper = new NavigationHelper(this); this.navigationHelper.LoadState += navigationHelper_LoadState; this.navigationHelper.SaveState += navigationHelper_SaveState;}private async void navigationHelper_LoadState(object sender, LoadStateEventArgs e){ }private async void navigationHelper_SaveState(object sender, LoadStateEventArgs e){ }
(2) 在以下情况下注册页面以调入 NavigationHelper: 该页面通过重写 OnNavigatedTo 和 OnNavigatedFrom 事件以参与导航:
protected override void OnNavigatedTo(NavigationEventArgs e){ navigationHelper.OnNavigatedTo(e);}protected override void OnNavigatedFrom(NavigationEventArgs e){ navigationHelper.OnNavigatedFrom(e);}