Windows Phone 7 编成之- 6.3 页面之间数据共享和传递

MFC程序一样,在winPhone7程序中,有一个App类。它继承于Application. 程序中的所有类都可以同过静态的Application.Current属性方便的访问这个类的实例。这就意味着你可以使用App类存储你想在程序页面间共享的任何数据。

1.使用全局App类存储共享数据

SilverlightShareData项目中,我在App类中定义了一个公共属性

Silverlight Project: SilverlightShareData File: App.xaml.cs (excerpt)

public partial class App : Application {

// public property for sharing data among pages

public Color? SharedColor { set; get; }

}

我定义一个可为Null类型的Color类型属性。这是出于考虑SolidColorBrushContentPanelBackground属性中还没有被设置的情况下。在那些情况下,Background 属性是null,而且不应该有Color存储在这个属性中。如果属性只是一个Color类型,那么这个Color属性的值将会被默认存储;这个Color值将是一个透明的黑色,那就错了。如果用户选择亮一点的颜色方案,即便是不透明的黑色,那也是错误的。

多数情况下,程序保持不变,除非当你触摸MainPage中的TextBlock,在导航到SecondPage之前,事件处理函数首先尝试在新的App类属性中保存一个颜色值:

Silverlight Project: SilverlightShareData File: MainPage.xaml.cs (excerpt)

void OnTextBlockManipulationStarted(object sender, ManipulationStartedEventArgs args)

{

if (ContentPanel.Background is SolidColorBrush)

(Application.Current as App).SharedColor = (ContentPanel.Background as SolidColorBrush).Color;

this.NavigationService.Navigate(new Uri("/SecondPage.xaml", UriKind.Relative));

args.Complete();

args.Handled = true;

}

重载SecondPage中的OnNavigatedTo 来存取这个属性:

Silverlight Project: SilverlightShareData File: SecondPage.xaml.cs (excerpt)

protected override void OnNavigatedTo(NavigationEventArgs args)

{

Color? sharedColor = (Application.Current as App).SharedColor;

if (sharedColor != null)

ContentPanel.Background = new SolidColorBrush(sharedColor.Value);

base.OnNavigatedTo(args);

}

同样,当在SecondPage触发TextBlock时,事件处理函数保存当前背景的颜色到App类中,接着调用GoBack:

Silverlight Project: SilverlightShareData File: SecondPage.xaml.cs (excerpt)

void OnTextBlockManipulationStarted(object sender, ManipulationStartedEventArgs args)

{

if (ContentPanel.Background is SolidColorBrush)

(Application.Current as App).SharedColor = (ContentPanel.Background as SolidColorBrush).Color;

this.NavigationService.GoBack();

args.Complete();

args.Handled = true;

}

MainPage类也可以重载OnNavigatedTo方法来获取存储的color值,并设置到背景属性:

protected override void OnNavigatedTo(NavigationEventArgs args)

{

Color? sharedColor = (Application.Current as App).SharedColor;

if (sharedColor != null)

ContentPanel.Background = new SolidColorBrush(sharedColor.Value);

base.OnNavigatedTo(args);

}

现在,我们可以在页面之间切换,颜色信息可以共享了。

使用App类作为仓库在页面之间共享数据是非常的方便。但是我们需要考虑更加结构化的解决方案,仅使用互相需要切换的页面资源,而不是使用一些第三方类,像App.

2 重载OnNavigatedFrom实现页面之间的数据传递

除了前面提到的OnNavigatedTo 虚拟方法,Page也定义了一个OnNavigatedFrom方法。初看起来这个方法没有什么用。终究,一个page知道自己要导航的其他page是因为它刚刚调用了Navigate或者GoBack.

OnNavigatedFromOnNavigatedTo方法中,他们都有一个NavigationEventArgs事件参数,它定义了两个属性:Uri类型的Uri, object类型的Content. 他们表示将要被导向到的page.

我们以MainPage导向到SecondPage为例,简单描述一些事件的处理顺序:

1) MainPage调用Navigate,参数为“/SecondPage.xaml.

2) MainPage中的OnNavigatedFrom方法被系统调用,传入的Uri属性包含“/SecondPage.xaml”信息,Content属性是SecondPage的新创建的实例对象。

3) SecondPage中的OnNavigatedTo方法被调用,参数与OnNavigatedFrom一样。

类似的,在SecondPage中,如果调用GoBack, 它的OnNavigatedFrom方法就会被调用,参数包括Uri指向“/MainPage.xaml”,Content属性就是MainPage的实例对象。接着,MainPage中的OnNavigatedTo方法被调用,并具有同样的参数信息。

