Windows Phone 7 计时器(停表)例子 Stopwatch
相关知识介绍:
1、System.Diagnostics.Stopwatch类
Stopwatch 实例可以测量一个时间间隔的运行时间,也可以测量多个时间间隔的总运行时间。在典型的 Stopwatch 方案中,先调用 Start 方法,然后调用 Stop 方法,最后使用 Elapsed 属性检查运行时间。
Stopwatch 实例或者在运行,或者已停止;使用 IsRunning 可以确定 Stopwatch 的当前状态。使用 Start 可以开始测量运行时间;使用 Stop 可以停止测量运行时间。通过属性 Elapsed、ElapsedMilliseconds 或 ElapsedTicks 查询运行时间值。当实例正在运行或已停止时,可以查询运行时间属性。运行时间属性在 Stopwatch 运行期间稳固递增;在该实例停止时保持不变。
默认情况下,Stopwatch 实例的运行时间值相当于所有测量的时间间隔的总和。每次调用 Start 时开始累计运行时间计数;每次调用 Stop 时结束当前时间间隔测量,并冻结累计运行时间值。使用 Reset 方法可以清除现有 Stopwatch 实例中的累计运行时间。
2、Microsoft.Phone.Shell.PhoneApplicationService类
PhoneApplicationService类提供了在程序的生命周期中可以访问应用程序的各种状态,以及自己存储的该类实例中的信息。用于管理应用程序的闲置行为。
3、相关控件
ToggleButton 类
可切换状态的控件的基类,例如 CheckBox 和 RadioButton。
命名空间: System.Windows.Controls.Primitives
Border 类
在另一个对象的周围绘制边框、背景或同时绘制二者。
命名空间: System.Windows.Controls
可以指定 Border 的基本属性,方法是设置其 Width、Height、BorderThickness 以及 Background 颜色。此外,您还可以通过设置 CornerRadius 属性以将边框的各角改为圆角,并且可以通过设置 Padding 属性以在 Border 中定位对象。
Border 只能包含一个子对象。如果要在多个对象周围放置一个边框,应将这些对象包装到一个容器对象中,例如 StackPanel。
实例代码及说明
<!--LayoutRoot contains the root grid where all other page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="STOPWATCH" Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<!-- 停表展示 -->
<Grid VerticalAlignment="Center"
Margin="25 0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- 时间显示 -->
<TextBlock Name="elapsedText"
Text="0"
Grid.Row="0"
FontFamily="Arial"
FontSize="{StaticResource PhoneFontSizeExtraLarge}"
TextAlignment="Center"
Margin="0 0 0 50"/>
<!--开始停止按钮 -->
<ToggleButton Name="startStopToggle"
Content="Start"
Grid.Row="1"
Checked="OnToggleButtonChecked"
Unchecked="OnToggleButtonChecked" />
</Grid>
<!-- 用一个Rectangle来控制时间设置的显示和隐藏 -->
<Rectangle Name="disableRect"
Fill="#80000000"
Visibility="Collapsed" />
<!-- 选择时间格式的对话框 -->
<Border Name="formatDialog"
Background="{StaticResource PhoneChromeBrush}"
BorderBrush="{StaticResource PhoneForegroundBrush}"
BorderThickness="3"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Visibility="Collapsed">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Name="radioButtonPanel"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
HorizontalAlignment="Center">
<RadioButton Content="Hour/Minute/Seconds"
Tag="HourMinuteSecond" />
<RadioButton Content="Seconds"
Tag="Seconds" />
<RadioButton Content="Milliseconds"
Tag="Milliseconds" />
</StackPanel>
<Button Grid.Row="1" Grid.Column="0"
Content="ok"
Click="OnOkButtonClick" />
<Button Grid.Row="1" Grid.Column="1"
Content="cancel"
Click="OnCancelButtonClick" />
</Grid>
</Border>
</Grid>
</Grid>
<!-- 底下的工具栏 -->
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar>
<!-- 弹出时间格式设置的按钮 -->
<shell:ApplicationBarIconButton IconUri="/Images/appbar.feature.settings.rest.png"
Text="format"
Click="OnAppbarFormatClick" />
<!-- 重置时间的按钮-->
<shell:ApplicationBarIconButton IconUri="/Images/appbar.refresh.rest.png"
Text="reset"
Click="OnAppbarResetClick" />
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.Globalization;
namespace StopWatch
{
public partial class MainPage : PhoneApplicationPage
{
Stopwatch stopwatch = new Stopwatch();//新建一个停表的类 System.Diagnostics.Stopwatch
TimeSpan suspensionAdjustment = new TimeSpan();//挂起的初始时间
string decimalSeparator = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator;//数字格式
public MainPage()
{
InitializeComponent();
DisplayTime();//初始化显示时间和时间的格式
}
//计时开始结束按钮 事件
void OnToggleButtonChecked(object sender, RoutedEventArgs e)
{
if ((bool)startStopToggle.IsChecked)
{
stopwatch.Start();//停表开始
startStopToggle.Content = "Stop";
CompositionTarget.Rendering += OnCompositionTargetRendering;
//当此事件发生时,表示存在一个可视框架可用于呈现到 Silverlight 内容图面。
//然后,可以在处理程序中一帧一帧地修改应用程序的可视对象或任何其他方面的内容。
}
else
{
stopwatch.Stop();//停表结束
startStopToggle.Content = "Start";
CompositionTarget.Rendering -= OnCompositionTargetRendering;
//移除帧变化的事件
}
}
//帧变化事件
void OnCompositionTargetRendering(object sender, EventArgs args)
{
DisplayTime();
}
//重置事件
void OnAppbarResetClick(object sender, EventArgs args)
{
stopwatch.Reset();//停止时间间隔测量,并将运行时间重置为零
startStopToggle.IsChecked = false;
suspensionAdjustment = new TimeSpan();//重新初始化时间为0
DisplayTime();
}
//设置时间格式的事件
void OnAppbarFormatClick(object sender, EventArgs args)
{
//显示设置时间格式的控件
disableRect.Visibility = Visibility.Visible;
formatDialog.Visibility = Visibility.Visible;
// 初始化 radio buttons
ElapsedTimeFormat currentFormat = (Application.Current as App).ElapsedTimeFormat;//读取程序的之前的设置
foreach (UIElement child in radioButtonPanel.Children)
{
RadioButton radio = child as RadioButton;
ElapsedTimeFormat radioFormat =
(ElapsedTimeFormat)Enum.Parse(typeof(ElapsedTimeFormat),
radio.Tag as string, true);
radio.IsChecked = currentFormat == radioFormat;
}
}
//保存时间的格式
void OnOkButtonClick(object sender, RoutedEventArgs args)
{
foreach (UIElement child in radioButtonPanel.Children)
{
RadioButton radio = child as RadioButton;
if ((bool)radio.IsChecked)
(Application.Current as App).ElapsedTimeFormat =
(ElapsedTimeFormat)Enum.Parse(typeof(ElapsedTimeFormat),
radio.Tag as string, true);
}
OnCancelButtonClick(sender, args);
}
//取消事件格式选择
void OnCancelButtonClick(object sender, RoutedEventArgs args)
{
//隐藏设置的控件
disableRect.Visibility = Visibility.Collapsed;
formatDialog.Visibility = Visibility.Collapsed;
DisplayTime();
}
//显示时间
void DisplayTime()
{
TimeSpan elapsedTime = stopwatch.Elapsed + suspensionAdjustment;//获取停表测量得出的总运行时间
string str = null;
switch ((Application.Current as App).ElapsedTimeFormat)//获取程序的时间格式设置
{
case ElapsedTimeFormat.HourMinuteSecond:
str = String.Format("{0:D2} {1:D2} {2:D2}{3}{4:D2}",
elapsedTime.Hours, elapsedTime.Minutes,
elapsedTime.Seconds, decimalSeparator,
elapsedTime.Milliseconds / 10);
break;
case ElapsedTimeFormat.Seconds:
str = String.Format("{0:F2} sec", elapsedTime.TotalSeconds);
break;
case ElapsedTimeFormat.Milliseconds:
str = String.Format("{0:F0} msec", elapsedTime.TotalMilliseconds);
break;
}
elapsedText.Text = str;
}
//当页面不再是框架中的活动页面时调用
protected override void OnNavigatedFrom(NavigationEventArgs args)
{
PhoneApplicationService service = PhoneApplicationService.Current;//获取当前应用程序的服务
service.State["stopWatchRunning"] = (bool)startStopToggle.IsChecked;//保存到当前的程序状态中 停表是否开始
service.State["suspensionAdjustment"] = suspensionAdjustment + stopwatch.Elapsed;//停表的事件
service.State["tombstoneBeginTime"] = DateTime.Now;//离开程序页面的时间
base.OnNavigatedFrom(args);
}
//当页面成为框架中的活动页面时调用
protected override void OnNavigatedTo(NavigationEventArgs args)
{
PhoneApplicationService service = PhoneApplicationService.Current;//获取当前应用程序的服务
if (service.State.ContainsKey("stopWatchRunning"))//判断是否离开过程序的页面
{
suspensionAdjustment = (TimeSpan)service.State["suspensionAdjustment"];
if ((bool)service.State["stopWatchRunning"])//判断是否离开程序页面的时候 是否已经开始计时了
{
suspensionAdjustment += DateTime.Now -
(DateTime)service.State["tombstoneBeginTime"];//计算时差
startStopToggle.IsChecked = true;
}
else
{
DisplayTime();
}
}
base.OnNavigatedTo(args);
}
}
}
namespace StopWatch
{
//时间格式设置枚举
public enum ElapsedTimeFormat
{
HourMinuteSecond,
Seconds,
Milliseconds
}
}
app.cs程序初始化和结束的处理
……
// 程序设置时间格式的设置
public ElapsedTimeFormat ElapsedTimeFormat { set; get; }
public PhoneApplicationFrame RootFrame { get; private set; }
public App()
{
UnhandledException += Application_UnhandledException;
InitializeComponent();
InitializePhoneApplication();
}
private void Application_Launching(object sender, LaunchingEventArgs e)
{
LoadSettings();
}
private void Application_Activated(object sender, ActivatedEventArgs e)
{
LoadSettings();
}
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
SaveSettings();
}
private void Application_Closing(object sender, ClosingEventArgs e)
{
SaveSettings();
}
//加载停表上一次的时间格式设置
void LoadSettings()
{
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
if (settings.Contains("elapsedTimeFormat"))
ElapsedTimeFormat = (ElapsedTimeFormat)settings["elapsedTimeFormat"];
else
ElapsedTimeFormat = ElapsedTimeFormat.HourMinuteSecond;
}
// 退出程序保存时间设置
void SaveSettings()
{
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
settings["elapsedTimeFormat"] = ElapsedTimeFormat;
settings.Save();
}
……