与众不同 windows phone (27) - Feature(特性)之搜索的可扩展性, 程序的生命周期和页面的生命周期, 页面导航, 系统状态栏
作者:webabcd
介绍
与众不同 windows phone 7.5 (sdk 7.1) 之特性
- 搜索的可扩展性
- 程序的生命周期和页面的生命周期
- 页面导航
- 系统状态栏
示例
1、关于搜索的可扩展性
SearchExtensibility.xaml
<phone:PhoneApplicationPage x:Class="Demo.Feature.SearchExtensibility" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480" shell:SystemTray.IsVisible="True"> <Grid x:Name="LayoutRoot" Background="Transparent"> <TextBlock VerticalAlignment="Top" TextWrapping="Wrap" Text="关于搜索的可扩展性:由于需要与“搜索”按钮的 bing 集成,而对于相关的 n 多 bing 特性中国又不支持,所以就不写 Demo 了" /> </Grid> </phone:PhoneApplicationPage>
2、页面的生命周期
LifeCycle.xaml
<phone:PhoneApplicationPage x:Class="Demo.Feature.LifeCycle" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480" shell:SystemTray.IsVisible="True"> <Grid x:Name="LayoutRoot" Background="Transparent"> <StackPanel Orientation="Vertical"> <HyperlinkButton Content="导航到主界面" NavigateUri="/MainPage.xaml" /> <TextBlock Name="lblMsg" Text="请模拟器调试,查看 Output 窗口" /> </StackPanel> </Grid> </phone:PhoneApplicationPage>
LifeCycle.xaml.cs
/* * 演示页面的生命周期 * * 应用程序的生命周期的演示详见:App.xaml 和 App.xaml.cs */ using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Phone.Controls; using System.Windows.Navigation; using System.Diagnostics; namespace Demo.Feature { public partial class LifeCycle : PhoneApplicationPage { public LifeCycle() { InitializeComponent(); } // 导航进此页面时触发 protected override void OnNavigatedTo(NavigationEventArgs e) { Debug.WriteLine("OnNavigatedTo"); // 当 NavigationMode.New 时由于是一个新的页面示例,所以只执行一次 // 当 NavigationMode.Back, NavigationMode.Forward 时由于是从内存加载的,之前的页面状态都会被保留,所以加上之前注册的事件这里一共会执行两遍 this.Loaded += delegate { MessageBox.Show("NavigationMode 为:" + e.NavigationMode.ToString() + ",看看我执行几次?"); }; // 当 NavigationMode.New 时由于是一个新的页面示例,所以 State 中不会有数据 // 当 NavigationMode.Back, NavigationMode.Forward 时由于是从内存加载的,所以 State 中可以获取到之前“OnNavigatedFrom”时保存的数据 if (State.Keys.Contains("navigatedFromTime")) Debug.WriteLine("应用程序在 OnNavigatedFrom 时保存到状态字典的数据:navigatedFromTime - " + ((DateTime)this.State["navigatedFromTime"]).ToString("HH:mm:ss")); } // 导航出此页面时触发 protected override void OnNavigatedFrom(NavigationEventArgs e) { Debug.WriteLine("OnNavigatedFrom"); // 导航出此页面时,可以在内存中保存一些状态数据 this.State["navigatedFromTime"] = DateTime.Now; } } }
3、程序的生命周期
App.xaml
<Application x:Class="Demo.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"> <Application.ApplicationLifetimeObjects> <shell:PhoneApplicationService Launching="Application_Launching" Closing="Application_Closing" Activated="Application_Activated" Deactivated="Application_Deactivated"/> </Application.ApplicationLifetimeObjects> </Application>
App.xaml.cs
/* * 演示程序的生命周期 * * 应用程序生命周期相关的事件 * Launching - 创建一个新的应用程序实例时会触发此事件 * Closing - 应用程序终止前会触发此事件 * Activated - 从 dormant 或 tombstone 状态返回时触发此事件 * Deactivated - 用户导航出此应用程序时触发此事件 * * 注:以上每一个事件处理的任务必须在 10 秒内完成 */ private void Application_Launching(object sender, LaunchingEventArgs e) { // 全新启动一个应用程序实例时触发(比如从开始屏幕启动,从 toast 启动等) Debug.WriteLine("Application_Launching"); /* * 将空闲监测设置为 PhoneApplicationService.Current.ApplicationIdleDetectionMode = IdleDetectionMode.Enabled: * 当系统检测到当前应用程序处于空闲状态时,会主动采取措施以减少设备的耗电量。比如锁屏时,会调用 Deactivated 事件,会转到休眠状态 * 将空闲监测设置为 PhoneApplicationService.Current.ApplicationIdleDetectionMode = IdleDetectionMode.Disabled: * 禁止进行空闲监测。比如锁屏时,一般不会调用 Deactivated 事件,不会转到休眠状态 */ // 默认值是 IdleDetectionMode.Enabled PhoneApplicationService.Current.ApplicationIdleDetectionMode = IdleDetectionMode.Enabled; /* * PhoneApplicationService.Current.ApplicationIdleDetectionMode - 应用程序空闲检测 * 当设备处于锁定状态,则认为此时应用程序处于空闲状态 * PhoneApplicationService.Current.UserIdleDetectionMode - 用户空闲检测 * 当用户在设备锁定超时期后未接触屏幕或硬件按键时,则认为处于用户空闲状态,此时系统会进入低功耗状态(所以举例:靠加速计操控的应用程序就应该禁用用户空闲检测) */ } private void Application_Activated(object sender, ActivatedEventArgs e) { // 从 dormant 状态或 tombstone 状态返回时触发 Debug.WriteLine("Application_Activated"); if (e.IsApplicationInstancePreserved) { // 从 dormant 状态返回(注:dormant 状态时,系统会保存 app 的状态) Debug.WriteLine("从 dormant 状态返回"); } else { // 从 tombstone 状态返回(注:tombstone 状态时,系统不会保存 app 的状态) Debug.WriteLine("从 tombstone 状态返回"); Debug.WriteLine("应用程序在 Application_Deactivated 时保存到状态字典的数据:deactivatedTime - " + ((DateTime)PhoneApplicationService.Current.State["deactivatedTime"]).ToString("HH:mm:ss")); } } private void Application_Deactivated(object sender, DeactivatedEventArgs e) { // 导航出应用程序、按“开始”按钮、启动其他应用程序、锁屏时触发 Debug.WriteLine("Application_Deactivated"); /* * 应用程序一般会转成 dormant 状态,必要时会转成 tombstone 状态 * 如果应用程序转成了 tombstone 状态,那么由于系统不会再保存 app 的状态,所以需要手动保存 * PhoneApplicationService.Current.State 是一个字典表 * * 注: * dormant 状态时,系统会保存 app 的状态(在内存) * tombstone 状态时,系统不会保存 app 的状态,需要手动保存相关的状态数据到状态字典表(在内存) * 系统最多只能保存最近 5 个 app 的状态或状态字典表(在内存),长按返回键可以看到 */ PhoneApplicationService.Current.State["deactivatedTime"] = DateTime.Now; } private void Application_Closing(object sender, ClosingEventArgs e) { // 应用程序终止前触发,此时应用程序即将终止,并且不会保存任何状态 Debug.WriteLine("Application_Closing"); }
4、关于页面导航
Navigation.xaml
<phone:PhoneApplicationPage x:Class="Demo.Feature.Navigation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480" shell:SystemTray.IsVisible="True"> <Grid x:Name="LayoutRoot" Background="Transparent"> <StackPanel Orientation="Vertical"> <Button Content="导航到主界面" Click="Button_Click" /> </StackPanel> </Grid> </phone:PhoneApplicationPage>
Navigation.xaml.cs
/* * 演示页面导航相关的操作 * * NavigationContext.QueryString - 用于获取导航进来的参数 * * * NavigationService - 导航服务 * CanGoBack - 能否向后导航 * CanGoForward - 能否向前导航 * CurrentSource - 当前页面的地址 * Source - 指定需要导航到的页面的地址 * BackStack - 后退堆栈中的历史记录的集合 * RemoveBackEntry() - 从后退堆栈中移除最近的条目 * 此操作为异步操作,相关事件:JournalEntryRemoved * StopLoading() - 页面导航是异步的,可以通过此方法停止尚未处理的异步导航 * 导航的相关事件:Navigating, Navigated, NavigationStopped, NavigationFailed * GoBack() - 向后导航 * GoForward() - 向前导航 * Navigate() - 导航到指定地址 * * * NavigationEventArgs - 导航参数 * Uri - 页面地址 * IsNavigationInitiator - 当前框架内做的导航则为 true;当前框架的父框架做的导航则为 false * NavigationMode - 导航模式(System.Windows.Navigation.NavigationMode 枚举) * New, Back, Forward, Refresh */ using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Phone.Controls; using System.Windows.Navigation; namespace Demo.Feature { public partial class Navigation : PhoneApplicationPage { public Navigation() { InitializeComponent(); /* * PhoneApplicationPage.BackKeyPress - 用户按了“后退”键时触发的事件 */ this.BackKeyPress += new EventHandler<System.ComponentModel.CancelEventArgs>(Navigation_BackKeyPress); } void Navigation_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e) { MessageBox.Show("你按了“后退”键"); } protected override void OnNavigatedTo(NavigationEventArgs e) { } protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) { base.OnNavigatingFrom(e); if (e.IsCancelable) { MessageBoxResult result = MessageBox.Show("确认离开此页吗?", "警告", MessageBoxButton.OKCancel); if (result == MessageBoxResult.Cancel) { e.Cancel = true; } } } protected override void OnNavigatedFrom(NavigationEventArgs e) { } private void Button_Click(object sender, RoutedEventArgs e) { NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative)); } } }
5、关于系统状态栏
SystemTrayDemo.xaml
<phone:PhoneApplicationPage x:Class="Demo.Feature.SystemTrayDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480" shell:SystemTray.IsVisible="True"> <!-- 通过 xaml 的方式设置 SystemTray 的 ProgressIndicator --> <!-- <shell:SystemTray.ProgressIndicator> <shell:ProgressIndicator IsIndeterminate="True" IsVisible="True" Text="系统状态栏文本" /> </shell:SystemTray.ProgressIndicator> --> <Grid x:Name="LayoutRoot" Background="Transparent"> </Grid> </phone:PhoneApplicationPage>
SystemTrayDemo.xaml.cs
/* * 演示如何控制系统状态栏 * * SystemTray - 系统状态栏 * BackgroundColor, SetBackgroundColor() - 背景 * ForegroundColor, SetForegroundColor() - 前景 * IsVisible, SetIsVisible() - 是否显示 * Opacity, SetOpacity() - 不透明度 * ProgressIndicator, SetProgressIndicator() - 系统状态上的进度条 * * ProgressIndicator - 系统状态上的进度条 * IsIndeterminate - 是否是进度不确定的进度条 * IsVisible - 是否显示 * Text - 需要显示的文本内容 * Value - 当 IsIndeterminate = false 时,指定实际进度(0 - 1 之间) */ using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Phone.Controls; using Microsoft.Phone.Shell; namespace Demo.Feature { public partial class SystemTrayDemo : PhoneApplicationPage { public SystemTrayDemo() { InitializeComponent(); SystemTray.SetIsVisible(this, true); SystemTray.SetOpacity(this, 0.7); SystemTray.SetBackgroundColor(this, Colors.Red); SystemTray.SetForegroundColor(this, Colors.Green); ProgressIndicator pi = new ProgressIndicator(); pi.IsVisible = true; pi.IsIndeterminate = true; pi.Text = "系统状态栏文本"; SystemTray.SetProgressIndicator(this, pi); } } }
OK
[源码下载]