下面然我们看看这个SilverlightInsertData的示例代码。这个项目包括连个page,分别叫MainPageSecondPage, 他们的XAML文件名就是我们前面提到的文件。

MainPage类中没有实现随机改变颜色的逻辑。相应的它使用SecondPage来为它获得颜色信息。

下面是MainPage后台的代码:

Silverlight Project: SilverlightInsertData File: MainPage.xaml.cs (excerpt)

public partial class MainPage : PhoneApplicationPage

{

public MainPage()

{

InitializeComponent();

}

public Color? ReturnedColor { set; get; }

void OnTextBlockManipulationStarted(object sender, ManipulationStartedEventArgs args)

{

this.NavigationService.Navigate(new Uri("/SecondPage.xaml", UriKind.Relative));

args.Complete();

args.Handled = true;

}

}

注意ReturnedColor 属性,可为空类型的Color属性和在前面App类中定义的属性一样。

下面是SecondPage后台的代码:

Silverlight Project: SilverlightInsertData File: SecondPage.xaml.cs (excerpt)

public partial class SecondPage : PhoneApplicationPage

{

Random rand = new Random();

public SecondPage() {

InitializeComponent();

}

void OnTextBlockManipulationStarted(object sender, ManipulationStartedEventArgs args)

{

this.NavigationService.GoBack();

args.Complete();

args.Handled = true;

}

protected override void OnManipulationStarted(ManipulationStartedEventArgs args)

{

ContentPanel.Background = new SolidColorBrush(

Color.FromArgb(255, (byte)rand.Next(255), (byte)rand.Next(255), (byte)rand.Next(255)));

base.OnManipulationStarted(args);

}

protected override void OnNavigatedFrom(NavigationEventArgs args)

{

if (ContentPanel.Background is SolidColorBrush)

{

Color clr = (ContentPanel.Background as SolidColorBrush).Color;

if (args.Content is MainPage) (args.Content as MainPage).ReturnedColor = clr;

}

base.OnNavigatedFrom(e);

}

}

当点击SecondPage时,SecondPage就将随机改变它的背景颜色,当点击TextBlock时,GoBack方法被调用。 新写的代码在重载的OnNavigatedFrom方法中,它会在GoBack被调用后,立即被调用。如果有一个有效的SolidColorBrush,方法中会检查导向的对象类型是否为MainPage, 如果是,它会将当前的Color对象保存到MainPageReturnedColor属性中。

MainPage接着可以在它的OnNavigatedTo方法中获得这个属性的值:

Silverlight Project: SilverlightInsertData File: MainPage.xaml.cs (excerpt)

public partial class MainPage : PhoneApplicationPage

{

protected override void OnNavigatedTo(NavigationEventArgs args)

{

if (ReturnedColor != null)

ContentPanel.Background = new SolidColorBrush(ReturnedColor.Value);

base.OnNavigatedTo(args);

}

}

从某种意义上说, MainPage调用SecondPage来获得Color值,就像调用一个对话框一样。但是如果你随后再次导向到SecondPage,它的屏幕初始颜色总是黑色(或者白色,如果你选择亮色彩的主题)。

有意思的是,SecondPage不能利用MainPage中的任何属性来初始化自己的背景颜色,因为目前我们没有重写SecondPage中的OnNavigatedTo 方法。从对称的角度,SecondPage需要定义自己的公共属性Color, 并需要MainPage在他的OnNavigatedFrom方法中设置这个Color属性值。你可能考虑对这个程序进行稍微地修改,在SecondPage中定义ReturnedColor属性。当MainPage导向到SecondPage,在MainPageOnNavigatedFrom 方法中将SecondPage的实例对象保存到MainPage的一个成员变量中。当SecondPage结束,它将Color值保存到ReturnedColor属性中并且调用GoBack. MainPage中的OnNavigatedTo方法会被调用,在这个方法中,MainPage可以使用先前保存的SecondPage的对象实例来访问ReturnedColor属性值。这个方案听起来不错,在这个程序中是可行的。但需要特别注意的是MainPage不能保证这个导向到的SecondPage实例和将来导向回来的SecondPage实例是相同的实例。每一次从MainPage导向到SecondPage, SecondPage都会生成一个完新的实例。你将会在后面章节中近一步的理解到这一点。

你可能感兴趣的:(windows,object,File,null,Random,silverlight,phone)