2

This seems like it should be a no-brainer, but I can't get a WPF storyboard to pause. I call Pause and nothing happens -- it keeps right on animating.

Here's a repro case: a button that animates its width. If you click the button, it calls Pause on the storyboard. I would expect that, as soon as I click the button, its width should stop changing; instead its width keeps right on animating as if I never called Pause.

NameScope.SetNameScope(this, new NameScope());
var storyboard = new Storyboard();

var button = new Button { Content = "Pause", Name = "pause" };
this.Content = button;
RegisterName(button.Name, button);
var animation = new DoubleAnimation(0, 200, TimeSpan.FromSeconds(5));
Storyboard.SetTargetName(animation, button.Name);
Storyboard.SetTargetProperty(animation,
    new PropertyPath(FrameworkElement.WidthProperty));
storyboard.Children.Add(animation);

button.Click += (sender, e) => { storyboard.Pause(this); };
storyboard.Begin(this);

From what I understand of the docs, I should call the Pause(FrameworkElement) overload with the same parameter I passed to Begin, hence the Pause(this) above. But I've also tried storyboard.Pause(), with no change in behavior. I also tried storyboard.Pause(button) just for the heck of it, again with no effect. I would have tried storyboard.Pause(storyboard) and storyboard.Pause(animation) just to exhaust the possibilities, but neither one compiles -- it wants a FrameworkElement (or FrameworkContentElement).

How do I get the storyboad to pause?

Joe White
  • 94,807
  • 60
  • 220
  • 330

1 Answers1

4

I don't know why you are using that weired SetNameScope etc. Clearing your code i could make it work:

        //NameScope.SetNameScope(this, new NameScope());
        var storyboard = new Storyboard();

        var button = new Button { Content = "Pause", Name = "pause" };
        this.Content = button;
        //RegisterName(button.Name, button);
        var animation = new DoubleAnimation(0, 200, TimeSpan.FromSeconds(5));
        Storyboard.SetTarget(animation, button);
        Storyboard.SetTargetProperty(animation,
            new PropertyPath(FrameworkElement.WidthProperty));
        storyboard.Children.Add(animation);

        button.Click += (sender, e) => { storyboard.Pause(); };
        storyboard.Begin();
Elad Katz
  • 7,483
  • 5
  • 35
  • 66
  • Huh. The MSDN docs insist that you *must* set a name scope, but your version is (a) simpler and (b) works. I'll take it. – Joe White Mar 15 '11 at 00:52
  • I have to say I'm a little baffled.. I've been programming WPF for 5 years now, and that's the first time I've ever seen the usage of NameScope & RegisterName... :-/ – Elad Katz Mar 15 '11 at 00:55
  • Looks like the magic combination of code changes is to (a) use SetTarget instead of SetTargetName, and (b) use the parameterless `Begin` and `Pause` instead of passing `this`. The NameScope is harmless, though unnecessary when using SetTarget. – Joe White Mar 15 '11 at 00:57
  • yeah, well... i just removed everything i never use and it worked ;-) – Elad Katz Mar 15 '11 at 00:59
  • The docs that insist on NameScope / RegisterName are here: "Storyboards Overview" http://msdn.microsoft.com/en-us/library/ms742868.aspx. I don't know why they say that -- I like your version a lot better. – Joe White Mar 15 '11 at 00:59
  • [Here's a question](http://stackoverflow.com/questions/13217221/settarget-vs-registername-settargetname) which illustrates a case where `SetTarget` doesn't work and the `RegisterName`/`SetTargetName` combo is necessary. – dharmatech Nov 05 '12 at 07:35