WPF的一個特色就是支持動畫,咱們能夠很是容易的實現漂亮大方的界面。首先,咱們來複習一下動畫的基本概念。計算機中的動畫通常是定格動畫,也稱之爲逐幀動畫,它經過每幀不一樣的圖像連續播放,從而欺騙眼和腦產生動畫效果。其原理在維基百科上有比較詳盡的解釋,這裏就很少介紹了。html
也就是說,咱們要產生動畫,只須要連續刷新界面便可。例如,咱們要實現一個寬度變化的按鈕的動畫,能夠用以下方式來實現:框架
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
var timer = new System.Windows.Threading.DispatcherTimer();
timer.Tick += new EventHandler(OnTimedEvent);
timer.Interval = TimeSpan.FromSeconds(1.0 / 20);
timer.Start();
}
int index = 0;
private void OnTimedEvent(object sender, EventArgs e)
{
index++;
if (index > 40)
index = 0;
button.Width = 8 * (index++);
} post
這段代碼不難理解,就是每隔1/20秒更新一次按鈕的寬度,在2s內將其高度從0變爲320,重複播放。 性能
這段代碼雖然實現了動畫效果,但它是經過計時器更新的傳統作法,在WinForm下也能實現。在WPF中,正統的實現動畫方式爲: 學習
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
var widthAnimation = new DoubleAnimation()
{
From = 0,
To = 320,
Duration = TimeSpan.FromSeconds(2),
RepeatBehavior = RepeatBehavior.Forever,
};
button.BeginAnimation(WidthProperty, widthAnimation);
} 動畫
相比較而言,WPF的動畫的實現方式有以下優勢:url
1、簡潔spa
這個是很是明顯的,WPF的動畫的代碼很是容易理解,Timer的版本則要難懂得多。固然,咱們也能夠經過封裝,使得用Timer也能用相似的API實現動畫。但動畫的API並非僅僅這麼一點,要把整個動畫框架的API都封裝也沒有那麼容易。線程
2、和XAML無縫集成設計
這個就是WPF的獨有技術了,得益於XAML強大的表述能力,咱們能夠寫出很是強大且容易維護的動畫。(這裏就不舉例了,後續文章中再作介紹)這點WinFom的Timer版本是沒法作到的。
3、流暢性
若是將這兩種實現方式一塊兒跑起來比較一下就會發現,Timer實現的版本明顯要卡頓,而且並無精準的按照咱們設計的那樣運動。具體緣由爲:
Timer精度的問題:因爲是改UI控件的屬性(按鈕的寬度),所以必須在UI線程上進行,所以DispatcherTimer 操做與其餘操做同樣須要放置到 Dispatcher 隊列中,它並不保證剛好在改時間間隔中。它並不適合動畫這種間隔很短的計時。
幀率的問題:逐幀動畫的流暢性通常取決於每秒更新的幀數,也就是常說的幀率。人眼睛上限是70幀,而我這裏代碼中的Timer的固定了爲20幀,所以是能明顯感受到卡頓的。而WPF的動畫則否則,從它的API中能夠看到,它是沒有幀率的設置的。實際上,它是根據計算機的性能和當前進程的繁忙程度儘量增大幀率的,所以WPF的動畫是遠大於20幀的,所以要流暢得多。
那麼,是否只要修改參數,加大Timer的版本的幀率,也能夠實現一樣流暢的動畫呢? 試了一下,就算修改參數,也是沒法達到WPF版本的流暢程度的。我認爲緣由主要有以下兩點,
- DispatcherTimer精度不夠,沒法實現大幀率下準確刷新。
- 經過簡單的設置參數很難像WPF那樣幀率根據計算機的性能和當前進程的繁忙程度智能匹配幀率。幀率設置太低,動畫不流暢,設置過大,處理不過來仍然不流暢。而且UI線程的忙碌程度是會動態變化的,幀率也須要相應調整,這些都沒法經過Timer來簡單的處理。
總之,經過Timer定時更新的方式並不適合用來實現動畫。所以仍是有必要學習一下WPF的動畫框架的,後面我將陸續寫一系列文章進行一些簡單的介紹。若是要系統的學習,建議參看如下微軟的官方文檔: http://msdn.microsoft.com/zh-cn/library/ms752312(v=vs.110).aspx