Storyboard can't be executed twice - windows-phone-7

I tried to use an animation in my app and I'm using only two pages to test the animation.
When the app starts for the first time, I want to animate my application title with a sliding effect. The title should come from outside the page.
I used the following code:
<StackPanel x:Name="TitlePanel"
Grid.Row="0"
Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle"
Text="{Binding LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}"
Style="{StaticResource PhoneTextNormalStyle}" RenderTransformOrigin="0.5,0.5" >
<TextBlock.RenderTransform>
<CompositeTransform x:Name="ApplicationTitleTransIn" TranslateX="-200"/>
</TextBlock.RenderTransform>
<TextBlock.Triggers>
<EventTrigger RoutedEvent="TextBlock.Loaded">
<BeginStoryboard>
<Storyboard BeginTime="00:00:0.5">
<DoubleAnimation Duration="00:00:0.7"
Storyboard.TargetName="ApplicationTitleTransIn"
Storyboard.TargetProperty="TranslateX"
From="-200" To="0">
<DoubleAnimation.EasingFunction>
<BackEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
</StackPanel>
And it works pretty well.
When I click a button, my application title should move to the right side of my page and then the second page should be displayed.
I created the following storyboard:
<phone:PhoneApplicationPage.Resources>
<Storyboard x:Name="ApplicationTitleTransOut">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="ApplicationTitle">
<EasingDoubleKeyFrame KeyTime="0" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseIn"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="600">
<EasingDoubleKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseIn"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</phone:PhoneApplicationPage.Resources>
In the code behind, the storyboard is executed as follow:
ApplicationTitleTransOut.Completed += delegate
{
ApplicationTitleTransOut.Stop();
var vm = DataContext as MainViewModel;
if (vm != null)
{
vm.OpenPageCommand.Execute(listBox.SelectedItem as TileItem);
}
};
ApplicationTitleTransOut.Begin();
The text will move to the right side of my page and then I'll navigate to the second page.
Until now everything works.
But when I press the back button (on the phone) I've an exception.
ExceptionObject = {System.InvalidOperationException: Cannot resolve TargetName ApplicationTitleTransIn.}
Did I miss something? Is this the right way to achieve this animation?
Thank you for your help.

In your situation, I would structure the XAML layout differently. First of all, it does not seem that you need CompositeTransform, but just TranslateTransform. In this case, use this snippet for RenderTransform:
<TextBlock.RenderTransform>
<TranslateTransform x:Name="ApplicationTitleTransIn" X="-200"/>
</TextBlock.RenderTransform>
Now, when you are binding the DoubleAnimation to it, use relative property conventions:
<DoubleAnimation Duration="00:00:0.7"
Storyboard.TargetName="ApplicationTitle"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
From="-200" To="0">
Same applies to your DoubleAnimationUsingKeyFrames:
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)" Storyboard.TargetName="ApplicationTitle">
Works like a charm.

Related

Blend Animation Playing Issue

I don't know if I named the question right but here it is
First of all I am very new to Blend and never used it before in my life. I decided to make a simple animation today and things happened but not as expected.
I'm animating a button and the animation is just a simple 360 degrees flip on the Y axis. I created the animation for a specific button. It worked exactly how I wanted with this code
TiltAnimation.Begin();
However when I tried to create a ControlTemplate with this animation this happened. I need to click and hold the button in order for the animation to finish. I set the animation to play on a specific state: 'Pressed' (to be more specific it was pressed -> * which I suppose means 'from pressed state to any state'). Am I doing something wrong or am I missing something
Note: I'm experimenting on the windows phone platform.
If you need any code tell me in the comments
EDIT:Here is the XAML code from the page and from the App.xaml
Page code:
<Button Grid.Column="1"
Height="60"
Width="60"
BorderThickness="1"
Background="White"
Opacity="0.8"
Template="{StaticResource ButtonControlTemplate1}"
Click="PlayButton_Click">
</Button>
App.xaml code:
<ControlTemplate x:Key="ButtonControlTemplate1" TargetType="Button">
<Grid x:Name="grid">
<Grid.Resources>
<Storyboard x:Name="Storyboard1">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="grid">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="360"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>
<Grid.Projection>
<PlaneProjection/>
</Grid.Projection>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition From="Pressed" GeneratedDuration="0">
<VisualTransition.GeneratedEasingFunction>
<BackEase EasingMode="EaseIn"/>
</VisualTransition.GeneratedEasingFunction>
<Storyboard>
<DoubleAnimation Duration="0:0:1" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="grid"/>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="grid">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="360"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Image x:Name="image" Source="/Assets/Icons/Previous.png">
<Image.Projection>
<PlaneProjection/>
</Image.Projection>
</Image>
<Ellipse Height="Auto" Width="Auto" Stroke="White" StrokeThickness="4"/>
</Grid>
</ControlTemplate>

