Синхронная / блокирующая анимация в WPF? - PullRequest
2 голосов
/ 06 августа 2010

Мне отчаянно нужны синхронные / блокирующие анимации в C # / WPF (выполнение кода в завершенном событии, к сожалению, недостаточно в моем случае).

Я пробовал два способа:

1) Запуск(асинхронная) анимация с использованием BeginAnimation с длительностью х.Добавьте Thread.Sleep (x) после асинхронного вызова.Однако это не работает, анимация запускается ПОСЛЕ того, как поток спал в течение заданной продолжительности.

2) Использование сигналов ( AutoResetEvent класс): Запустите анимацию в другом потоке,Завершенные анимации сигнализируют о том, что анимация была завершена с использованием сигнала.Результат: код никогда не выполняется, весь поток блокируется, анимация не отображается / не запускается, хотя заблокированный код запускается после вызова BeginAnimation.Может я неправильно использую сигнал?(Я никогда не использовал их раньше).(Идея основана на этой теме: WPF: возврат метода ПОСЛЕ анимации завершен )

Пример проекта можно найти по адресу http://cid -0432ee4cfe9c26a0.office.live.com / self.aspx /% C3% 96ffentlich / BlockingAnimation.zip

Большое спасибо за любую помощь!

Кстати, вот простой код:

Метод1:

messageLogTB.Clear();

TranslateTransform translateTransform = new TranslateTransform();
animatedButton.RenderTransform = translateTransform;

DoubleAnimation animation = new DoubleAnimation(0, 200.0, new Duration(TimeSpan.FromMilliseconds(2000)));
translateTransform.BeginAnimation(TranslateTransform.XProperty, animation);

// Animation is asynchronous and takes 2 seconds, so lets wait two seconds here
// (doesn't work, animation is started AFTER the 2 seconds!)
Thread.Sleep(2000);
messageLogTB.Text += "animation complete";

Метод 2:

messageLogTB.Clear();

TranslateTransform translateTransform = new TranslateTransform();
animatedButton.RenderTransform = translateTransform;

AutoResetEvent trigger = new AutoResetEvent(false);

// Create the animation, sets the signaled state in its animation completed event
DoubleAnimation animation = new DoubleAnimation(0, 200.0, new Duration(TimeSpan.FromMilliseconds(2000)));
animation.Completed += delegate(object source, EventArgs args) 
    {
        trigger.Set();
        messageLogTB.Text += "\nsignaled / animation complete";
    };


// Start the animation on the dispatcher
messageLogTB.Text += "starting animation";

Dispatcher.Invoke(
new Action(
    delegate()
    {
        translateTransform.BeginAnimation(TranslateTransform.XProperty, animation);
    }
), null);

// Wait for the animation to complete (actually it hangs before even starting the animation...)
trigger.WaitOne();
messageLogTB.Text += "\nThis should be reached after the signal / animation";

Ответы [ 3 ]

2 голосов
/ 06 августа 2010

Хватит усложнять работу с потоками.Вместо этого используйте событие Completed анимации, чтобы объединить несколько анимаций в одну последовательность или выполнить некоторый код в событии Completed.

1 голос
/ 09 февраля 2012

Хитрость заключается в том, чтобы запустить анимацию в отдельном потоке пользовательского интерфейса (это означает создание цикла сообщений для этого потока и не забудьте разорвать его, когда закончите с ним).

Я только что опубликовал сообщение в блоге , описывающее, как я это сделал.

0 голосов
/ 08 августа 2010

Возможно, вы захотите опубликовать контекст того, что вы пытаетесь выполнить, потому что то, что вы описываете, невозможно в WPF. Анимации выполняются в потоке пользовательского интерфейса, и если вы блокируете поток пользовательского интерфейса, анимация не происходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...