开发者

Synchronous / blocking animations in WPF?

I desperately need synchronous / blocking Animations in C# / WPF (executing code in the completed event is unfortunately not enough in my case).

I tried two ways:

1) Start the (asynchronous) animation using BeginAnimation with a Duration of x. Add Thread.Sleep(x) after the asynchronous call. However this doesn't work, the Animation is started AFTER the thread has slept for the given duration.

2) Using signals (AutoResetEvent class): Start the animation in another thread, the animations completed event signals that the animation was completed using a signal. Result: Code is never executed, whole thread is blocked, no animation shown / started, though the locked code starts after the BeginAnimation call. Maybe I'm using the signal in a wrong way? (I never used them before). (Idea based on this thread: WPF: Returning a method AFTER an animation has completed)

You can find a sample project at http://cid-0432ee4cfe9c26a0.office.live.com/self.aspx/%C3%96ffentlich/BlockingAnimation.zip

Thank you very much for any help!

BTW here's the plain code:

Method 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";

Method 2:

messageLogTB.Clear();

TranslateTransform tr开发者_Python百科anslateTransform = 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";


Stop making it complex with threading. Use Animation's Completed event instead to chain multiple animations in a single sequence or execute some code in Completed event.


The trick is to run the animation on a separate UI thread (this means setting up a message loop for this thread and remembering to tear it down when you're done with it).

I've just posted a blog post describing how I did this.


You might want to post the context of what you are trying to accomplish because what you are describing is impossible in WPF. The animations run on the UI thread, and if you block UI thread, the animation does not happen.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