1. 程式人生 > >WPF控制動畫開始、停止、暫停和恢復

WPF控制動畫開始、停止、暫停和恢復

1、閒言

好久也沒更新一部落格了,自己有點發懶,同時確實這幾個月來也有點忙。風機監測軟體,專案中,有這樣一個小需求:正常風機在旋轉的時候,上位機軟要做一個風機的圖片,讓它不停地旋轉,一但檢測到下面風機停止了,上位機軟體介面的風機圖片也要跟著停止,並且風機圖片的旋轉速度最好是能夠與真實的速度成比例關係,這樣軟體才更有逼格一點。就是實現這樣一個效果,看下圖1,左邊是一個狀態指示,沒有做動畫,只是做了一個圖片的切換,效果還看得過去吧。

圖1 風機旋轉動畫

2、動畫製作

 在WPF做動畫前,首先超碼得有3個東西:動畫要做什麼樣子的動作(基本的有旋轉,平移,放縮等等),是什麼型別的動畫持續多久(某個數值變化,顏色變化,3D變化之類的),最後是一個故事板。這就相當於我們開發人員做個導演,而介面上的控制元件就是我們請來的演員,所有的窗體就是我們場地。故事板就是表演的劇本了,一切準備就緒後,就可以開始請演員們做事了(在這裡,我要它轉,而且是360度的轉,有殘忍了)。

3個東西準備的相應的程式碼下:

1 private RotateTransform rt_FanRotate = new RotateTransform();   //做旋轉動
2 private DoubleAnimation da_FanRotate = new DoubleAnimation();   //數值型別
3 private Storyboard sb_FanRotate = new Storyboard();             //故事板

接下來就開始安排旋轉動作了,程式碼如下:

1 rt_FanRotate.CenterX = img_FanRotate.Width / 2
; //旋轉中心 2 rt_FanRotate.CenterY = img_FanRotate.Height / 2; 3 img_FanRotate.RenderTransform = rt_FanRotate; //將此旋轉變換賦給風機圖片控制元件

動作安排好看,就要開始準備要這個動作怎麼做了,做多久了。平時我們自己轉圈,有轉90度的,有轉180度的,還有轉720度(這傢伙可能是抽風了)。並且還有指定這個旋轉的時間,有時候要它慢慢地完成,有時要它瞬間完成,在這裡我要這個風機圖片從0度開始轉,轉360度,用時300ms,程式碼如下:

1 da_FanRotate.Duration = new
Duration(TimeSpan.FromMilliseconds(600)); 2 da_FanRotate.From = 0; 3 da_FanRotate.By = 360;

動作安排好了,動作的怎麼動,動多久也指定好了,可以讓風機圖片上場了。這個時候,導演就開始叫人了,程式碼如下:

1 DependencyProperty[] propertyChain = new DependencyProperty[]
2 {
3     Image.RenderTransformProperty,
4     RotateTransform.AngleProperty
5 };
6 
7 Storyboard.SetTargetName(da_FanRotate, img_FanRotate.Name);
8 Storyboard.SetTargetProperty(da_FanRotate, new PropertyPath("(0).(1)", propertyChain));
9 sb_FanRotate.Children.Add(da_FanRotate);

這段程式碼的理解比前面的可能稍微難一點點,不怕,我們一步步來分析。1~5行是定義了一個依賴屬性鏈:Image的變化屬性,和旋轉變化的角度屬性,它將是我們動畫要控制的屬性。說簡單點,就是我們要讓圖片旋轉變化。按理來講,前面我們已經指定了圖片的旋轉動作,和它的時間,這裡為什麼還要在故事板上指定一下呢。因為故事板不止可以控制一個物件,它可以控制多個。這很好理解決,我們的電影電視不可能一直是一個人演吧(好像也有這樣的電影,邪惡了!)。所以當我們的風機圖片上場的時候,就應該給導演說,我是某某,來演XX的。因此就出現了7、8行的程式碼。個人的表述能力有限,如果把你說蒙了,請過來打我!!

這個時候一切準備就緒了,請開始我們的表演吧。不過還別急,我們還要設定一下,這個故場景要持續多長時間,也就是我們的一個境頭要多長時間,程式碼如下:

1 sb_FanRotate.Duration = new Duration(TimeSpan.FromMilliseconds(600));
2 sb_FanRotate.RepeatBehavior = RepeatBehavior.Forever;

上面程式碼設定為故事的時間為600ms,不停地迴圈(小時候看的電視劇《西遊記後傳》就有類似的鏡頭,孫悟空拿個棒子不停地打打打打打!!)。

這個時候是真的全部準備就緒了,導演開始喊,Action!!程式碼如下:

sb_FanRotate.Begin(img_FanRotate);

這個時候,代開始RUN你的VS,就可以開心地發現在你的所指定的物件開始轉了,應該很開心吧,當了一回導演了,小激動一把。

3、控制動畫

① 開始動畫

 按理來講,第2節已經說明了如何開始動畫了,不就是Begin嗎?但是如果這樣子單純地Begin,動畫是停不下來的。有的傢伙演得比較投入,完全停不下來的那種。網上就有很多人碰到這種問題,如下圖,這是CSDN部落格上的一個博友總結的辦法。不得不說這博友很是粗爆,別人不就是停不下來嗎,直接把人家給踢走了(Remove)。當然我們是文明人,不能像他那樣子。

 圖2 博友動畫停止

解決辦法我們在開始動畫的時,要使用如下Begin的方法:

sb_FanRotate.Begin(img_FanRotate, true);//如果只有一個動畫, img_FanRotate可以寫成this

後面一個true引數是讓動畫可控制。這樣子問題都解決了。

② 停止、暫停和恢復動畫

 有了上面對開始動畫的說明,停止、暫停和恢復動畫就很簡單了,全部可呼叫官方的函式,如下:

1 sb_FanRotate.Pause(img_FanRotate); //暫停動畫
2 sb_FanRotate.Resume(img_FanRotate);//恢復動畫
3 sb_FanRotate.Stop(img_FanRotate);  //停止動畫

百度知道上有人提出類似的問題,只可惜這哥們被踩了15次,大家也真是狠。這哥們其實挺冤的,不是Stop方法有問題,而是那些踩的人用的Begin方法不正確,在這裡給這位哥們平個冤,希望過兩天能收到他的感謝信。

圖3 百度知道停止動畫

③ 控制動畫速度

這個也很容易,官方有自帶的方法,如下:

sb_FanRotate.SetSpeedRatio(img_FanRotate, fanMeasure.FanSpeed1 / 2000);

總結

平時碰到問題,大家可百度,但是百度不到了,不要灰心,我們還可以查MSDN,或者是Google。另:本人初學WPF,如上文中有理解不當之處,敬請指正,定虛心接受。若言語有所不妥,還請諒解。程式碼取自專案,故原始碼不能分享,請見諒!