页面导航与参数传递
在学习过程中,大致的总结一些页面导航与参数传递的知识。
通常我们的应用程序是由多个应用页面构成的,于是就有一个十分重要的行为——页面间的切换。在这里成为页面间的导航。我们需要注意的问题是:怎么实现切换和怎么传递参数。
我们要了解的信息是:
显而易见,我们实现页面切换的必要数据就是每一个页面的URI,这和我们Web中的Uri的书写是相仿的,我们一样可以通过“?id=‘’”的形式来传递参数。
我们创建一个项目,叫做“NavigationPractice”,添加一个页面叫做“MyPage.xaml”,这是主页面MainPage需要导航到的页面。
四种页面切换的方式?
使用HyperlinkButton来实现
这也是HyperlinkButton的一个重要的应用方式,通过指定HyperlinkButton的NavigateUri属性,实现导航,具体实现:
<HyperlinkButton Content="点击跳转" Height="30" HorizontalAlignment="Left" Margin="28,41,0,0" Name="myHyperlinkButton" VerticalAlignment="Top" Width="200" NavigateUri="/MyPage.xaml"/>
?
在代码中进行导航
通过页面的NavigationService来实现,NavigationService在这里是页面PhoneApplicationPage的一个属性,取主机用于导航到此页的服务,实际是返回一个NavigationService类型的值,相当于是实例化一个NavigationService的对象。同理,用于接收参数的NavigationContext也是PhoneApplicationPage的一个属性,获取包含有关导航请求的信息的对象,实际上是返回一个NavigationContext类型的属性值,相当于是创建了一?个NavigationContext 的实例。
具体实现:定义一个按钮,给按钮添加Click事件,以实现导航。
this.NavigationService.Navigate(new Uri("/MyPage.xaml", UriKind.Relative));
?
返回操作
就是当在一个页面中操作完成后,返回到前一个页面中进行操作。
方法一:
使用代码:NavigationService.GoBack()。
方法二:
使用返回键实现返回操作。
补充:禁用返回按键的返回操作。给当前页面添加BackKeyPress事件,使用e.Cancel=true;的方式来禁用返回按键。
?
别名导肮
即定义系统资源,使用别名来实现导航。WP7页面导航可以使用路径别名,是从Silverlight继承来的。使用的方法涉及到资源的定义。方法如下:
首先,在App.xaml的文件中添加Windows.Navigation 命名空间:mlns:navigate="clr-namespace:System.Windows.Navigation;assembly=Microsoft.Phone"。
其次,书写资源代码:
<Application.Resources><navigate:UriMapper x:Key="UriMapper"><navigate:UriMapping Uri="MyNewPage" MappedUri="/MyPage.xaml"/></navigate:UriMapper></Application.Resources>
最后,给Frame添加UriMapper :this.RootFrame.UriMapper = Resources["UriMapper"] as UriMapper;即将这句代码写到App类的构造函数中。
在使用的时候,就像之前的应用一般,只是在路径名中直接书写路径别名就行了。
NavigationService.Navigate(new Uri("NewPage", UriKind.Relative));
?
?
五种页面间参数传递的方法
直接在Uri中添加
类似于web中的参数的传递方法,在Uri中使用”?id=‘’&name=‘’“的方式添加需要传递的参数。当然这不会局限于后台代码或者是HyperlinkButton的NavigateUri属性中,如:
this.NavigationService.Navigate(new Uri("/MyPage.xaml?flag=test",UriKind.Relative));
或:
<HyperlinkButton Content="点击跳转" Height="30" HorizontalAlignment="Left" Margin="28,41,0,0" Name="myHyperlinkButton" VerticalAlignment="Top" Width="200" NavigateUri="/MyPage.xaml?flag=test"/>
?
使用路径别名中传递参数
在资源的定义中,我们可以定义这样的资源:
<Application.Resources>
<navigate:UriMapper x:Key="UriMapper">
<navigate:UriMapping Uri="NewPage/{param}" MappedUri="/MyPage.xaml?ID={param}"/>
</navigate:UriMapper>
</Application.Resources>
这样通过定义之后,在使用的时候new Uri("NewPage/10", UriKind.Relative));就行了,在实际使用中,如果我们在定义资源Uri的时候,使用的名称和将要转到的页面的名称一致的话,会出现以下三种效果功能相同的使用方式:
/NewPage.xaml?ID=10
NewPage?ID=10
NewPage/ID=10
对于以上两种传递参数的方式,在接受的时候,使用NavigationContext。具体方法:
if (NavigationContext.QueryString.Keys.Contains("flag")) { NavigationContext.QueryString.TryGetValue("flag", out flag); myTextBlock1.Text=flag; }
为了很好的使用参数,避免异常等情况发生,在获取数据的时候最好先判断参数是不是存在。
?
配合独立存储传递参数
在导航的时候,配合独立存储,将需要传递的参数保存在独立存储中,由于一般传递的参数不会很大,笔者觉得使用IsolatedStorageSetting就行了。如在传递的时候:
private void btnNavigate5_Click(object sender, RoutedEventArgs e) { IsolatedStorageSettings iss = IsolatedStorageSettings.ApplicationSettings; iss["ID2"] = 10; NavigationService.Navigate(new Uri("NewPage", UriKind.Relative)); }
而在接受的时候:
IsolatedStorageSettings iss = IsolatedStorageSettings.ApplicationSettings; if (iss.Contains("ID2")) { this.myTextBlock1.Text=iss["ID2"].ToString(); }
这样也算是很方便的实现了数据的传递。
?
PhoneApplicationService传递参数
这个类提供对应用程序生存期各个方面的访问。这包括对应用程序空闲行为的管理以及当应用程序变为活动或不活动时对应用程序状态的管理。在这里主要是用到了它的state属性,获取用于调用之间传递应用程序状态的词典,用来存储数据。方法:
在将要跳转的页面中重写方法OnNavigatedFrom,将需要传递的参数保存在State中:
PhoneApplicationService myService = PhoneApplicationService.Current; protected override void OnNavigatedFrom(NavigationEventArgs e) { myService.State["name"] = "sky"; base.OnNavigatedFrom(e); }
在将要跳转到的页面中重写方法OnNavigatedTo,从State中读取字典数据:
PhoneApplicationService myService = PhoneApplicationService.Current; protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { object name; if (myService.State.ContainsKey("name")) { if (myService.State.TryGetValue("name", out name)) { this.myTextBlock3.Text = name.ToString(); } } base.OnNavigatedTo(e); }
?
共享数据传递参数
?
另一种常用的页面间共享数据的方法是使用公共资源App.xaml。在其后台代码中加入相应属性,即可使用。这种方法最经常用来传递对象,可以采用的办法是创建两个页面都可以访问到的静态对象。
具体实现:
public string Name{set;get;}
public string Number{set;get;}
在使用的时候:
(Application.Current as App).Name
(Application.Current as App).Number
如定义属性MyName,把需要传递的参数保存在共享数据中:
private void myTextBox_TextChanged(object sender, TextChangedEventArgs e) { (Application.Current as App).MyName = this.myTextBox.Text.ToString(); }
取得数据:
if ((Application.Current as App).MyName != "") { this.myTextBlock2.Text = (Application.Current as App).MyName; }
?
以上的各种方法,在我们的项目中最这样的布局,其实就是简单地实现:
实现结果为:
项目地址:http://files.cnblogs.com/waitingsky/NavigationPractice.rar