I'm using the following animation to "flash" a control:
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="1"
To="0.3"
AutoReverse="True"
Duration="0:0:0.5"
RepeatBehavior="Forever" />
The resulting effect is more like a fade in and out. What I'm really after is to just "flip" the opacity from one value to the other (and back) every 0.5 seconds, rather than a smooth transition. How do I achieve that?
This is the solution you are looking for:
<Storyboard RepeatBehavior="Forever" Duration="0:0:0.5" AutoReverse="True">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity">
<DiscreteDoubleKeyFrame Value="0.3" KeyTime="0:0:0.25" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
You can adapt it to your needs.
Related
I am trying to play a bit with the badged control from Mahapps. Is it possible to change the size of the badge (not just the color/value/etc..)
Finally I am trying to do some sort of bigger pulse effect when the badge value changed, I tried the following for the color but it didn't work:
<Controls:Badged.Triggers>
<EventTrigger RoutedEvent="Controls:Badged.BadgeChanged">
<EventTrigger.EnterActions>
<BeginStoryboard Name="AnimateVisibilityChanged">
<Storyboard>
<ColorAnimation Duration="0:0:0.5"
From="#FFEE4709"
To="Green"
BeginTime="0:0:0"
Storyboard.TargetProperty="(Controls:Badged.BadgeBackground).(SolidColorBrush.Color)">
</ColorAnimation>
<ColorAnimation Duration="0:0:0.5"
From="Green"
To="Transparent"
AutoReverse="True"
BeginTime="0:0:2"
RepeatBehavior="0:0:2.5"
Storyboard.TargetProperty="(Controls:Badged.BadgeBackground).(SolidColorBrush.Color)">
</ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.EnterActions>
<EventTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="AnimateVisibilityChanged" />
</EventTrigger.ExitActions>
</EventTrigger>
</Controls:Badged.Triggers>
The next step if this would work is to also increase the size more than it's already increasing
It looks like I will answer to my question:
the animation didn't work because I used EnterActions instead of simply Actions (EventTrigger.Actions)
To change the size of the badge when the value changes I had to use BadgeChangedStoryboard property and replace with my own:
<SineEase x:Key="BadgeEase"
EasingMode="EaseOut" />
<Storyboard x:Key="BadgeChangedStoryboard">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0"
Value="2.3" />
<EasingDoubleKeyFrame EasingFunction="{StaticResource BadgeEase}"
KeyTime="0:0:0.3"
Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0"
Value="2.3" />
<EasingDoubleKeyFrame EasingFunction="{StaticResource BadgeEase}"
KeyTime="0:0:0.3"
Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
To change the size change both the easing double key frame Value
I have a textblock which should only show 2 lines of the text, while it is unselected. As soon as it gets selected, I want it to expand smoothly.
I started with something like:
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="Second"
Storyboard.TargetProperty="(TextBlock.MaxHeight)"
To="50.0" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
But the issue here is, that I don't know how big the text is.
You should be able to use From='0' instead, which would start the animation with a value of 0 and end with whatever the value of MaxHeight is. However, that raises a different problem, as MaxHeight defaults to infinity, which would make the animation far too fast. Adding an ObjectAnimationUsingKeyframes at the start that sets MaxHeight to ActualHeight might work to resolve this. Something like this:
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyframes
Storyboard.TargetName='Second'
Storyboard.TargetProperty='(TextBlock.MaxHeight)'>
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{Binding TargetName=Second, Path=ActualHeight}" />
</ObjectAnimationUsingKeyframes>
<DoubleAnimation
Storyboard.TargetName="Second"
Storyboard.TargetProperty="(TextBlock.MaxHeight)"
From="0" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
You can use DoubleAnimation to implement this. I have implemented this in a sample application.
<Window.Resources>
<Storyboard x:Key="OnGotFocus">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="textBox" Storyboard.TargetProperty="(FrameworkElement.Height)">
<EasingDoubleKeyFrame KeyTime="0:0:2">
<EasingDoubleKeyFrame.Value>
<System:Double>NaN</System:Double>
</EasingDoubleKeyFrame.Value>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OnLostFocus">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="textBox" Storyboard.TargetProperty="(FrameworkElement.Height)">
<EasingDoubleKeyFrame KeyTime="0">
<EasingDoubleKeyFrame.Value>
<System:Double>NaN</System:Double>
</EasingDoubleKeyFrame.Value>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="30" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="UIElement.GotFocus" SourceName="textBox">
<BeginStoryboard Storyboard="{StaticResource OnGotFocus}" />
</EventTrigger>
<EventTrigger RoutedEvent="UIElement.LostFocus" SourceName="textBox">
<BeginStoryboard x:Name="OnLostFocus_BeginStoryboard" Storyboard="{StaticResource OnLostFocus}" />
</EventTrigger>
</Window.Triggers>
Your code for textbox should be :
<TextBox x:Name="textBox"
Height="30"
HorizontalAlignment="Right"
Text="Hello World" />
This will animate the textbox to a specified height as soon as it gets focussed. I have added an animation to collapse it as well when it loses focus.
Hope this helps you.
Im new in WPF, please if somebody can give me some tips to do this:
I need to move some images from to left or right, like in a coverflow (carousel, i can't use component as Dev Express, i have to do it for myself). And i need that if i maximize the window the "carousel" expand too and keep relation between margins of the images.
I try it moving the images in a Canvas, but when i maximize the window the Canvas dont do it and keep little.. I read and understand that i can't do that with a Canvas, so i do it putting the images on grids and changing its margin property, its works but when i maximize, the margin still is the same that when images are little and the aspect ratio is loose.
So my question is, how can i change the margin too when i maximize the window?
My code to move images using margin is:
<Storyboard Name="FlowIzq">
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="Margin" Storyboard.TargetName="Image1" BeginTime="00:00:00">
<SplineThicknessKeyFrame KeyTime="00:00:00" Value="0,0,0,0"/>
<SplineThicknessKeyFrame KeyTime="00:00:0.5" Value="-157, 0,157,0"/>
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard.Storyboard>
I think i need to change the value of all SplineThicknessKeyFrame, but how i do that?
I hope explain it well and somebody can help me (sorry for my english) if something is not understood i explain it again.
Peace,
Rob.
4 years later I found myself needing a similar storyboard so I thought I'd share what I ended up with. Hopefully it helps someone else in 4 more years.
<Grid.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="1"
To="0"
Duration="0:0:1">
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="0"
To="1"
Duration="0:0:1"
BeginTime="0:0:1">
</DoubleAnimation>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="Margin" Duration="00:00:1">
<SplineThicknessKeyFrame KeyTime="00:00:1" Value="0,0,500,0" />
</ThicknessAnimationUsingKeyFrames>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="Margin" Duration="00:00:1">
<DiscreteThicknessKeyFrame KeyTime="00:00:1.0" Value="0,0,-550,0" />
</ThicknessAnimationUsingKeyFrames>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="Margin" Duration="00:00:1" BeginTime="0:0:1">
<SplineThicknessKeyFrame KeyTime="00:00:1.0" Value="0" />
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
Just replace Grid.Triggers with your Control.Triggers and the EventTrigger.RoutedEvent to the event that makes sense to you.
I would like to do a sequence of animations on a label, for example, first do opacity animations from values 0 to 1 and vice versa and just at the end of opacity animation and not before a foreground animation. I would like to do it in XAML code and then start and finish de animation from C# code. Which is the best and efficient way to do it?
All replies are welcome!
Thanks in advance.
The easiest way is to define the entire animation in a single storyboard with suitable BeginTime and Duration properties. This way the entire animation can be started and stopped as a unit, but you can have different sequences.
For example:
<Storyboard Duration="0:00:06">
<DoubleAnimation Duration="0:0:4" Storyboard.TargetName="gear1RotateTransform" Storyboard.TargetProperty="Angle" From="-600" To="0"/>
<DoubleAnimation Duration="0:0:4" Storyboard.TargetName="gear2RotateTransform" Storyboard.TargetProperty="Angle" From="600" To="0"/>
<DoubleAnimation Duration="0:0:4" Storyboard.TargetName="gear3RotateTransform" Storyboard.TargetProperty="Angle" From="-600" To="0"/>
<DoubleAnimation BeginTime="0:0:1" Duration="0:00:02" Storyboard.TargetName="firstLetter" Storyboard.TargetProperty="Opacity" From="0.0" To="1.0"/>
<DoubleAnimation BeginTime="0:0:2" Duration="0:00:02" Storyboard.TargetName="secondLetter" Storyboard.TargetProperty="Opacity" From="0.0" To="1.0"/>
<DoubleAnimation BeginTime="0:0:3" Duration="0:00:02" Storyboard.TargetName="thirdLetter" Storyboard.TargetProperty="Opacity" From="0.0" To="1.0"/>
<DoubleAnimation BeginTime="0:0:4" Duration="0:00:02" Storyboard.TargetName="siteLink" Storyboard.TargetProperty="Opacity" From="0.0" To="1.0"/>
<DoubleAnimation BeginTime="0:0:4" Duration="0:00:02" Storyboard.TargetName="siteLinkTop" Storyboard.TargetProperty="Opacity" From="0.0" To="1.0"/>
</Storyboard>
This storyboard changes the values on the 3 rotate transforms for the first 4 seconds, but the opacity on the firstLetter item doesn't start to change until after one second has passed and it only runs for 2 seconds. The siteLink and siteLinkTop elements don't have their opacity changed until after 4 seconds (and the gear rotation animation has finished).
In my current application I have this little animation. It makes a full 360 degrees rotation of a canvas and works fine.
<DoubleAnimation
Storyboard.TargetName="WaitCanvas"
Storyboard.TargetProperty="(Canvas.RenderTransform).(TransformGroup.Children)[0]
.(RotateTransform.Angle)"
From="0" To="360" Duration="0:0:2"
AutoReverse="False" RepeatBehavior="Forever" />
But the thing I want to do is not a smooth animation but animation is steps of 22.5 degrees each. How can this be done?
You could use a DoubleAnimationUsingKeyFrames and make two keyframes for each increment of 22.5 degrees at the same point in time.
Adding the XAML example which I was actually searching for.
<Storyboard
BeginTime="00:00:00"
RepeatBehavior="Forever"
Storyboard.TargetName="WaitCanvas"
Storyboard.TargetProperty="(Canvas.RenderTransform).(TransformGroup.Children)[0].(RotateTransform.Angle)">
<DoubleAnimationUsingKeyFrames Duration="0:0:2">
<DoubleKeyFrameCollection>
<DiscreteDoubleKeyFrame KeyTime="0:0:0.000" Value="0" />
<DiscreteDoubleKeyFrame KeyTime="0:0:0.125" Value="22.5" />
<DiscreteDoubleKeyFrame KeyTime="0:0:0.250" Value="45" />
<DiscreteDoubleKeyFrame KeyTime="0:0:0.375" Value="67.5" />
<DiscreteDoubleKeyFrame KeyTime="0:0:0.500" Value="90" />
<DiscreteDoubleKeyFrame KeyTime="0:0:0.625" Value="110.5" />
<!-- ... -->
</DoubleKeyFrameCollection>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
Even easier, use the DoubleAnimation "By" property, as in:
<DoubleAnimation
Storyboard.TargetName="WaitCanvas"
Storyboard.TargetProperty="(Canvas.RenderTransform).(TransformGroup.Children)[0]
.(RotateTransform.Angle)"
From="0" To="360" By="22.5" Duration="0:0:2"
AutoReverse="False" RepeatBehavior="Forever" />