Windows Phone笔记(8)页面间数据共享
通过上一篇笔记我们知道了如何将源页面(调用navigation函数的页面)的数据传递到目标页面中,但是当我们把这个顺序反过来,即把目标页面的数据返回给源页面时该怎么去做呢?在这篇笔记中我们给出两个解决方案。
1.通过app类保存页面共享数据
在windows phone笔记中的第一篇笔记中我提到过:app类通常用来存储整个应用程序所使用的资源。该类从application类中派生,我们通过application.current属性可以返回当前应用程序的application对象,我们可以把理解为当前应用程序的实例,或者说一个全局变量,在各个页面都可以很轻易的访问到它。
和以前一样,我们通过一个简单的示例来学习如何使用app类在页面间共享数据,和上一篇笔记中给出的示例类似,我们首先在app.xaml.cs也就是为app类中定义一个类型为color?的属性,用于存储在页面间需要共享的数据:
1 public partial class app : application
2 {
3 //用于在页面间共享数据的公共属性,可空类型
4 public color? sharecolor { get; set; }
5 }
接着是这个示例的第一个页面mainpage.xaml的前端代码:
1 <!--contentpanel - 在此处放置其他内容-->
2 <grid x:name="contentpanel" grid.row="1" margin="12,0,12,0">
3 <textblock padding="0 34" fontsize="32" horizontalalignment="center" name="tblnavigationsecondpage" text="navigation to secondpage" verticalalignment="center" manipulationstarted="tblnavigationsecondpage_manipulationstarted"/>
4 </grid>
mainpage.xmal.cs后台程序处理代码:
1 public partial class mainpage : phoneapplicationpage
2 {
3 random ran = new random();
4 // 构造函数
5 public mainpage()
6 {
7 initializecomponent();
8 }
9
10 private void tblnavigationsecondpage_manipulationstarted(object sender, manipulationstartedeventargs e)
11 {
12 //contentpanel背景颜色不为默认值时(brush类null)
13 if (this.contentpanel.background is solidcolorbrush)
14 {
15 (application.current as app).sharecolor = (contentpanel.background as solidcolorbrush).color;
16
17 this.navigationservice.navigate(new uri("/secondpage.xaml", urikind.relative));
18 e.complete();
19 e.handled = true;
20 }
21 }
22
23 protected override void onmanipulationstarted(manipulationstartedeventargs e)
24 {
25 this.contentpanel.background = new solidcolorbrush(color.fromargb
26 (255, (byte)ran.next(255), (byte)ran.next(255), (byte)ran.next(255)));
27
28 base.onmanipulationstarted(e);
29 }
30
31 //当页面变为框架(frame)中的活动页面时调用。
32 protected override void onnavigatedto(system.windows.navigation.navigationeventargs e)
33 {
34 color? sharecolor = (application.current as app).sharecolor;
35 if (sharecolor != null)
36 {
37 this.contentpanel.background = new solidcolorbrush(sharecolor.value);
38 }
39
40 base.onnavigatedto(e);
41 }
42 }
43
接着是我们的第二个页面secondpage.xmal的前端代码:
1 <!--contentpanel - 在此处放置其他内容-->
2 <grid x:name="contentpanel" grid.row="1" margin="12,0,12,0">
3 <textblock padding="0 34" horizontalalignment="center" name="tblnavigationmainpage" text="goback to mainpage" fontsize="32" verticalalignment="center" manipulationstarted="tblnavigationmainpage_manipulationstarted"
4 />
5 </grid>
secondpage.xmal.cs后台程序处理代码:
1 public partial class secondpage : phoneapplicationpage
2 {
3 random ran = new random();
4 public secondpage()
5 {
6 initializecomponent();
7 }
8
9 private void tblnavigationmainpage_manipulationstarted(object sender, manipulationstartedeventargs e)
10 {
11 //contentpanel背景颜色不为默认值时(brush类null)
12 if (this.contentpanel.background is solidcolorbrush)
13 {
14 (application.current as app).sharecolor = (this.contentpanel.background as solidcolorbrush).color;
15 }
16 this.navigationservice.goback();
17 }
18
19 protected override void onmanipulationstarted(manipulationstartedeventargs e)
20 {
21 this.contentpanel.background = new solidcolorbrush(color.fromargb
22 (255, (byte)ran.next(255), (byte)ran.next(255), (byte)ran.next(255)));
23 }
24
25 //当页面变为框架(frame)中的活动页面时调用。
26 protected override void onnavigatedto(system.windows.navigation.navigationeventargs e)
27 {
28 color? sharedcolor = (application.current as app).sharecolor;
29 if (sharedcolor != null)
30 {
31 this.contentpanel.background = new solidcolorbrush(sharedcolor.value);
32 }
33
34 base.onnavigatedto(e);
35 }
36 }
编译运行程序,我们可以发现当前显示页面都把自己contentpanel背景色保存到公共属性sharedcolor中,通过时当前显示页面的contentpanel元素的背景色变为上一个显示页面的背景色。下面是程序运行的效果
这个示例中我们需要注意的是:onnavigatedto方法(当页面变为框架(frame)活动页面时调用),这个方法的navigationeventargs类型参数有两个属性:
•uri类型的uri(将要呈现页面的uri)
•object类型的content(将要呈现页面的实例)
在这个实例中我们主要通过这个类型的参数的属性来设置源页面和目标页面的contentpanel元素的背景色属性。page类除了onnavigatedto()方法外,还包括:
•
•
• onfragmentnavigation方法 —— 在导航到页面上的片段时调用。
• onnavigatedfrom方法 —— 当页面不再是框架中的活动页面时调用。
• onnavigatingfrom方法 —— 在页面即将不再是框架中的活动页面时调用。
我们可以通过利用这些在不同的周期运行的page类方法来做更多的事情,比如我们利用onnavigatedfrom方法的特性在源页面导航到目标页面时设置其属性,或调用其方法。下面我们通过一个简单的示例来实现这个目标,该示例的mainpage和secondpage页面的的前端代码和前面的示例相同,这里只给出两个页面的后台代码:
mainpage.xaml.cs:
1 public partial class mainpage : phoneapplicationpage
2 {
3 // 构造函数
4 public mainpage()
5 {
6 initializecomponent();
7 }
8
9 public color? returnedcolor { get; set; }//为mainpage类增加的属性,用于存放需要显示的背景色
10 private void tblnavigationsecondpage_manipulationstarted(object sender, manipulationstartedeventargs e)
11 {
12 this.navigationservice.navigate(new uri("/secondpage.xaml", urikind.relative));
13
14 e.complete();
15 e.handled = true;
16 }
17
18 //当页面变为框架(frame)中的活动页面时调用。
19 protected override void onnavigatedto(navigationeventargs e)
20 {
21 if (returnedcolor != null)
22 {
23 this.contentpanel.background = new solidcolorbrush(returnedcolor.value);
24 }
25
26 base.onnavigatedto(e);
27 }
28 }
secondpage.xaml.cs:
1 public partial class secondpage : phoneapplicationpage
2 {
3 random ran = new random();
4 public secondpage()
5 {
6 initializecomponent();
7 }
8
9 private void tblnavigationmainpage_manipulationstarted(object sender, manipulationstartedeventargs e)
10 {
11 this.navigationservice.goback();
12
13 e.complete();
14 e.handled = true;
15 }
16
17 protected override void onmanipulationstarted(manipulationstartedeventargs e)
18 {
19 this.contentpanel.background = new solidcolorbrush(color.fromargb
20 (255, (byte)ran.next(255), (byte)ran.next(255), (byte)ran.next(255)));
21
22 base.onmanipulationstarted(e);
23 }
24
25 //当页面不再是框架(frame)中的活动页面时调用。
26 protected override void onnavigatedfrom(system.windows.navigation.navigationeventargs e)
27 {
28 color clr = (this.contentpanel.background as solidcolorbrush).color;
29
30 if (e.content is mainpage)
31 {
32 //设置mainpage页面的背景色
33 (e.content as mainpage).returnedcolor = clr;
34 }
35 base.onnavigatedfrom(e);
36 }
37 }
在这个示例中:
mainpage页面没有改变颜色的方法,当导航到secondpage页面时,触摸该页面的textblock控件之外的屏幕改变contentpanel背景色,随后点击textblock控件,调用goback方法返回到上一页面也就是mainpage中,同时利用onnavigatedfrom方法,把mainpage的contentpanel控件的背景色设置和自身一个颜色。
2.通过phoneapplicationservice类来保存共享数据
使用的phoneapplicationservice类在app.xaml中定义:
1 <application.applicationlifetimeobjects>
2 <!--处理应用程序的生存期事件所需的对象-->
3 <shell:phoneapplicationservice
4 launching="application_launching" closing="application_closing"
5 activated="application_activated" deactivated="application_deactivated"/>
6 </application.applicationlifetimeobjects>
需要引用:microsoft.phone.shell命名空间,phoneapplicationservice类有一个state属性(类型为:idictionary<string,object>)可以用来作为保存和恢复数据的字典,所有保存在state字典中的对象都必须是可序列化的(对象可以转换为xml,并可以从xml中反序列化为对象)。并且需要注意的是,保存的数据只有在应用程序运行的时候才会保留(临时数据,transient),并不适合必须在多次执行期间保存的应用程序的配置信息,这里我们可以考虑使用独立存储(将在后面的笔记中介绍它)。
下面我们通过一个简单的示例来学习使用phoneapplicationservice类保存共享数据的使用方法。这个示例的前端显示xaml代码和前面的示例一致,这里就不在给出,下面直接给出后台处理程序代码:
mainpage.xaml.cs:
1 public partial class mainpage : phoneapplicationpage
2 {
3 // 构造函数
4 public mainpage()
5 {
6 initializecomponent();
7 }
8 random ran = new random();
9
10 private void tblnavigationsecondpage_manipulationstarted(object sender, manipulationstartedeventargs e)
11 {
12 this.navigationservice.navigate(new uri("/secondpage.xaml", urikind.relative));
13
14 e.complete();
15 e.handled = true;
16 }
17
18 //当页面变为框架(frame)活动页面时调用
19 protected override void onnavigatedto(system.windows.navigation.navigationeventargs e)
20 {
21 //取回颜色
22 if (phoneapplicationservice.current.state.containskey("color"))
23 {
24 color clr = (color)phoneapplicationservice.current.state["color"];
25 this.contentpanel.background = new solidcolorbrush(clr);
26 }
27 base.onnavigatedto(e);
28 }
29 }
secondpage.xaml.cs:
1 public partial class secondpage : phoneapplicationpage
2 {
3 public secondpage()
4 {
5 initializecomponent();
6 }
7
8 random ran = new random();
9
10 //随机改变背景色
11 protected override void onmanipulationstarted(manipulationstartedeventargs e)
12 {
13 this.contentpanel.background = new solidcolorbrush(color.fromargb
14 (255, (byte)ran.next(255), (byte)ran.next(255), (byte)ran.next(255)));
15
16 base.onmanipulationstarted(e);
17 }
18
19 //当页面不再是框架中的活动页面时调用
20 protected override void onnavigatedfrom(system.windows.navigation.navigationeventargs e)
21 {
22 //如果contentpanel背景色不为默认值(null,brush)
23 if (this.contentpanel.background is solidcolorbrush)
24 {
25 color clr = (this.contentpanel.background as solidcolorbrush).color;
26
27 //保存颜色
28 phoneapplicationservice.current.state["color"] = clr;
29 }
30
31 base.onnavigatedfrom(e);
32 }
33
34 private void tblnavigationmainpage_manipulationstarted(object sender, manipulationstartedeventargs e)
35 {
36 this.navigationservice.goback();
37
38 e.complete();
39 e.handled = true;
40 }
41
42 }
编译运行程序,先导航到secondpage页面,改变背景色,然后在导航到mainpage页面中(背景色改变),下面是实际效果:
摘自 :晴天猪の博客