对于页面传值这个问题,其实在很多地方都有用到,无论是安卓,iOS,Windows客户端还是网页。今天很多朋友问我,Windows 10下怎么页面之间传递值。其实有很多方法。
第一种,就是设置全局变量,就是在App.cs里面设置一个对象的引用,这个做有一个好处。哈哈,先卖一个关子,一会说。
第二种就是用系统自带的传递方法,今天着重唠叨一下这个方法,在Windows 10UWP中,有这么一段代码。
Frame root = Window.Current.Contentas Frame;root.Navigate(typeof(BlankPage1));
1
2
相信大家都能看懂吧,如果是学习wp8.1,都可以看懂的,这个就是页面导航,从当前页面导航到BlankPage1这个页面去,可是怎么传值呢?其实传值就在这里。可以右键转到定义,转到定义的Navigate方法。
可以看到,这个重载了三个,我就直接拿第三个参数最多的来说了,第一个参数,就是我们可以通过typeof运算符获得页面的类型,其实就要我们要导航到那个页面去,第二个参数是Object类型的,它就是我们要传递的参数,为啥是Object类型呢?我要传递string啊,或者int,或者我自定义的类型,如果学的好的,就知道,C#所有类型默认的继承了Object(拆箱装箱也能用到这点知识,说的过了哈哈),所以这个类型参数就可以传递任意的了,而第三个参数,大家可以看到是NavigationTransitionInfo类型的,其实有兴趣研究下,在这个空间下,有很多个类,那些类就是启动第二个页面的效果,我说一个大家肯定知道,经典的Windows phone8.1旋转门导航。
下来我们来研究怎么用,并且如果在第二个页面接受这个参数,我的做法是在第一个页面,输入参数,然后点击按钮,导航到第二个页面,并且第二个页面弹出提示框,显示第一个页面传递过来的参数,并且判断传递过来的是一个引用还是深度拷贝的对象。
首先,我们建立这样的一个类用来测试。
publicclassInfo {//为什么我这里要写这个类,麻烦呢,//因为要研究对于对象,传递过去的是浅拷贝还是深度拷贝publicstringMsg {set;get; } }
1
2
3
4
5
6
下来在App.cs里面这样定义一个静态变量
publicstaticInfo info =null;
1
这是我们第一个页面的界面,
很简单。然后对应的Button点击事件里面这样写
privatevoidbutton_Click(objectsender, RoutedEventArgs e) { Info info =newInfo(); info.Msg = textBox.Text;//这里将刚才定义在全局的变量指向当前这个对象App.info = info;//输出HasCodeDebug.WriteLine(info.GetHashCode()); Frame root = Window.Current.ContentasFrame;//这里参数自动装箱root.Navigate(typeof(BlankPage1),info); }
1
2
3
4
5
6
7
8
9
10
11
12
在第二个页面,我们怎么接受数据呢?
//////这里重写OnNavigatedTo方法//////protectedoverrideasyncvoidOnNavigatedTo(NavigationEventArgs e) {base.OnNavigatedTo(e);//这个e.Parameter是获取传递过来的参数,其实大家应该再次之前判断这个参数是否为null的,我偷懒了Info info = (Info)e.Parameter; Debug.WriteLine(info.GetHashCode()); MessageDialog msg =newMessageDialog(info.Msg +" 比较结果是两者相等?"+ info.Equals(App.info));awaitmsg.ShowAsync(); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
接下来,我们看看运行效果图,并且要看看在第一个页面用App.info指向的那个对象是否跟在第二个页面的对象相等,并且查看他们的HasCode
是否相等。
这里试运行起来的第一个页面,我输入参数之后,开始点击
导航进入的第二个页面
可以看到,比较结果是相等的。
下来再看看HasCode是否相等?
现在我们可以下结论了,对于页面传值,如果是对象的话,其实就是传递一个引用过去,而他的真实对象只有一个,没有进行深度拷贝。对于值类型?希望大家可以继续研究,我就不说了
刚才说到用全局变量有一个好处,其实是我开发时候遇到的,当初在页面传值,我传递一个对象过去(这里应该不能这样说,应该是引用),这个对象引用的那段内存,里面存的很多东西,有图书资源,文章。然后我点击Button传值,结果给卡了,体验太差了,大约是两秒才传递过去的。我当初以为是深度拷贝过去的,就用全局变量替换页面传值了(这个要考虑内存优化,比如你不用时候,应该把他释放,不然全局一直引用,GC永远释放不了,除非关程序)。最后自己研究了下,对于对象传值,应该是引用啊,不应该这么慢的?这个问题我到现在都没想通为什么?希望有大神能帮忙解释。