Windows Phone 7 利用计时器DispatcherTimer创建时钟
DispatcherTimer是在System.Windows.Threading 命名空间下的定时器。集成到按指定时间间隔和指定优先级处理的 Dispatcher 队列中的计时器。 在每个 Dispatcher 循环的顶端重新计算 DispatcherTimer。 不能保证会正好在时间间隔发生时执行计时器,但能够保证不会在时间间隔发生之前执行计时器。 这是因为 DispatcherTimer 操作与其他操作一样被放置到 Dispatcher 队列中。 何时执行 DispatcherTimer 操作取决于队列中的其他作业及其优先级。
每当将对象方法绑定到计时器时,DispatcherTimer 都将使对象保持活动状态。 DispatcherTimer timer = new DispatcherTimer() ; timer.Tick += new EventHandler(timer_Tick); void timer_Tick() {} timer.Interval = new TimeSpan(TimeSpan.TicksPerSecond); 首先,DispatcherTimer只会创建一个线程,竟然是一个线程,那么它的执行顺序就很明显,要等执行完成之后,才会重头开始执行。 其实是这样的,每当线程执行完一次,等待Interval 设置的时间(比如上面我们设置了TicksPerSecond),然后才会重新开始,也就是说 ,要执行完->然后再等待时间->然后重复 时钟的例子: <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="利用定时器设计的时钟" Style="{StaticResource PhoneTextNormalStyle}"/> </StackPanel> <!--ContentPanel - place additional content here--> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" SizeChanged="OnContentPanelSizeChanged"> <TextBlock Name="referenceText" Text="参考对象文本控件" /> <TextBlock Name="hourHand"> <TextBlock.RenderTransform> <CompositeTransform /> </TextBlock.RenderTransform> </TextBlock> <TextBlock Name="minuteHand"> <TextBlock.RenderTransform> <CompositeTransform /> </TextBlock.RenderTransform> </TextBlock> <TextBlock Name="secondHand"> <TextBlock.RenderTransform> <CompositeTransform /> </TextBlock.RenderTransform> </TextBlock> </Grid> </Grid> using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Threading; using Microsoft.Phone.Controls; namespace HybridClock { public partial class MainPage : PhoneApplicationPage { Point gridCenter; Size textSize; double scale; public MainPage() { InitializeComponent(); DispatcherTimer tmr = new DispatcherTimer();//创建计时器 tmr.Interval = TimeSpan.FromSeconds(1);//TimeSpan 结构 表示一个时间间隔。 //DispatcherTimer.Interval 属性 获取或设置计时器刻度之间的时间段。 //不能保证会正好在时间间隔发生时执行计时器,但能够保证不会在时间间隔发生之前执行计时器。 //这是因为 DispatcherTimer 操作与其他操作一样被放置到 Dispatcher 队列中。 //何时执行 DispatcherTimer 操作取决于队列中的其他作业及其优先级。 tmr.Tick += OnTimerTick;//DispatcherTimer.Tick 事件 超过计时器间隔时发生。 tmr.Start();//计时器开始 } //这个事件会在刚进入这个grid面板的时候触发 //从而可以确定grid ContentPanel的准确高度和宽度 void OnContentPanelSizeChanged(object sender, SizeChangedEventArgs args)//ContentPanel的ActualHeight 或 ActualWidth 属性的值发生更改时发生。 { gridCenter = new Point(args.NewSize.Width / 2, args.NewSize.Height / 2); textSize = new Size(referenceText.ActualWidth, referenceText.ActualHeight);//这个就是grid的内的高度和宽度 scale = Math.Min(gridCenter.X, gridCenter.Y) / textSize.Width; UpdateClock(); } //计时器触发的事件函数 void OnTimerTick(object sender, EventArgs e) { UpdateClock(); } void UpdateClock() { DateTime dt = DateTime.Now; double angle = 6 * dt.Second; SetupHand(secondHand, "--------------秒针 " + dt.Second, angle); angle = 6 * dt.Minute + angle / 60; SetupHand(minuteHand, "---------分针 " + dt.Minute, angle); angle = 30 * (dt.Hour % 12) + angle / 12; SetupHand(hourHand, "------时针 " + (((dt.Hour + 11) % 12) + 1), angle); } void SetupHand(TextBlock txtblk, string text, double angle) { txtblk.Text = text; CompositeTransform xform = txtblk.RenderTransform as CompositeTransform;//获取txtblk的RenderTransform 属性 并转化为CompositeTransform xform.CenterX = textSize.Height / 2;//移动的中心点的 x 坐标 xform.CenterY = textSize.Height / 2;//移动的中心点的 y 坐标 xform.ScaleX = scale;//设置 x 轴的缩放比例 xform.ScaleY = scale;//设置 y 轴的缩放比例 xform.Rotation = angle - 90;//获取或设置顺时针旋转角度(以度为单位) xform.TranslateX = gridCenter.X - textSize.Height / 2;//设置沿 x 轴平移对象的距离 xform.TranslateY = gridCenter.Y - textSize.Height / 2;//设置沿 y 轴平移对象的距离 } } } |