Windows Phone编程中页面间传值方法
wp开发过程中有时会遇到页面间转值的需求,如果定义两个页面,一个是初始页面source page,另外一个是跳转的页面destination page,简单地分析主要有两个方面的要求:: r2 q. h% e" f4 f4 i2 t! m
• 首先是在source page跳转到destination page时给destination page页面传值的实现;
• 然后是当在destination page中调用goback函数回到source page时如何在source page传值;) c9 m. g: `: |; x3 \; r9 f7 w
) z3 a' x* g3 y; x) t
第一点本身提供了基本的实现方法,新建一个项目datapassingdemo,然后新建一个页面secondpage.xaml,我们需要实现就是从mainpage中跳转到secondpage中去,并传递参数让secendpage捕捉。首先在mainpage中增加一个textblock并且增加事件处理函数:2 o* v; x i3 x _
view sourceprint?: b3 y5 ^4 m j9 k; n
<grid x:name="contentpanel" grid.row="1" margin="12,0,12,0">
<textblock text="navigate to 2nd page with data" horizontalalignment="center"
verticalalignment="center" padding="0 34" * f/ v" t% g8 r( o+ w$ k
manipulationstarted="textblock_manipulationstarted"/>
</grid># q2 z& x( @. g t2 |
在mainpage的后台代码中,实现textblock_manipulationstarted方法如下:4 ]7 z) j8 b- p. w3 w! f
view sourceprint?
private void textblock_manipulationstarted(object sender, manipulationstartedeventargs args) ) b, q4 u" t" `8 ] w( h
{
string destination = "/secondpage.xaml?parameter1=hello¶meter2=world"; " b( k6 }+ w3 \" c/ l r. a: l. q
this.navigationservice.navigate(new uri(destination, urikind.relative)); 9 ?7 ^$ a- s a% v
args.complete(); * o' t$ i) s3 d
args.handled = true; 0 j, k8 g$ }0 b; r% \$ ~* a1 |+ r, e
}% b& u4 o- q+ g1 p
可以看到上面的那个destination是不是很像网页间传递参数的形式呢?同理在secondpage中增加一个textblock,并给该textblock的manipulationstarted事件中增加goback()事件。同时,为了捕捉mainpage传递过来的参数,在secondpage的后台代码中实现下面的代码:
view sourceprint?
protected override void onnavigatedto(system.windows.navigation.navigationeventargs args)
{
idictionary<string, string> parameters = this.navigationcontext.querystring; / u1 \' j" w' `6 m9 i
if (parameters.containskey("parameter1")) % ~( h4 i8 l7 x' ]
{ ' t, ? o' ^0 t
string parameter1 = parameters["parameter1"];
string parameter2 = parameters["parameter2"]; ' n/ v% g6 k+ \
txtblk.text = string.format("parameter1 is:{0} and parameter2 is:{1}", parameter1, parameter2); ) f8 y- v, v# c: i3 @ v
} " \4 q0 h, u* h7 g; t
base.onnavigatedto(args); 2 f" x; y. u* t% ^% v; f
}
通过重载onnavigatedto函数实现获取传递过来的参数并在其中的一个textblock中显示出来。
[local]1[/loca所以实现第一个传值要求的方法很简单,只要通过给navigationservice的目标页面地址附带上参数再由目标页面获取参数即可,而我们要注意的地方是,由于移动设备设计的便捷性要求,我们应该避免那些很复杂的传递参数的设计,并且,在设计时要注意windows phone设计中的墓碑机制,才能设计出合理高效的wp应用。8 e' _) q! z6 b; f# w+ m8 l6 w
7 r+ i% l( x' [: m, s3 o, m
接着我们来考虑第二个问题,如何在页面间共享,传递数据。我们可以考虑到如果有一个是中间的“容器”可以存放一些公共的数据的话那且不是可以实现这个要求了吗?这时如果熟悉silverlight设计的话头脑里就会呈现出app这个类,由于所有的页面都可以访问到app这个类,所以我们可以把一些准备共享的数据放在app这个类中定义。就在上面那个例子中,我们在app类中增加一个公共变量:
view sourceprint?
public string sharedstring { set; get; }
7 l7 c) x- c) w, c6 g4 _
这时如果想在mainpage中给secondpage传递参数的话则需要先访问那个共享数据,这时的mainpage中的后台代码如下:
view sourceprint?5 t) m. \& ?2 h
private void textblock_manipulationstarted(object sender, manipulationstartedeventargs args) $ |8 m* h2 p) o/ p8 a5 t, c* [
{
(application.current as app).sharedstring = "hello world";
this.navigationservice.navigate(new uri("/secondpage.xaml", urikind.relative)); : s/ q1 q" v4 v; k3 {/ t
args.complete(); ; h8 k. r1 n& t8 z/ o
}
即在访问secondpage前先修改那个共享数据的值,然后在secondpage的onnavigatedto事件中代码修改如下:
view sourceprint?
protected override void onnavigatedto(system.windows.navigation.navigationeventargs args) 0 m# i6 s) f3 u. _/ d t: t# u; @
{ ! ^2 v% h8 b3 w. i' k# w+ o+ h
string sharedstring = (application.current as app).sharedstring; # _, i+ l1 r6 r8 q
txtblk.text = sharedstring;
base.onnavigatedto(args);
}0 u3 k7 x0 u8 }' w7 h% g
% i5 w+ y3 q' r! ~4 k8 @
同理,如果想通过secondpage向mainpage传递数据的话,只要在调用goback函数前修改那个共享数据的值再由mainpage中的onnavigatedto函数来获取到相对应的数据即可。5 r+ a0 n) k5 f
% k3 z8 f' a9 j2 y) w
到这里我们已经基本可以实现上面的两个要求了,但第二种方法只是一种取巧的方法,在逻辑及实现上都有不合理的地方,我们应该走思考另外一种更为合理与通用的实现方式,那就是onnavigatedfrom这个函数了。大家可能会想,from不是很明显吗,我们就是通过from的原页面跳到目标页面的,那么这个from有何用处呢。其实它的用处挺大的,例如,通过这个函数我们可以很好的解决上面提到的问题。
2 k% u( n* s- g- s5 v0 s
最后用一个例子去说明这种方式的具体实现,我们定义两个页面,和之前的类似,这次我们通过secondpage返回的值去定义mainpage页面的颜色,mainpage的后台代码定义如下:! z4 x" q( n- n% i4 t
view sourceprint?$ @, g, l) d4 o$ q$ h8 k
public partial class mainpage : phoneapplicationpage
{ b n& s' ^; _6 j8 l
public mainpage() + b! _1 m a' r7 n6 {5 r7 `$ d
{
initializecomponent(); v, f" i: m: n3 k" q
} - t8 \* p/ o' e* f4 z, g8 b
public color? returnedcolor { set; get; }
# w7 u/ v. \" l- b7 r. v
private void textblock_manipulationstarted(object sender, manipulationstartedeventargs args)
{
this.navigationservice.navigate(new uri("/secondpage.xaml", urikind.relative)); - x {$ o5 s0 a5 |& ]: o, }
args.complete();
args.handled = true; ; c" r5 y1 g% }. q/ g/ h6 a: x# ?
} % v( c' p- l6 x$ l- ?
}7 ^* v- _ v, i
[+ f m" \ {
这里定义为color?,因为返回的值有可能是非颜色的。而secondpage中的后台代码定义如下:
show sourceview sourceprint?& e8 c4 b" {( u
namespace datapassingdemo
{
public partial class secondpage : phoneapplicationpage 8 @$ u1 k2 i& c! l0 s! y; w
{ 3 u- t- c9 y! r
public secondpage() + v8 c. m f. s! e& g/ m, h
{ # v5 q; w( q7 j2 @
initializecomponent(); ; k, u b5 h4 q7 r( l/ b, t
} 6 w2 v) `+ a, f
random rand = new random();
private void textblock_manipulationstarted(object sender, manipulationstartedeventargs args)
{ ( q3 o8 z. p3 l. a
this.navigationservice.goback();
args.complete();
args.handled = true;
}
* j2 v; a. t; \2 y) u9 `" f
protected override void onnavigatedfrom(system.windows.navigation.navigationeventargs e) ' s0 n0 r, s( e; a$ q' s8 |
{
if (contentpanel.background is solidcolorbrush) ) p$ }/ f5 b# ?! a7 [1 j
{
color clr = (contentpanel.background as solidcolorbrush).color;
if (e.content is mainpage)
(e.content as mainpage).returnedcolor = clr; . r2 r% u* i2 p+ c" g( e
}
base.onnavigatedfrom(e); 4 ]2 `1 r2 ?4 e+ o
} ! @9 u! {5 _2 u" d( {' z
8 s) u4 u m( a' e+ p
protected override void onmanipulationstarted(manipulationstartedeventargs args) ) z. t- m) g3 a2 a' a) \+ y
{
contentpanel.background = new solidcolorbrush( / b( \! h4 n; m, z4 p7 l+ w5 o; g
color.fromargb(255, (byte)rand.next(255), * k! u$ ]- a" m, w
(byte)rand.next(255),
(byte)rand.next(255))); 5 o1 j) r% u. h; c
base.onmanipulationstarted(args); 4 s' p& _' r, k, r2 ^7 \5 t
}
} q0 k; n$ w9 o+ w% y4 f
}/ ]5 l; g9 e, r
4 g, n, o- {1 r3 f. d" k* j
我们通过获得一个随机数值组合而成的颜色设置为secondpage的背景颜色,然后通过onnavigatedfrom设置returnedcolor为当前背景颜色,所以为了获取secondpage返回的returnedcolor,在mainpage的后台代码中还需要重载onnavigatedto方法响应这个onnavigatedfrom:
view sourceprint?
protected override void onnavigatedto(system.windows.navigation.navigationeventargs args)
{
if (returnedcolor != null)
contentpanel.background =
new solidcolorbrush(returnedcolor.value);
base.onnavigatedto(args); ( f& j8 ~ h9 s& \9 |
}
通过onnavigatedfrom与onnavigatedto,我们就完成了数据的传递过程。l]
摘自 xiechengfa的专栏