I'd like to fade in a drop shadow effect on a DataGrid over 2 seconds, which fades out over 2 seconds again after the fade-in animation is completed.
My code so far:
DropShadowEffect dropShadowEffect = new DropShadowEffect();
dropShadowEffect.ShadowDepth = 0;
dropShadowEffect.Color = Colors.LightSeaGreen;
dropShadowEffect.Opacity = 0;
dropShadowEffect.BlurRadius = 20;
element.Effect = dropShadowEffect;
Storyboard storyboard1 = new Storyboard();
TimeSpan duration1 = TimeSpan.FromMilliseconds(2000);
DoubleAnimation animateOpacity1 = new DoubleAnimation() { From = 0, To = 1, Duration = new Duration(duration1) };
Storyboard.SetTargetName(animateOpacity1, element.Name);
Storyboard.SetTargetProperty(animateOpacity1, new PropertyPath(DropShadowEffect.OpacityProperty));
DoubleAnimation animateOpacity2 = new DoubleAnimation() { From = 1, To = 0, Duration = new Duration(duration1) };
Storyboard.SetTargetName(animateOpacity2, element.Name);
Storyboard.SetTargetProperty(animateOpacity2, new PropertyPath(DropShadowEffect.OpacityProperty));
storyboard1.Children.Add(animateOpacity1);
storyboard1.Children.Add(animateOpacity2);
storyboard1.Begin(element);
Upon executing the code, nothing happens.
If you simply want to do DoubleAnimation, no need to complex it using StoryBoard. Also, you can achieve this with only single double animation with property AutoReverse set to true.
Moreover, do animation on dropShadowEffect object instead of element object.
TimeSpan duration = TimeSpan.FromMilliseconds(2000);
DoubleAnimation animateOpacity = new DoubleAnimation() { From = 0, To = 1,
Duration = duration, AutoReverse = true };
dropShadowEffect.BeginAnimation(DropShadowEffect.OpacityProperty,
animateOpacity);
Related
This is my code to do animation (change opacity) for one ui element.
var animation = new DoubleAnimation
{
To = 0.0,
Duration = TimeSpan.FromSeconds(5),
FillBehavior = FillBehavior.HoldEnd
};
Storyboard story = new Storyboard();
Storyboard.SetTarget(animation, element1);
Storyboard.SetTargetProperty(animation, "Opacity");
story.Children.Add(animation);
story.Begin();
It works, for some reason I need to it only programmatically. The problem is I need to animate several controls at once. Is there any solution for several controls?
You would have to define several animations for this controls.
var animation1 = new DoubleAnimation
{
To = 0.0,
Duration = TimeSpan.FromSeconds(5),
FillBehavior = FillBehavior.HoldEnd
};
var animation2 = new DoubleAnimation
{
To = 0.0,
Duration = TimeSpan.FromSeconds(5),
FillBehavior = FillBehavior.HoldEnd
};
Storyboard.SetTarget(animation1, element1);
Storyboard.SetTargetProperty(animation1, "Opacity");
Storyboard.SetTarget(animation2, element2);
Storyboard.SetTargetProperty(animation2, "Opacity");
Storyboard story = new Storyboard();
story.Children.Add(animation1);
story.Children.Add(animation2);
story.Begin();
I am creating a flashing animation for a Text Block in WPF in the code behind. I know that the text block as the opacity property, yet this code cannot seem to find it. What am I doing wrong?
DoubleAnimation da = new DoubleAnimation
{
From = 1,
To = 0,
Duration = new Duration(TimeSpan.FromSeconds(0.5)),
AutoReverse = true,
RepeatBehavior = RepeatBehavior.Forever
};
myTextBlock.BeginAnimation(Opacity, da);
In addition, I am trying to create a color animation. That doesn't seem to be working either:
ColorAnimation ca = new ColorAnimation
{
From = Colors.Red,
To = Colors.Black,
Duration = new Duration(TimeSpan.FromSeconds(1)),
AutoReverse = true,
RepeatBehavior = RepeatBehavior.Forever
};
myTextBlock.Background.BeginAnimation(SolidColorBrush.ColorProperty, ca);
Animation is applied to Property, not to Field. Also it seem you use parent's Opacity, not the TextBlock.
Change Opacity to UIElement.OpacityProperty:
DoubleAnimation da = new DoubleAnimation
{
From = 1,
To = 0,
Duration = new Duration(TimeSpan.FromSeconds(0.5)),
AutoReverse = true,
RepeatBehavior = RepeatBehavior.Forever
};
myTextBlock.BeginAnimation(UIElement.OpacityProperty, da);
Storyboard sboard = new Storyboard();
DoubleAnimation da = new DoubleAnimation
{
From = 1,
To = 0,
AutoReverse = true,
RepeatBehavior = RepeatBehavior.Forever
};
Storyboard.SetTarget(da, urButton);
Storyboard.SetTargetProperty(animation, new PropertyPath((object)UIElement.OpacityProperty));
sboard.Children.Add(animation);
sboard.Start()
Your code works for me. Did you set the background color to red, first? If not try setting the background color to red.
What I'm trying to do is make my control "pulse" (as in enlarge a bit, then shrink a bit, then back to its normal size). The following code does exactly what I want, but it just seems like there should be a simpler way. It has to be done in code behind because this is an abstract class that most of our controls derive from. I don't have much experience with animation controls and story boards.
So specifically my question is, is there a simpler way to get the desired results than the following method (while still being done in the code-behind)?
public void Pulse()
{
var storyboard = new Storyboard
{
FillBehavior = FillBehavior.Stop,
RepeatBehavior = new RepeatBehavior(2)
};
double timeIncrement = .15;
double changePercent = 20;
var firstTime = TimeSpan.FromSeconds(timeIncrement);
var secondTime = TimeSpan.FromSeconds(timeIncrement * 3);
var thirdTime = TimeSpan.FromSeconds(timeIncrement * 4);
var scale = new ScaleTransform(1.0, 1.0);
RenderTransformOrigin = new Point(.5, .5);
RenderTransform = scale;
//enlarge
{
DoubleAnimation growX = new DoubleAnimation
{
Duration = firstTime,
To = 1 + changePercent
};
storyboard.Children.Add(growX);
Storyboard.SetTargetProperty(growX, new PropertyPath("RenderTransform.ScaleX"));
DoubleAnimation growY = new DoubleAnimation
{
Duration = firstTime,
To = 1 + changePercent
};
storyboard.Children.Add(growY);
Storyboard.SetTargetProperty(growY, new PropertyPath("RenderTransform.ScaleY"));
}
//shrink
{
DoubleAnimation shrinkX = new DoubleAnimation
{
Duration = secondTime,
To = 1 - changePercent
};
storyboard.Children.Add(shrinkX);
Storyboard.SetTargetProperty(shrinkX, new PropertyPath("RenderTransform.ScaleX"));
DoubleAnimation shrinkY = new DoubleAnimation
{
Duration = secondTime,
To = 1 - changePercent
};
storyboard.Children.Add(shrinkY);
Storyboard.SetTargetProperty(shrinkY, new PropertyPath("RenderTransform.ScaleY"));
}
//back to normal
{
DoubleAnimation normX = new DoubleAnimation
{
Duration = thirdTime,
To = 1
};
storyboard.Children.Add(normX);
Storyboard.SetTargetProperty(normX, new PropertyPath("RenderTransform.ScaleX"));
DoubleAnimation normY = new DoubleAnimation
{
Duration = thirdTime,
To = 1
};
storyboard.Children.Add(normY);
Storyboard.SetTargetProperty(normY, new PropertyPath("RenderTransform.ScaleY"));
}
BeginStoryboard(storyboard, HandoffBehavior.SnapshotAndReplace, false);
}
You could perhaps simplify things a little by moving your grow/shrink logic into its own method. This reduces duplication and provides a potentially more reusable code kibble.
public void Pulse()
{
var storyboard = new Storyboard
{
FillBehavior = FillBehavior.Stop,
RepeatBehavior = new RepeatBehavior(2)
};
double timeIncrement = .15;
double growPercent = 20;
double shrinkPercent = -20;
var firstTime = TimeSpan.FromSeconds(timeIncrement);
var secondTime = TimeSpan.FromSeconds(timeIncrement * 3);
var thirdTime = TimeSpan.FromSeconds(timeIncrement * 4);
var scale = new ScaleTransform(1.0, 1.0);
RenderTransformOrigin = new Point(.5, .5);
RenderTransform = scale;
storyboard = AddSizeChange(firstTime, growPercent, storyboard);
storyboard = AddSizeChange(secondTime, shrinkPercent, storyboard);
storyboard = AddSizeChange(thirdTime, growPercent, storyboard);
BeginStoryboard(storyboard, HandoffBehavior.SnapshotAndReplace, false);
}
public Storyboard AddSizeChange(TimeSpan animTime, double changePercent, Storyboard storyboard)
{
DoubleAnimation growX = new DoubleAnimation
{
Duration = animTime,
To = 1 + changePercent
};
storyboard.Children.Add(growX);
Storyboard.SetTargetProperty(growX, new PropertyPath("RenderTransform.ScaleX"));
DoubleAnimation growY = new DoubleAnimation
{
Duration = animTime,
To = 1 + changePercent
};
storyboard.Children.Add(growY);
Storyboard.SetTargetProperty(growY, new PropertyPath("RenderTransform.ScaleY"));
return storyboard;
}
That's a fine way of doing it, WPF does not provide methods or events to automatically pulse. Yours is simple and as you've created it, you know how to modify it as you wish.
Why below code doesn't change ScaleY to 1?
var transform = new ScaleTransform { ScaleY = 0 };
var story = new Storyboard();
var animation = new DoubleAnimation {
Duration = new Duration(new TimeSpan(0)), To = 1 };
Storyboard.SetTarget(animation, transform);
Storyboard.SetTargetProperty(animation, new PropertyPath("ScaleY"));
story.Children.Add(animation);
story.Begin();
I use transform indirectly: it use for render some UIElements and kept in their DependencyProperty.
Does it perhaps work if you drop the Storyboard and just call BeginAnimation directly?
var transform = new ScaleTransform { ScaleY = 0 };
var animation = new DoubleAnimation { Duration = TimeSpan.Zero, To = 1 };
transform.BeginAnimation(ScaleTransform.ScalyYProperty, animation);
Note that this will only have any effect if the animation's FillBehavior has a value of HoldEnd. Otherwise the animated property will immediately revert back to its local value (which is 0 here). Fortunately HoldEnd is the default value for FillBehavior.
And of course the transform should be used somewhere.
I would like to use it, but it doesnt't work, I wanna create a tile animation, in code behind, or if you know a project for this gol, pls write me
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
while(true){
Duration duration = new Duration(TimeSpan.FromSeconds(0.15));
// Create two DoubleAnimations and set their properties.
DoubleAnimation myDoubleAnimation1 = new DoubleAnimation();
myDoubleAnimation1.Duration = duration;
myDoubleAnimation1.From = -173
myDoubleAnimation1.To = 173;
Storyboard sb = new Storyboard();
sb.Duration = duration;
sb.Children.Add(myDoubleAnimation1);
Storyboard.SetTarget(myDoubleAnimation1, image);
// Set the attached properties of Canvas.Left and Canvas.Top
// to be the target properties of the two respective DoubleAnimations.
Storyboard.SetTargetProperty(myDoubleAnimation1, new PropertyPath(StackPanel.MarginProperty));
// Begin the animation.
sb.Begin();}
});
Here is the working example, if anybody needs:
//Animate margin for Label, named "label" from right to left. from 300 to 0.
var sb = new Storyboard();
var ta = new ThicknessAnimation();
ta.BeginTime = new TimeSpan(0);
ta.SetValue(Storyboard.TargetNameProperty, "label");
Storyboard.SetTargetProperty(ta, new PropertyPath(MarginProperty));
ta.From = new Thickness(300, 30, 0, 0);
ta.To = new Thickness(0, 30, 0, 0);
ta.Duration = new Duration(TimeSpan.FromSeconds(3));
sb.Children.Add(ta);
sb.Begin(this);
Use a ThicknessAnimation instead of a DoubleAnimation. It's almost the same.
Edit:
If you want to make the Animation endless use Timeline.RepeatBehavior.
myThicknessAnimation1.RepeatBehavior = RepeatBehavior.Forever;