wpf ObjectAnimationUsingKeyFrames setting the left value - wpf

In WPF, I'm trying to move an image from left to center, pause for a second, then move the image to the right.
I'm trying to achieve it using ObjectAnimationUsingKeyFrames.
<BeginStoryboard>
<Storyboard Storyboard.TargetName="RoundNumberText" >
<ObjectAnimationUsingKeyFrames Duration="0:0:1" Storyboard.TargetProperty="Left">
<DiscreteObjectKeyFrame Value="400" KeyTime="0:0:0.5"/>
<DiscreteObjectKeyFrame Value="1400" KeyTime="0:0:1.5"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
Somehow i got the error message on the TargetProperty that the object does not supported by this properties. I've tried with margin as well, but still giving error.
Appreciate if anyone could help.

To set the value for alignment, you need to do something like this:
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MyImage"
Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<HorizontalAlignment>Center</HorizontalAlignment>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
Below is my example, where the image appears in the role of the Label:
<Grid>
<Grid.Triggers>
<EventTrigger SourceName="MoveToCenter" RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Test"
Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<HorizontalAlignment>Center</HorizontalAlignment>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames BeginTime="0:0:1"
Storyboard.TargetName="Test"
Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<HorizontalAlignment>Right</HorizontalAlignment>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Label x:Name="Test" Content="Test" Width="300" Height="200" Background="Aqua" HorizontalAlignment="Left" />
<Button Name="MoveToCenter" Content="MoveToCenter" Width="120" Height="30" HorizontalAlignment="Right" VerticalAlignment="Bottom" />
</Grid>

Related

How to start Storyboard by means of data binding?

I have a Storyboard at Window resources as shown below.
<Window.Resources>
<!-- Storyboard as a window resource -->
<Storyboard
x:Key="NB"
x:Name="NB_resource"
Completed="NB_resource_Completed"
RepeatBehavior="5x">
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="NB_image"
Storyboard.TargetProperty="Source"
Duration="0:0:1.2">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="pack://application:,,,/CircleSurrogateButton;component/Images/NB_00.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:.3">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="pack://application:,,,/CircleSurrogateButton;component/Images/NB_01.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:.6">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="pack://application:,,,/CircleSurrogateButton;component/Images/NB_02.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:.9">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="pack://application:,,,/CircleSurrogateButton;component/Images/NB_03.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
The Storyboard can be started with the following string which is placed in regular Button.
<EventTrigger RoutedEvent="PreviewMouseLeftButtonDown">
<BeginStoryboard Storyboard="{DynamicResource NB}" />
</EventTrigger>
A question is How to use a data binding in order to start that Storyboard.
For example:
<DataTrigger Binding="{Binding Start_Storyboard}" Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{DynamicResource NB}"/>
</DataTrigger.EnterActions>
</DataTrigger>

WPF Animation not working correctly

I have the following storyboard for my Image control, however, when running this code, the last image does not get displayed:
<Image Height="15" Width="137" RenderTransformOrigin="0.415,4.583" Canvas.Left="104" Canvas.Top="13">
<Image.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding State, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="Reconnect">
<DataTrigger.EnterActions>
<BeginStoryboard Name="reconnectStoryBoardImageChange" >
<Storyboard>
<ObjectAnimationUsingKeyFrames
BeginTime="00:00:00" RepeatBehavior="Forever"
Storyboard.TargetProperty="(Image.Source)">
<DiscreteObjectKeyFrame KeyTime="00:00:01">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/State/Reconnect.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="00:00:02">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/State/Reconnect_2.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="00:00:03">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/State/Reconnect_3.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="00:00:04">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/State/Reconnect_4.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="reconnectStoryBoardImageChange"/>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
What this XAML does it to display different images at different times, but never displays reconnect_4 , it goes till _3 then back to the first image.
Am I doing something wrong?
You can find the explanation why it is not working the way you expect it here.
If the animation's Duration is Automatic or its Duration is equal to
the time of the last key frame, the animation ends. Otherwise, if the
animation's Duration is greater than the key time of the last key
frame, the animation holds the key frame value until it reaches the
end of its Duration.
So you should specify the Duration of the Storyboard. I'd do it like this:
<Style.Triggers>
<DataTrigger Binding="{Binding State, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="Reconnect">
<DataTrigger.EnterActions>
<BeginStoryboard Name="reconnectStoryBoardImageChange" >
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:04" RepeatBehavior="Forever" Storyboard.TargetProperty="(Image.Source)">
<DiscreteObjectKeyFrame KeyTime="00:00:00">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/State/Reconnect.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="00:00:01">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/State/Reconnect_2.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="00:00:02">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/State/Reconnect_3.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="00:00:03">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/State/Reconnect_4.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="reconnectStoryBoardImageChange"/>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
I specified 4 seconds as the Duration. The first image is shown from 00:00:00 to 00:00:01. The second image is shown from 00:00:01 to 00:00:02. The third image is shown from 00:00:02 to 00:00:03. Fourth image is shown from 00:00:03 to 00:00:04. Then it restarts.
In your case the last key frame lasts 0 seconds, because your storyboard ends too early.

