2013年4月24日 星期三

[Silverlight、WPF] 計時器(Timer)方式

最近被問到在WPF中如何製作計時器,其實計時器的製作方式有很多種方法,像常見就是使用DispatcherTimer來做計時器,或者是製作動畫很重要的Storyboard也同樣可以達到計時器的功能,而DispatcherTimer跟Storyboard兩者雖然在使用上語法很接近,不過Storyboard的時間準確度會比DispatcherTimer來的高,詳細的原因在網路上也有許多人解釋過了,可以參考下面連結:

StoryBoard versus DispatcherTimer for Animation and Game Loops.

DispatcherTimer vs Storyboard

不過一般來說如果時間沒有需要計算到非常準確的話,兩者其實都是可行的方法,另外下面說明的兩種計時器方法也同樣可以適用在Silverlight上,語法上並沒有差異。

 

DispatcherTimer

主要就是設定Interval的值,這裡範例是每秒倒數的一個計時器,所以Interval就是一秒鐘,然後當Interval的時間到的時候會去觸發Tick事件,所以再把要做的邏輯寫在Tick中,而要啟動DispatcherTimer則是呼叫Start()方法,當要停止時則是呼叫Stop()方法

using System;
using System.Windows;
using System.Windows.Threading;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(1) };
int sec = 5;
public MainWindow()
{
InitializeComponent();
timer.Tick += timer_Tick;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
if (sec > 0)
{
sec--;
timerText.Text = sec.ToString(); //timerText是介面上的一個TextBlock
}
else
timer.Stop();
}
}
}

Storyboard

Storyboard整個作法幾乎都跟DispatcherTimer雷同,除了屬性名稱上的差異外,最大的差別在於Storyboard的Completed事件結束後,並不會重新再去觸發,也就是只會執行一次,跟DispatcherTimer的Tick事件會一直不斷觸發有所不同,所以Storyboard必須在Completed事件中再次呼叫Begin()方法,才可以達到重複執行的效果

using System;
using System.Windows;
using System.Windows.Media.Animation;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
Storyboard sb_timer = new Storyboard() { Duration = TimeSpan.FromSeconds(1) };
int sec = 5;
public MainWindow()
{
InitializeComponent();
sb_timer.Completed += sb_timer_Completed;
sb_timer.Begin();
}
void sb_timer_Completed(object sender, EventArgs e)
{
if (sec > 0)
{
sec--;
timerText.Text = sec.ToString(); //timerText是介面上的一個TextBlock
sb_timer.Begin();
}
}
}
}

Reference

DispatcherTimer Class (System.Windows.Threading)

Storyboard Class (System.Windows.Media.Animation)

0 意見:

張貼留言