計時事件概觀
更新:2007 年 11 月
本主題說明如何使用 Timeline 和 Clock 物件上可用的五種計時事件。
必要條件
若要了解本主題,您應該了解如何建立及使用動畫。若要開始使用動畫,請參閱動畫概觀。
有幾種方式可以在 WPF 中將屬性做成動畫:
使用腳本物件 (標記和程式碼):您可以使用 Storyboard 物件來排列和配置動畫給一個或多個物件。如需範例,請參閱 HOW TO:使用腳本建立屬性的動畫。
使用本機動畫 (僅程式碼):您可以直接將 AnimationTimeline 物件套用至要建立動畫的屬性。如需範例,請參閱 HOW TO:不使用腳本而建立屬性的動畫。
使用時鐘 (僅程式碼):您可以明確管理時鐘的建立,並且自己配置動畫時鐘。如需範例,請參閱 HOW TO:使用 AnimationClock 建立屬性的動畫。
因為您可以用標記和程式碼使用這些方法,所以本概觀中的範例會使用 Storyboard 物件。但是,這裡所述的概念也適用於其他建立屬性動畫的方法。
什麼是時鐘?
除了描述時間區段之外,時刻表本身實際並不會執行任何動作。真正在執行工作的是時刻表的 Clock 物件:它會替時刻表維護與計時相關的執行時期狀態。在大部分情況下 (例如使用腳本時),系統會自動為時刻表建立時鐘。您也可以使用 CreateClock 方法來明確建立 Clock。如需 Clock 物件的詳細資訊,請參閱動畫和計時系統概觀。
使用事件的原因?
所有互動計時作業都是非同步的,只有一個例外 (與最後一個刻度對齊)。您無法得知事件執行的確切時間。若您有其他程式碼必須依賴您的計時作業,這就會是個問題。假設您想要停止會將矩形顯示為動畫的時刻表。而在時刻表停止後,您想要變更矩形的色彩。
myStoryboard.Stop(myRectangle);
// This statement might execute
// before the storyboard has stopped.
myRectangle.Fill = Brushes.Blue;
在上述範例中,程式碼的第二行可能會在腳本停止之前就執行,這是因為停止動作是屬於非同步作業。告訴時刻表或時鐘停止,就會建立一種「停止要求」,而這種要求要等到計時引擎跳到下一個時間後才會處理。
若要在時刻表完成後執行命令,請使用計時事件。下列範例會在腳本停止播放後,用事件處理常式變更矩形的色彩。
// Change the rectangle's color after the storyboard stops.
void myStoryboard_CurrentStateInvalidated(object sender, EventArgs e)
{
Clock myStoryboardClock = (Clock)sender;
if (myStoryboardClock.CurrentState == ClockState.Stopped)
{
myRectangle.Fill = Brushes.Blue;
}
}
...
// Register for the CurrentStateInvalidated timing event.
myStoryboard.CurrentStateInvalidated += new EventHandler(myStoryboard_CurrentStateInvalidated);
如需更完整的範例,請參閱 HOW TO:時鐘的狀態變更時接收通知。
公用事件
Timeline 和 Clock 類別都提供五種計時事件。下表列出這些事件和其觸發條件。
事件 |
觸發互動作業 |
其他觸發程序 |
---|---|---|
Completed |
跳至填滿 |
時鐘完成。 |
CurrentGlobalSpeedInvalidated |
暫停、繼續、搜尋、設定速率、跳至填滿、停止 |
時鐘倒轉、加速、開始或停止。 |
CurrentStateInvalidated |
開始、跳至填滿、停止 |
時鐘開始、停止或填滿。 |
CurrentTimeInvalidated |
開始、搜尋、跳至填滿、停止 |
時鐘進行中。 |
RemoveRequested |
移除 |
跳動和事件的合併
當您在 WPF 中顯示物件動畫時,實際上是計時引擎在管理您的動畫。計時引擎會追蹤時間的進度,並計算每個動畫的狀態。它會在一秒內進行許多這類評估活動。這類評估活動稱為「跳動」。
雖然跳動發生次數很頻繁,但每次跳動之間仍可能發生許多事情。例如,時刻表可能已停止、又啟動,然後又再度停止,在這個情況下,它的狀態已經變更三次。理論上,一次跳動可以引發事件許多次;但是時間引擎會合併事件,使得每一次跳動最多只會引發每種事件一次。
註冊事件
有兩種方式可以註冊以取得計時事件:您可以使用時刻表註冊或使用時刻表建立的時鐘註冊。雖然直接使用時鐘註冊事件只能利用程式碼完成,但這是比較容易的做法。您可以使用標記或程式碼向時刻表註冊事件。下節說明如何使用時刻表註冊時鐘事件。
使用時刻表註冊時鐘事件
雖然時刻表的 Completed、CurrentGlobalSpeedInvalidated、CurrentStateInvalidated、CurrentTimeInvalidated 和 RemoveRequested 事件表面上與時刻表有關,但註冊這些事件實際上會使事件處理常式與為該時刻表建立的 Clock 產生關聯。
例如,當您在時刻表上註冊 Completed 事件時,實際上就是在告訴系統註冊為該時刻表而建立之每個時鐘的 Completed 事件。在程式碼中,您必須在為這個此時刻表建立 Clock 之前註冊這個事件,否則您就不會收到通知。這在 XAML 中會自動發生,剖析器 (Parser) 會在建立 Clock 之前自動註冊事件。