Focusable WinRT UserControl with image background

I'm having difficulty developing a WinRT control that can display an image as well as be focusable and receive keyboard input. The first part - displaying an image in a UserControl - is straightforward; using a child Rectangle whose background is an ImageBrush works fine.
However, calling UserControl.Focus(FocusState.Programmatic) (or any other focus state) does not work - it returns false and focus is not set to the user control.
Incidentally, this UserControl is currently being tested inside a ContentControl, not sure if that makes any difference.
How can I make this UserControl focusable and able to receive keyboard input?
You need to set IsTabStop="True" to let it focus. UserControl's default is False.
Another thing you need to do is to display a focus indicator, which you don't get with UserControl for free. Here's the way you can add the visuals for it - copied from a Button template:
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup
x:Name="FocusStates">
<VisualState
x:Name="Focused">
<Storyboard>
<DoubleAnimation
Duration="0"
To="1"
Storyboard.TargetProperty="Opacity"
Storyboard.TargetName="FocusVisualWhite" />
<DoubleAnimation
Duration="0"
To="1"
Storyboard.TargetProperty="Opacity"
Storyboard.TargetName="FocusVisualBlack" />
</Storyboard>
</VisualState>
<VisualState
x:Name="Unfocused" />
<VisualState
x:Name="PointerFocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle
x:Name="FocusVisualWhite"
IsHitTestVisible="False"
Opacity="0"
StrokeDashOffset="1.5"
StrokeEndLineCap="Square"
Stroke="{ThemeResource FocusVisualWhiteStrokeThemeBrush}"
StrokeDashArray="1,1" />
<Rectangle
x:Name="FocusVisualBlack"
IsHitTestVisible="False"
Opacity="0"
StrokeDashOffset="0.5"
StrokeEndLineCap="Square"
Stroke="{ThemeResource FocusVisualBlackStrokeThemeBrush}"
StrokeDashArray="1,1" />
</Grid>
You still need to switch the visual state and so you could do something like this:
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
this.UpdateVisualState(true);
}
protected override void OnLostFocus(RoutedEventArgs e)
{
base.OnLostFocus(e);
this.UpdateVisualState(true);
}
private void UpdateVisualState(bool useTransitions)
{
switch (this.FocusState)
{
case FocusState.Programmatic:
case FocusState.Keyboard:
VisualStateManager.GoToState(this, "Focused", useTransitions);
break;
case FocusState.Pointer:
VisualStateManager.GoToState(this, "PointerFocused", useTransitions);
break;
case FocusState.Unfocused:
VisualStateManager.GoToState(this, "Unfocused", useTransitions);
break;
}
}

Running storyboard animations in windows 8 datatemplate

I'm trying to create a to do list in Windows 8 XAML. when I complete an item, I want a storyboard to erase the completed items. How can I get a storyboard to run on items inside a datatemplate? when I run the storyboard from C#, I get an error that says: WinRT information: Cannot resolve TargetName rectangleToDelete.
My storyboard looks like this:
<Page.Resources>
<Storyboard x:Name="AnimateDelete">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="rectangleToDelete">
<EasingDoubleKeyFrame KeyTime="0" Value="-0.333"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="-327.5"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="rectangleToDelete">
<EasingDoubleKeyFrame KeyTime="0" Value="0.333"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="-163.25"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Page.Resources>
My Listview template looks like this:
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel Orientation="Horizontal"
Margin="0,0,-393,-15">
<CheckBox x:Name="CheckBoxComplete"
IsChecked="{Binding Complete, Mode=TwoWay}"
Checked="CheckBoxComplete_Checked"
Content="{Binding Text}"
Margin="10,5"
VerticalAlignment="Center"
MinWidth="300" />
<Button x:Name="ButtonDelete"
Click="ButtonDelete_Click"
Content="Delete" />
</StackPanel>
<Rectangle x:Name="rectangle"
Fill="#FFF4F4F5"
Stroke="Black"
StrokeThickness="0"
RenderTransformOrigin="0.5,0.5"
Margin="319,2,-300,-14"
Height="34"
VerticalAlignment="Top">
<Rectangle.RenderTransform>
<CompositeTransform ScaleX="-1" />
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
My codebehind looks like this:
Button btn = (Button)sender;
TodoItem item = btn.DataContext as TodoItem;
StackPanel stk = (StackPanel)btn.Parent;
Grid grd = (Grid)stk.Parent;
Rectangle rect = (Rectangle)grd.Children[1];
rect.Name = "rectangleToDelete";
AnimateDelete.Begin();
as you can see, I've tried finding the rectangle and giving it the correct name, but I get the same error.
any help would be appreciated!
thanks, tom
A DataTemplate has a different namescope than anything outside. You can put the contents of that DataTemplate and the Storyboard in their own UserControl to get it to work.

