使用離散動畫做倒數計時

  • 940
  • 0

寫 WPF 或 UWP 的你,還在用 Timer 做倒數計時嗎?其實有更好的選擇 -- 直接使用動畫來完成這個工作。

可能是受到 Windows Forms 的制約,有些人即使是在開發 WPF 或 UWP 還是常常會想到用 Timer 來控制 UI 的變化;或許可以做到類似的效果,但我總覺得直接用動畫完成這項工作是比較乾淨俐落的。

雖然在 WPF 中有一個稱為 String Animation 的動畫形式,但為了讓程式碼在 WPF 和 UWP 間的差異最小化,這個範例我們使用『離散畫格 (DiscreteObjectKeyFrame)』來達成這項目標。

程式的流程很簡單,首先建立一個關鍵影格動畫:
 

 ObjectAnimationUsingKeyFrames animation = new ObjectAnimationUsingKeyFrames();

接著,依據所需的秒數,建立各秒的離散畫格:
 

for (Int32 i = 0; i < (seconds + 1); i++)
{
    DiscreteObjectKeyFrame clockKeyFrame = new DiscreteObjectKeyFrame();
    clockKeyFrame.KeyTime = KeyTime.FromTimeSpan(new TimeSpan(0, 0, i));
    clockKeyFrame.Value = ConvertSecondsToClock(seconds - i);
    animation.KeyFrames.Add(clockKeyFrame);
}
animation.Duration = new Duration(new TimeSpan(0, 0, seconds));

最後這個步驟就是加上 Storyboard,這邊在 WPF 和 UWP 有一點點不一樣,差異在兩邊的 Storyboard.SetTargetProperty Mtehod 參數不同。
(a) WPF
 

Storyboard.SetTarget(animation, countDownText);
Storyboard.SetTargetProperty(animation, new PropertyPath(TextBlock.TextProperty)); 
var storyboard = new Storyboard();           
storyboard.Children.Add(animation);           
storyboard.Begin();

(b) UWP
 

Storyboard.SetTarget(animation, countDownText);
Storyboard.SetTargetProperty(animation, "TextBlock.Text");
var storyboard = new Storyboard();
storyboard.Children.Add(animation);
storyboard.Begin();

既簡單又方便,是不是很容易啊?以後別再搞甚麼 Timer 了。

範例程式連結 WPF-UWP-Countdown-Animation