tags:

views:

316

answers:

1

How can I remove a running animation from a WPF element in such a way that its Completed event does not fire?

The solutions presented here and here remove the animation's visible effects, but the Completed event still fires at the time that the animation would have completed.

Here's some code that demonstrates my problem (it's in the code behind of a Window with a Label, a Button, and a TextBox):

    int _count = 0;

    private void button1_Click(object sender, RoutedEventArgs e) {
        myLabel.Content = "Starting animation: " + _count++;

        // Cancel any already-running animations and return
        // the label opacity to 1.0.
        myLabel.BeginAnimation(Label.OpacityProperty, null);
        myLabel.Opacity = 1.0;

        // Create a new animation to fade out the label.
        DoubleAnimation opacityAnim = new DoubleAnimation(1.0, 0.0, TimeSpan.FromSeconds(2), FillBehavior.Stop) {
            BeginTime = TimeSpan.FromSeconds(3)
        };
        opacityAnim.Completed += (sndr, ev) => {
            myTextbox.Text += Environment.NewLine + "Completed fired.";
        };

        // Start the countdown/animation.
        myLabel.BeginAnimation(Label.OpacityProperty, opacityAnim);
    }

How can I remove an animation such that it will not raise its Completed event?

+3  A: 

Unsubscribe from Completed event... That also means you have to rewrite Completed event handler from lambda to explicit method:

   DoubleAnimation _opacityAnim; // Created somewhere else.

   private void button1_Click(object sender, RoutedEventArgs e) 
   {
    myLabel.Content = "Starting animation: " + _count++;

    // Cancel any already-running animations and return
    // the label opacity to 1.0.
    _opacityAnim.Completed -= AnimationCompleted;

    myLabel.BeginAnimation(Label.OpacityProperty, null);
    myLabel.Opacity = 1.0;

    // Create a new animation to fade out the label.
    opacityAnim.Completed += AnimationCompleted;

    // Start the countdown/animation.
    myLabel.BeginAnimation(Label.OpacityProperty, opacityAnim);
}

 private void AnimationCompleted(object sender, EventArgs e)
 {
        myTextbox.Text += Environment.NewLine + "Completed fired.";
 }
Anvaka
Fascinating...I'd thought of this before but figured it would still fire the event because you add a handler back right away, and it's the same animation object. However, upon actually testing it (novel concept, that) I find that it works as desired! (Might you be able to point me to an explanation of why this is?) A little counterintuitive to read in code, but I'm pleased that it works. Thanks!
Matt Winckler