У меня есть приложение 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();
}
EDIT (добавлена дополнительная информация)
Сначала я столкнулся с этим, потому что вызывал этот метод из другого метода (поскольку он обрабатывал элементыон сделал вызов анимации).Я заметил, что предметы не оказались там, где я ожидал.Новые координаты X / Y, которые я передаю, основаны на текущем местоположении элементов, поэтому, если они вызывались несколько раз до завершения, они оказались в неправильном месте.В качестве теста я добавил кнопку, которая запускала анимацию только один раз.Это сработало.Однако, если я нажимаю на кнопку несколько раз подряд, я вижу то же поведение, что и раньше: элементы оказываются в неправильном месте.
Да, похоже, анимации Silverlight запускаются в основном потоке пользовательского интерфейса,В одном из тестов, которые я попробовал, я добавил два свойства, которые отмечали, завершены ли обе анимации.В методе 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));
}
}
Затем я вызываю свою начальную процедуру (которая ставит в очередь анимации) и вызываю этот метод в новом потоке.Я вижу те же результаты.