我有一個Silverlight應用程序。有一個矩形動畫到一個新位置的基本動畫。動畫由兩個DoubleAnimation()組成 - 一個轉換X,另一個轉換Y.它工作正常。如何在動畫完成之前阻止對方法的訪問
我基本上想阻止任何其他調用這個動畫方法,直到前兩個動畫完成。我看到DoubleAnimation()類具有一個Completed事件,但我沒有成功構建任何類型的代碼,直到兩者都完成,才成功阻塞。
我試圖在輸入方法時使用私有成員上的Monitor.Enter,然後釋放一個動畫Completed事件中的鎖,但我試圖鏈接兩個事件(所以直到兩個已經完成)沒有成功。
這裏的動畫方法是什麼樣子:
public void AnimateRectangle(Rectangle rect, double newX, double newY)
{
var xIsComplete = false;
Duration duration = new Duration(new TimeSpan(0, 0, 0, 1, 350));
var easing = new ElasticEase() { EasingMode = EasingMode.EaseOut, Oscillations = 1, Springiness = 4 };
var animateX = new DoubleAnimation();
var animateY = new DoubleAnimation();
animateX.EasingFunction = easing;
animateX.Duration = duration;
animateY.EasingFunction = easing;
animateY.Duration = duration;
var sb = new Storyboard();
sb.Duration = duration;
sb.Children.Add(animateX);
sb.Children.Add(animateY);
Storyboard.SetTarget(animateX, rect);
Storyboard.SetTargetProperty(animateX, new PropertyPath("(Canvas.Left)"));
Storyboard.SetTarget(animateY, rect);
Storyboard.SetTargetProperty(animateY, new PropertyPath("(Canvas.Top)"));
animateX.To = newX;
animateY.To = newY;
sb.Begin();
}
編輯(添加詳細信息)
我最初遇到了這一點,因爲我打電話從其他方法這個方法(因爲它處理它製成的物品對動畫的調用)。我注意到,這些項目沒有結束,我預期他們會。我傳入的新X/Y座標是基於當前位置的項目,因此如果在完成之前多次調用該X/Y座標,則會導致錯誤的位置。作爲一項測試,我添加了一個只運行一次動畫的按鈕。有效。但是,如果我連續點擊一次按鈕,就會看到與之前相同的行爲:項目最終位於錯誤的位置。
是的,看起來Silverlight動畫是在主UI線程上運行的。我嘗試過的一個測試是添加了兩個屬性,標記了兩個動畫是否都已完成。在AnimateRectange()方法中,我在一個while循環中調用了它們(調用Thread.Sleep)。這個循環從未完成(所以它絕對在同一個線程上)。
所以我創建了一個隊列來處理動畫順序:
private void ProcessAnimationQueue()
{
var items = this.m_animationQueue.GetEnumerator();
while (items.MoveNext())
{
while (this.m_isXanimationInProgress || this.m_isYanimationInProgress)
{
System.Threading.Thread.Sleep(100);
}
var item = items.Current;
Dispatcher.BeginInvoke(() => this.AnimateRectangle(item.Rect.Rect, item.X, item.Y));
}
}
然後,我打電話給我的最初的程序(其中排隊的動畫),並調用此方法在一個新線程。我看到了相同的結果。