本篇介绍一下Windows Phone 8.1 中页面导航的实现方式。
大家对Windows Phone 8 中页面导航的实现一定不陌生,我们使用 NavigationService 来实现。具体写法是这样的:
NavigationService.Navigate(new Uri("XAML相对路径", UriKind.RelativeOrAbsolute));
而在导航目标页,我们在 OnNavigatedTo 方法中通过 NavigationContext.QueryString["key"] 来接收页面传递的参数。
当按下回退键时,导航源页面会被从回退栈中取出显示,这样我们就完成了一个完整的页面导航过程。
而在Windows Phone 8.1 中,导航方式有所不同,首先我们需要在导航源页面做如下处理:
Frame.Navigate(typeof(NavigationDemoPage), null);
我们利用到了Page内容控制Frame的Navigate方法,它有两个参数,第一个参数是导航目标页的类型,第二个参数(可选)为页面间传递的参数。
而在目标页,我们通过 NavigationHelper 来完成接受参数和其他处理。当我们在项目中新建一个基本页(BasicPage)时,Common文件夹中会出现NavigationHelper类和其他一些辅助类。
NavigationHelper 有两个很重要的事件 LoadState 和 SaveState,分别用来加载已保存状态和保存当前页的状态。而接收导航参数就会用到LoadState 事件,来看看我们在它的注册方法中的处理:
private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e) { var param = e.NavigationParameter; }
与Windows Phone 8中可传递多个字符串参数不同的是,8.1 中导航参数只有一个,而且是object 类型,这也就是说我们可以传递包括字符串在内的很多自定义类型,这在参数传递和使用上无疑方便了很多。
在按下回退键时,页面返回到导航源。而如果我们没有使用NavigationHelper 的话,页面是没有办法正常回退的,这是怎么回事呢,我们来看看NavigationHelper 的构造函数吧:
public NavigationHelper(Page page) { this.Page = page; // 当此页是可视化树的一部分时,进行两个更改: // 1) 将应用程序视图状态映射到页的可视状态 // 2) Handle hardware navigation requests this.Page.Loaded += (sender, e) => { #if WINDOWS_PHONE_APP Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed; #else // 仅当占用整个窗口时,键盘和鼠标导航才适用 if (this.Page.ActualHeight == Window.Current.Bounds.Height && this.Page.ActualWidth == Window.Current.Bounds.Width) { // 直接侦听窗口,因此无需焦点 Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated += CoreDispatcher_AcceleratorKeyActivated; Window.Current.CoreWindow.PointerPressed += this.CoreWindow_PointerPressed; } #endif }; // 当页不再可见时,撤消相同更改 this.Page.Unloaded += (sender, e) => { #if WINDOWS_PHONE_APP Windows.Phone.UI.Input.HardwareButtons.BackPressed -= HardwareButtons_BackPressed; #else Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated -= CoreDispatcher_AcceleratorKeyActivated; Window.Current.CoreWindow.PointerPressed -= this.CoreWindow_PointerPressed; #endif }; }
我们看到,这是有一个条件编译符 WINDOWS_PHONE_APP。在使用了NavigationHelper 的Page 中,Loaded 和 UnLoaded 事件处理代码中都加入了Windows.Phone.UI.Input.HardwareButtons.BackPressed 的处理,这就是对硬件回退按钮点击的响应,响应事件如下:
private void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e) { if (this.GoBackCommand.CanExecute(null)) { e.Handled = true; this.GoBackCommand.Execute(null); } }
public RelayCommand GoBackCommand { get { if (_goBackCommand == null) { _goBackCommand = new RelayCommand( () => this.GoBack(), () => this.CanGoBack()); } return _goBackCommand; } set { _goBackCommand = value; } }
我们看到,事件的处理中执行了GoBackCommand 来导航到导航历史中的最新项。
最有还有一点要说明,Windows Phone 8.1 中,页面导航回退时,导航源页面会重新Load,对于需要加载数据等的页面,这种重新加载的结果并不是我们想看到的。
这里我们可以使用 NavigationCacheMode 来避免这一现象,我们在页面构造方法中对它进行设置,它是一个枚举类型,有三种枚举值:
- Disabled 不缓存页面,导航返回时重新加载页面
- Required 缓存页面,且不考虑缓存大小
- Enabled 缓存页面,但是当超过缓存大小的限制时,放弃缓存。
好了,到这里我们就把Windows Phone 8.1 中的页面导航相关知识介绍完了,希望对大家有帮助,谢谢。