Image Animation: Make Image move left and then back

I have the following which works for animating the opacity of the image, but what I'd really like to do is have the image move back in forth say 100 pixels to the right then a 100 pixels to the left. But I haven't been able to achieve this effect.
<Image Source="MyImage.jpg" Width="2000" Height="800" x:Name="MyAnimatedImageGeometry">
<Image.Triggers>
<EventTrigger RoutedEvent="Image.Loaded">
<BeginStoryboard>
<Storyboard Storyboard.TargetName="MyAnimatedImageGeometry" Storyboard.TargetProperty="Opacity">
<DoubleAnimation To="0" AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
Here's an image:
<Image x:Name="image" Source="/filename.png" RenderTransformOrigin="0.5,0.5" >
<Image.RenderTransform>
<CompositeTransform TranslateX="0"/>
</Image.RenderTransform>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<eim:ControlStoryboardAction Storyboard="{StaticResource moveImage}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
The initialization of the rendor transform is the interesting bit. The trigger is just there to demonstrate starting the storyboard. You wouldn't do this in a real app as tapping the item to move it in this way gets messed up when you tap it while it's moving. (Obviously this would be easy to control in code.)
Here's the other interesting bit, the related storyboard:
<Storyboard x:Name="moveImage" AutoReverse="True" RepeatBehavior="1x">
<DoubleAnimation Duration="0:0:1"
To="-100"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)"
Storyboard.TargetName="image"
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseIn"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
This will move the image 100 pixels to the left (over a period of one second) and then back again.
I've added an easing function to make it more interesting.

Why does the ball in this animation look chopped when it changes position?

Here is a link to the animation: http://www.microdivision.com/blog/Strange-Silverlight-Behavior
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
x:Class="BouncingBall.MainPage"
Width="640" Height="480">
<UserControl.Resources>
<Storyboard x:Name="Bounce" RepeatBehavior="Forever" AutoReverse="True">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="Ball">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<SplineDoubleKeyFrame KeyTime="0:0:1" Value="-144" KeySpline="0,1,1,1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<i:Interaction.Triggers>
<i:EventTrigger>
<ei:ControlStoryboardAction Storyboard="{StaticResource Bounce}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Canvas x:Name="LayoutRoot" Background="#FFCADFFF">
<Ellipse x:Name="Ball" Stroke="Black" Width="100" Height="100" Fill="#FFF31D1D" Canvas.Top="190" Canvas.Left="0">
<Ellipse.RenderTransform>
<CompositeTransform/>
</Ellipse.RenderTransform>
</Ellipse>
</Canvas>
</UserControl>
As answered by SharpGIS at http://forums.silverlight.net/forums/t/223659.aspx enabling hardware acceleration solved the problem.
For HTML modify the Silverlight control to include the following param:
<param name="EnableGPUAcceleration" value="true" />
I think this may be the result of how Silverlight is adapting during playback. On my machine the ball appears unchopped most of the time despite the fact that I have an older machine with hardly a good CPU/GPU. Silverlight uses only CPU for rendering (except for 3D perspective operations when told to do so) and its time-based animation allows it to cut frames in order to adapt to the host client. It is known for choppiness as a result. Silverlight 5 promises GPU support.
Any reason you are using a spline to create the bounce instead of this?
<Storyboard x:Name="Bounce" RepeatBehavior="Forever" AutoReverse="True">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="Ball">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="-144">
<EasingDoubleKeyFrame.EasingFunction>
<BounceEase EasingMode="EaseIn" Bounciness="0" Bounces="1"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>

Resources