上一个项目实现的功能是如何从源页面传递数据到目标页面,但是,当回到源页面时,如何才能返回数据,实现数据共享呢?这个就是这一篇文章要解决的问题,而且解决这个问题有几个方案,总结如下。这里共享的数据是页面背景颜色。

方案一:使用App类来存储共享数据

  MainPage.xaml XAML代码:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Text="Navigate to Second Page!"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Padding="0,34"
ManipulationStarted="TextBlock_ManipulationStarted"/>
</Grid>

  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代码:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Text="Go back to Main Page!"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Padding="0,34"
ManipulationStarted="TextBlock_ManipulationStarted"/>
</Grid>

  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代码:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Text="Navigate to Second Page!"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Padding="0,34"
ManipulationStarted="TextBlock_ManipulationStarted"/>
</Grid>

  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代码:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Text="Go back to Main Page!"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Padding="0,34"
ManipulationStarted="TextBlock_ManipulationStarted"/>
</Grid>

  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代码:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Text="Navigate to Second Page!"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Padding="0,34"
ManipulationStarted="TextBlock_ManipulationStarted"/>
</Grid>

  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代码:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Text="Go back to Main Page!"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Padding="0,34"
ManipulationStarted="TextBlock_ManipulationStarted"/>
</Grid>

  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字典只适用于存储程序同一次运行过程中的临时数据。如果需要在程序多次执行过程之间保存数据,需要使用独立存储。下一篇将会总结到。 

posted on 2012-02-15 21:25  永远的麦子  阅读(2373)  评论(9编辑  收藏  举报