我迫切需要在C#/ WPF中使用同步/阻塞动画(在我的情况下,在已完成的事件中执行代码是不够的。)
我尝试了两种方法:
1)使用持续时间为x的BeginAnimation启动(异步)动画。 异步调用后添加Thread.Sleep(x)。但是这不起作用,动画在线程睡眠达到给定的持续时间后启动。
2)使用信号(AutoResetEvent class):在另一个线程中启动动画,动画完成事件表示使用信号完成动画。结果:代码永远不会执行,整个线程被阻止,没有动画显示/启动,但锁定的代码在BeginAnimation调用后启动。也许我以错误的方式使用信号? (我之前从未使用过它们)。 (基于这个主题的想法:WPF: Returning a method AFTER an animation has completed)
您可以在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";
答案 0 :(得分:2)
使用线程停止使其复杂化。使用动画的Completed
事件代替在单个序列中链接多个动画或在Completed
事件中执行一些代码。
答案 1 :(得分:1)
诀窍是在单独的UI线程上运行动画(这意味着为此线程设置一个消息循环,并记住在完成它时将其拆除)。
我刚刚发布了blog post来描述我是如何做到这一点的。
答案 2 :(得分:0)
您可能希望发布您要完成的内容的上下文,因为您在WPF中无法描述的内容。动画在UI线程上运行,如果你阻止UI线程,动画就不会发生。