Silverlight Image Flip Animation

In my silverlight app, I have two images of equal dimension.
When the user clicks on the image I would like to animate the transition of one image to the other as if it were a piece of paper being flipped with the first image on the front and the other on the back.
I haven't worked with silverlight animation, yet so I don't know where to begin.
Basically you will need two Storybards to begin with. Each Storyboard will be using PlaneProjection (in this case I am using RotationX which rotates the images around the x-axis of rotation) to do the flipping animation.
In the following example, I have created FlippingDown and FlippingUp two Storyboards. I attached a ControlStoryboardAction behavior to each of them, they will be triggered when MouseLeftButtonDown is fired.
You'll need to reference System.Windows.Interactivity and Microsoft.Expression.Interactions.
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" mc:Ignorable="d" x:Class="FilppingAnimation.MainPage" Width="640" Height="480">
<UserControl.Resources>
<Storyboard x:Name="FlippingDown">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" Storyboard.TargetName="Front">
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="90.0146"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="180"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" Storyboard.TargetName="Back">
<EasingDoubleKeyFrame KeyTime="0" Value="-180"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="-90"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Front">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:0.3">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Back">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:0.3">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Name="FlippingUp">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Front">
<DiscreteObjectKeyFrame KeyTime="0:0:0.3">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Duration="0:0:0.6" To="0" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" Storyboard.TargetName="Front" d:IsOptimized="True"/>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" Storyboard.TargetName="Back">
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="-90.0146"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="-180"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Back">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:0.3">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="#FFCC9E9E">
<Image x:Name="Back" HorizontalAlignment="Center" VerticalAlignment="Center" Source="/311438.jpg" Height="226" Width="129">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<ei:ControlStoryboardAction Storyboard="{StaticResource FlippingUp}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Image.Projection>
<PlaneProjection/>
</Image.Projection>
</Image>
<Image x:Name="Front" HorizontalAlignment="Center" VerticalAlignment="Center" Source="/318549.jpg" Height="226" Width="129" d:IsHidden="True">
<Image.Projection>
<PlaneProjection/>
</Image.Projection>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<ei:ControlStoryboardAction Storyboard="{StaticResource FlippingDown}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
</Grid>
</UserControl>
Hope this helps. :)
You could search for info on Projection animations in Blend. This looks like what you need: http://www.silverlightbuzz.com/2009/10/14/using-the-3d-tools-to-animate-in-blend/

WPF stackpanel visibility animation

I have a stackpanel with a button which, when clicked, makes the stackpanel disappear. I want to animate the transition form visible to hidden, but haven't been able to.
I looked around for a while and bumped into something that looks like this:
<StackPanel Margin="80,60,60,80" Background="Gray">
<StackPanel.Triggers >
<EventTrigger >
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard TargetProperty="Visibility">
<DoubleAnimation Duration="0:0:5:0" From="Visible" To="Hidden"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</StackPanel.Triggers>
<Button Name="buttonTop" Content="TOP" Margin="40,40,40,40" Click="buttonTop_Click" Width="131" />
</StackPanel>
which of course, is not 100% there yet. Any ideas?
You can use
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ItemsHost"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
This is pretty much a setter in a storyboard, where KeyTime describes the time when the value should be set.
So the full storyboard would be like this:
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
To="0" Duration="0:0:5.0"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:5.0" Value="{x:Static Visibility.Hidden}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
edit: How to make the storyboard trigger when button is clicked:
<Button Content="Button" HorizontalAlignment="Left" Margin="337,221,0,0" VerticalAlignment="Top" Width="75">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
To="0" Duration="0:0:5.0"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:5.0" Value="{x:Static Visibility.Hidden}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
Visibiltiy is a discrete value - it's either on or off, so animating will still result in a sudden disappearance rather than a gradual fading out. You could instead animate the Opacity of the StackPanel from 1 to 0, and then animate the Visibilty to Hidden (or Collapsed) after that.

Change the background image of a Button when pressed using VisualStateManager

I have this button :
<Button x:Name="PrevAdIcon" Tag="-1" Visibility="Collapsed" Width="80" Height="80" Click="PrevAd">
<Button.Background>
<ImageBrush AlignmentY="Top" Stretch="None" ImageSource="/Images/prev.png"></ImageBrush>
</Button.Background>
</Button>
How can I change the background to /Images/prev-selected.png when a user pressed the button ? It'll give him a feedback, since it's a WP7 app
what I have so far (not working) :
<vsm:VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="Background" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<ImageBrush ImageSource="/Images/prev-selected.png" Stretch="Fill"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
As far as I know, you can't change the value of the Source property on the Image element by using the VisualStateManager. However, you can just add two Image elements to the ControlTemplate: one for the Normal state and one for the Pressed state, and toggle the Visibility in the Pressed state.
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Img">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="PressedImg">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
See Peter Torr's post on "Why can't I change the Background of my Button on a Click event?" for an example and explanation of how to do this.
To add more information to Derek's answer, you should look at Gambit's answer here for full XAML that works

Resources