I have something like this:
barProgress.BeginAnimation(RangeBase.ValueProperty, new DoubleAnimation(
barProgress.Value, dNextProgressValue,
new Duration(TimeSpan.FromSeconds(dDuration)));
Now, how would you stop that animation (the DoubleAnimation)? The reason I want to do this, is because I would like to start new animations (this seems to work, but it's hard to tell) and eventually stop the last animation...
To stop it, call BeginAnimation again with the second argument set to null.
When using storyboards to control an animation, make sure you set the second parameter to true in order to set the animation as controllable:
public void Begin(
FrameworkContentElement containingObject,
**bool isControllable**
)
There are two ways to stop a BeginAnimation. The first is to call BeginAnimation again with the second parameter set to null. This will remove all animations on the property and revert the value back to its base value.
Depending on how you are using that value this may not be the behavior you want. The second way is to set the animations BeginTime to null then call BeginAnimation with it. This will remove that specific animation and leave the value at its current position.
DoubleAnimation myAnimation = new Animation();
// Initialize animation
...
// To start
element.BeginAnimation(Property, myAnimation);
// To stop and keep the current value of the animated property
myAnimation.BeginTime = null;
element.BeginAnimation(Property, myAnimation);
<Trigger.EnterActions>
<BeginStoryboard x:Name="myStory">
.........
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="myStory"/>
</Trigger.ExitActions>
In my case I had to use two commands, my xaml has a button which fires a trigger, and its trigger fires the storyboard animation.
I've put a button to stop animation with this code behind:
MyBeginStoryboard.Storyboard.Begin(this, true);
MyBeginStoryboard.Storyboard.Stop(this);
I don't like it but it really works here. Give it a try!
If you want the base value to become
the effective value again, you must
stop the animation from influencing
the property. There are three ways to
do this with storyboard animations:
Set the animation's FillBehavior
property to Stop
Remove the entire Storyboard
Remove the animation from the
individual property
From MSDN
How to: Set a Property After Animating It with a Storyboard
Place the animation in a StoryBoard. Call Begin() and Stop() on the storyboard to start to stop the animations.
You can use this code:
[StoryBoardName].Remove([StoryBoardOwnerControl]);
Related
What is my actual problem?
I want to stop Storyboard animation but keep current value of animated properties and unfreeze those properties.
What I have tried?
I tried storyboard.Pause() but this will keep the animated properties frozen. (changing values has no effect) I want to be able to release all properties from storyboard.
storyboard.Stop() doesn't work because it either sets value of animated properties to end or start of the animation depending on the FillBehavior. Although it will unfreeze the properties.
I tried clearing storyboard.Childern but it throws exception unless storyboard is fully stopped.
I tried to make new storyboard with duration 0 with same animations, this will stop previous animations and storyboard it self will finish in no time, but here are the problems
I should know what animations were added in last storyboard (I already solved this by storing dependency objects with property path in a List)
I have to retrieve current value of animated properties from property path.
I am stuck at the last one because this does not exist in UWP
string propertyPath = "(UIElement.Projection).(PlaneProjection.RotationY)";
// all animated properties are double
double value = (double)dependencyObject.GetValue(???);
GetValue requires DependencyProperty but i have a string.
Note: I just want a solution to my actual problem (top of this post).
I was able to solve this problem using following timeline
new DoubleAnimation { By = 0, Duration = TimeSpan.Zero }
With this timeline i don't have to know value of the properties. new storyboard on same elements and same property path's with duration 0 with this timeline will stop previous storyboard and keep their values. the new storyboard will also stop in no time and unfreeze the animated properties.
So I searched for a solution and I didn't find something...
I have an application that use Storyboard for animations, and a button that create the animation and start it. looks like this:
DoubleAnimation animation = new DoubleAnimation
{
//properties
};
sb = new Storyboard();//sb is the Storyboard
sb.Children.Add(animation);
Storyboard.SetTargetName(animation, myControl.Name);
Storyboard.SetTargetProperty(animation, new PropertyPath(Canvas.TopProperty));
sb.Begin(this);
The problem is that when I click the button while the animation still running, it restart the animation, and I want it to "add it to the order" so when the animation finished it starts again over and over, the amount of times I clicked the button.
Instead of trying to change a storyboard that's already running I suggest you instead use just a list of animations.
Or storyboards if you need some functionality in storyboard like animating several things at once.
You can then add them to a list ( or queue even ).
Subscribe to the completed event of each.
Keep a currentIndex pointer so you know which one is running.
When the completed event is hit, unhook your event handler from the one just finished, hook the next one. Begin the next storyboard.
I have a SpriteVisual for which I'm animating opacity, offset, and size using KeyFrameAnimations. While the animation is running the property values seem to be unaffected: they show the initial values until the animation finishes, at which point they update to the final values.
I would like to be able to get the current value part-way through the animation without having to either stop the animation to synchronise the properties or to store a separate copy of the animation and the time it started in order to calculate the value myself.
Is this possible?
As far as I known, it is impossible.
When we use the StartAnimation method of the SpriteVisual class to add the KeyFrameAnimation to it and start the animation, that there is no method to get the current value.
We can use the KeyFrameAnimation and the SpriteVisual to change the value of the property during the animation.There is an ForegroundFocusEffects sample that you can refer it, it uses the ScalarKeyFrameAnimation and set the Duration of the animation.
I'm messing around with making a clock in silverlight. I am trying to set up the animation code programmatically because I want to reuse the same code for each of the 3 clock hands (and I don't think I can do this with a single storyboard in xaml).
public void Rotate(double toAngle, RotateTransform rotate)
{
Storyboard sb = new Storyboard();
DoubleAnimationUsingKeyFrames keyframes = new DoubleAnimationUsingKeyFrames();
EasingDoubleKeyFrame easingStart = new EasingDoubleKeyFrame();
easingStart.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0));
easingStart.Value = rotate.Angle;
EasingDoubleKeyFrame easingEnd = new EasingDoubleKeyFrame();
easingEnd.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.5));
easingEnd.Value = toAngle;
var ease = new ElasticEase();
ease.EasingMode = EasingMode.EaseIn;
easingEnd.EasingFunction = ease;
keyframes.KeyFrames.Add(easingStart);
keyframes.KeyFrames.Add(easingEnd);
Storyboard.SetTarget(keyframes, rotate);
Storyboard.SetTargetProperty(keyframes, new PropertyPath("(RotateTransform.Angle)"));
sb.Children.Add(keyframes);
sb.Begin();
}
I pass in both the angle I want the current hand to rotate to and the rotate transform for that hand. From this rotate transform I get the starting angle.
When I run the clock, the clock hands move (the second hand moves to the correct spot each second etc) but the animations don't appear to actually animate. They just go from start to end instantly.
Why does the animation not happen properly?
The skipping problem is likely the lag in starting a storyboard that wants to show changes in less than a second. By the time the storyboard gets itself ready to display it basically says "oh... it's after 1 second now, where should I be now". You are better off with longer storyboards.
I'm not sure how much control you are wanting over your clock, but regarding using a single storyboard, here goes...
I was not sure of the overall problem you are trying to solve, but the following example uses one simple storyboard to run the 3 hands of a clock. The only problem I had was that the maximum time interval I could specify for the hour hand (in XAML), without a parsing error, is 23:59:59.
<Storyboard x:Name="SecondHandStoryboard" RepeatBehavior="Forever">
<DoubleAnimation Duration="0:1:0" To="360" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="SecondHand" />
<DoubleAnimation Duration="1:0:0" To="360" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="MinuteHand"/>
<DoubleAnimation Duration="23:59:59" To="360" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="HourHand"/>
</Storyboard>
I actually wanted to add a solid "tick" animation to the second hand, but have not figured out how to get rotation "by" storyboards to work. Basically use a repeated 6 degree per-second 1-second long storyboard with steep easing-in (will keep looking into that problem).
Anyway, hope this is of help to you.
I am using animations with my window to slide out or slide back up.
But when these animations are not used.
I would like to use Window.Top to set the position of the window,
but I think due to animations I cannot set the top.
I was wondering if anyone knows how to fix this? Thanks
example.
window.top is already = 33.
but when is ay
window.top =900;
it will stay at 33.
Manual value changes are ignored while an animation is running. You need to remove the animation from the property entirely to make the manually-set values visible.
If you started your animation with a BeginStoryboard action, use a RemoveStoryboard action to remove it:
<RemoveStoryboard BeginStoryboardName="NameOfStoryboard" />
If you applied your animation in code or otherwise, the trick is to pass "null" into the BeginAnimation method to remove it:
window.BeginAnimation(Window.TopProperty, null);
In many cases you can call a Storyboard's Remove method to reset the value source from an animation back to the original source, in this case your explicit value. If you could post some code it would be easier to get a more definitive answer.
Try setting FillBehavior="Stop" in your animation.