上一个项目实现的功能是如何从源页面传递数据到目标页面,但是,当回到源页面时,如何才能返回数据,实现数据共享呢?这个就是这一篇文章要解决的问题,而且解决这个问题有几个方案,总结如下。这里共享的数据是页面背景颜色。
方案一:使用App类来存储共享数据
MainPage.xaml XAML代码:
MainPage.xaml C#代码:
namespace SilverlightShareData1 { public partial class MainPage : PhoneApplicationPage { Random rand = new Random(); // 构造函数 public MainPage() { InitializeComponent(); } private void TextBlock_ManipulationStarted(object sender, ManipulationStartedEventArgs e)//处理Manipulation事件 { //todo:将MainPage页面背景保存到App类中声明的公共属性中,然后导航到目标页面 if (this.ContentPanel.Background is SolidColorBrush) { (Application.Current as App).SharedColor = (this.ContentPanel.Background as SolidColorBrush).Color;//将当前背景保存到App类的公共属性中,Application静态属性Current返回当前Application对象 } this.NavigationService.Navigate(new Uri("/SecondPage.xaml",UriKind.Relative));//导航到目标页面 e.Complete(); e.Handled = true; } protected override void OnManipulationStarted(ManipulationStartedEventArgs e)//重写基类Control(MainPage从它派生)的虚方法 { //todo:实现点击屏幕随机更换背景颜色 this.ContentPanel.Background = new SolidColorBrush(Color.FromArgb(255,(byte)rand.Next(256),(byte)rand.Next(256),(byte)rand.Next(256)));//随机更换背景颜色 base.OnManipulationStarted(e);//基类访问表达式调用基类虚方法 } protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)//重写基类Page的虚方法(当页面成为框架的活动页面时发生) { //todo:从App类的公共属性中获取背景颜色值,然后初始化页面背景 Color? SharedColor = (Application.Current as App).SharedColor;//访问App类中的SharedColor属性 if (SharedColor != null)//注意一定要先判断是否为空,因为SharedColor是可空类型 { this.ContentPanel.Background = new SolidColorBrush(SharedColor.Value); } base.OnNavigatedTo(e); } } }
SecondPage.xaml XAML代码:
SecondPage.xaml C#代码:
namespace SilverlightShareData1 { public partial class SecondPage : PhoneApplicationPage { Random rand = new Random(); public SecondPage() { InitializeComponent(); } private void TextBlock_ManipulationStarted(object sender, ManipulationStartedEventArgs e)//处理Manipulation事件(当单击TextBlock的有效区域时发生) { //todo:返回到源页面 this.NavigationService.GoBack(); e.Complete(); e.Handled = true; } protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)//重写基类Page的虚方法(当页面成为框架的活动页面时发生) { //todo:访问App类中公共属性,然后用该属性值初始化页面背景颜色 Color? SharedColor = (Application.Current as App).SharedColor;//访问App类中的SharedColor属性 if (SharedColor != null)//注意一定要先判断是否为空,因为SharedColor是可空类型 { this.ContentPanel.Background = new SolidColorBrush(SharedColor.Value); } base.OnNavigatedTo(e); } protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)//重写基类Page的虚方法(当页面不再是框架的活动页面时发生) { //todo: 当页面离开时将当前背景颜色保存到App类中的公共属性中,以便源页面在加载时获取该属性的值并初始化页面背景 if (this.ContentPanel.Background is SolidColorBrush) { (Application.Current as App).SharedColor = (this.ContentPanel.Background as SolidColorBrush).Color; } base.OnNavigatedFrom(e); } protected override void OnManipulationStarted(ManipulationStartedEventArgs e)//重写基类Control(MainPage从它派生)的虚方法(当单击屏幕时发生) { //todo:实现点击屏幕随机更换背景颜色 this.ContentPanel.Background = new SolidColorBrush(Color.FromArgb(255, (byte)rand.Next(256), (byte)rand.Next(256), (byte)rand.Next(256)));//随机更换背景颜色 base.OnManipulationStarted(e);//基类访问表达式调用基类虚方法 } } }
App.xaml C#代码:
//用于在页面间共享数据的公共属性 public Color? SharedColor { set; get; }//C#3.0自动属性,Color?表示可空类型
效果如图:
导航到目标页面时 返回到源页面时
注意:1,程序中所有页面都可以访问到从Application派生的App类。
2,访问Application类的静态属性Current可以返回当前应用程序的Application对象。 3,注意Page类的OnNavigatedTo方法和OnNavigatedFrom方法的区别。OnNavigatedTo是当页面成为框架的活动页面时调用,而OnNavigatedFrom是当页面不再(离开)是框架的活动页面时调用。方案二:使用页面中的公共属性来存储共享数据
这个方案的实现原理与方案一差不多,只不过这里将共享数据保存在了页面中,而不像上例中保存在App这样的第三方类中。
MainPage.xaml XAML代码:
MainPage.xaml C#代码:
namespace SilverlightShareData2 { public partial class MainPage : PhoneApplicationPage { Random rand = new Random(); // 构造函数 public MainPage() { InitializeComponent(); } //公共属性,用来存储共享数据 public Color? ReturnedColor { set; get; } private void TextBlock_ManipulationStarted(object sender, ManipulationStartedEventArgs e)//处理Manipulation事件(当单击TextBlock是发生) { //todo:导航到目标页面 this.NavigationService.Navigate(new Uri("/SecondPage.xaml", UriKind.Relative));//导航到目标页面 e.Complete(); e.Handled = true; } protected override void OnManipulationStarted(ManipulationStartedEventArgs e)//重写基类Control(MainPage从它派生)的虚方法(当单击屏幕时发生) { //todo:实现点击屏幕随机更换背景颜色 this.ContentPanel.Background = new SolidColorBrush(Color.FromArgb(255, (byte)rand.Next(256), (byte)rand.Next(256), (byte)rand.Next(256)));//随机更换背景颜色 base.OnManipulationStarted(e);//基类访问表达式调用基类虚方法 } protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)//重写基类Page的虚方法(当页面不再成为框架的活动页面时调用) { //todo:保存当前页面背景到目标页面(在这里是SecondPage)的公共属性中 if (this.ContentPanel.Background is SolidColorBrush) { Color clr = (this.ContentPanel.Background as SolidColorBrush).Color; if (e.Content is SecondPage) { (e.Content as SecondPage).ReturnedSecondColor = clr; } } base.OnNavigatedFrom(e); } protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)//重写基类Page的虚方法(当页面成为框架的活动页面时调用) { //todo:获取公共属性的值并初始化页面背景 if (ReturnedColor != null) { this.ContentPanel.Background = new SolidColorBrush(ReturnedColor.Value); } base.OnNavigatedTo(e); } } }
SecondPage.xaml XAML代码:
SecondPage.xaml C#代码:
namespace SilverlightShareData2 { public partial class SecondPage : PhoneApplicationPage { Random rand = new Random(); public SecondPage() { InitializeComponent(); } //公共属性,用来存储共享数据 public Color? ReturnedSecondColor { set; get; } private void TextBlock_ManipulationStarted(object sender, ManipulationStartedEventArgs e)//处理Manipulation事件(当单击TextBlock时发生) { //todo:返回到源页面 this.NavigationService.GoBack(); e.Complete(); e.Handled = true; } protected override void OnManipulationStarted(ManipulationStartedEventArgs e)//重写基类Control(MainPage从它派生)的虚方法(当单击屏幕时发生) { //todo:实现点击屏幕随机更换背景颜色 this.ContentPanel.Background = new SolidColorBrush(Color.FromArgb(255, (byte)rand.Next(256), (byte)rand.Next(256), (byte)rand.Next(256)));//随机更换背景颜色 base.OnManipulationStarted(e);//基类访问表达式调用基类虚方法 } protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)//重写基类Page的虚方法(当页面成为框架的活动页面时调用) { //todo:获取公共属性的值并初始化页面背景 if (ReturnedSecondColor != null) { this.ContentPanel.Background = new SolidColorBrush(ReturnedSecondColor.Value); } base.OnNavigatedTo(e); } protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)//重写基类Page的虚方法(当页面不再成为框架的活动页面时调用) { //todo:保存当前页面背景到源页面(在这里是MainPage)的公共属性中 if (this.ContentPanel.Background is SolidColorBrush) { Color clr = (this.ContentPanel.Background as SolidColorBrush).Color; if (e.Content is MainPage) { (e.Content as MainPage).ReturnedColor = clr; } } base.OnNavigatedFrom(e); } } }
效果与方案一的一样。
注意:1,OnNavigatedFrom和OnNavigatedTo方法都有一个类型为NavigationEventArgs的事件参数,NavigationEventArgs类型定义了两个属性:Uri类型的Uri和Object类型的Content,它们都标识了要导航到的页面。记住,Content属性是获取目标页面对象的最方便的方式。方案三:使用PhoneApplicationService对象的State属性
MainPage.xaml XAML代码:
MainPage.xaml C#代码:
namespace SilverlightRetainData { public partial class MainPage : PhoneApplicationPage { // 构造函数 public MainPage() { InitializeComponent(); } //公共属性保存目标页面的背景颜色 public Color? ReturnedColor { get; set; } private void TextBlock_ManipulationStarted(object sender, ManipulationStartedEventArgs e)//处理Manipulation事件(当单击TextBlock时发生) { //todo:导航到目标页面 this.NavigationService.Navigate(new Uri("/SecondPage.xaml",UriKind.Relative)); e.Complete(); e.Handled = true; } protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)//重写基类Page的虚方法(当页面成为活动页面时调用) { //todo:获取公共属性的值并初始化页面背景 if (ReturnedColor != null) { //Color clr = ReturnedColor.Value; this.ContentPanel.Background = new SolidColorBrush(ReturnedColor.Value); } base.OnNavigatedTo(e); } } }
SecondPage.xaml XAML代码:
SecondPage.xaml C#代码:
namespace SilverlightRetainData { public partial class SecondPage : PhoneApplicationPage { Random rand = new Random(); public SecondPage() { InitializeComponent(); } private void TextBlock_ManipulationStarted(object sender, ManipulationStartedEventArgs e)//处理Manipulation事件(当单击TextBlock时发生) { //todo:返回到源页面 this.NavigationService.GoBack(); e.Complete(); e.Handled = true; } protected override void OnManipulationStarted(ManipulationStartedEventArgs e)//重写基类Control(MainPage从它派生)的虚方法(当单击屏幕时发生) { //todo:随机改变背景颜色 this.ContentPanel.Background = new SolidColorBrush(Color.FromArgb(255,(byte)rand.Next(256),(byte)rand.Next(256),(byte)rand.Next(256))); base.OnManipulationStarted(e); } protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)//重写基类Page(MainPage从它派生)的虚方法(当页面离开时调用) { //todo:将当前页面背景颜色保存到MainPage中的公共属性ReturnedColor中,然后将当前页面背景颜色保存到PhoneApplicationService对象的State字典中,以便恢复时取回颜色 if (this.ContentPanel.Background is SolidColorBrush) { Color clr=(this.ContentPanel.Background as SolidColorBrush).Color; if (e.Content is MainPage) { (e.Content as MainPage).ReturnedColor = clr; } //保存颜色 PhoneApplicationService.Current.State["Color"] = clr; } base.OnNavigatedFrom(e); } protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)//重写基类Page(MainPage从它派生)的虚方法(当页面成为活动页面时调用) { //todo:取回在PhoneApplicationService对象State字典中保存的颜色并初始化页面 if (PhoneApplicationService.Current.State.ContainsKey("Color")) { Color clr=(Color)PhoneApplicationService.Current.State["Color"]; this.ContentPanel.Background = new SolidColorBrush(clr); } base.OnNavigatedTo(e); } } }
注意:每当在主页面中通过按下Back按键来退出程序,State字典将会从PhoneApplicationService中全部清空。该State字典只适用于存储程序同一次运行过程中的临时数据。如果需要在程序多次执行过程之间保存数据,需要使用独立存储。下一篇将会总结到。