问题
I am building Windows Store Application (Winrt, Metro, Windows 8 app). I try give images in gridview animation: after image is loaded from web and opened it populates its cell.
I have storyboard for that:
<Storyboard x:Name="PopupImageStoryboard">
<DoubleAnimationUsingKeyFrames EnableDependentAnimation="True" Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="image">
<EasingDoubleKeyFrame KeyTime="0" Value="100"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="240"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames EnableDependentAnimation="True" Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="image">
<EasingDoubleKeyFrame KeyTime="0" Value="100"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="240"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
And I have such C# code for handling event that image loaded and opened:
private void Image_ImageOpened(object sender, RoutedEventArgs e)
{
Storyboard.SetTarget(PopupImageStoryboard, sender as Image);
PopupImageStoryboard.Begin();
}
It does not work, I can not change target and rerun same storyboard while it is running. But I want multiple images run this animation simultaneously. Can you recommend any solution for animation reuse ?
回答1:
You should remove this from each of the child animations:
Storyboard.TargetName="image"
Then also I think a single Storyboard might not be possible to be used on two target elements at the same time, so the solution for that would be to put it in a DataTemplate, e.g.
<Page.Resources>
<DataTemplate
x:Name="myStoryboard">
<Storyboard ... />
</DataTemplate>
</Page.Resources>
Then in code you would say
var sb = (Storyboard)myStoryboard.LoadContent();
Storyboard.SetTarget(sb, sender as Image);
sb.Begin();
BTW - do not animate Width and Height properties. This is almost certainly not the best idea in your case. You should animate your RenderTransform properties instead, e.g. targeting ScaleTransform's ScaleX and ScaleY properties. If an animation is a dependent - it will cause layout updates in each frame which is very inefficient and will degrade your animation frame rate.
*EDIT
A better solution then would look like this:
<Page.Resources>
<DataTemplate
x:Name="myStoryboardTemplate">
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="ScaleX"
From="0.5"
To="1.0"
Duration="0:0:0.4">
<DoubleAnimation.EasingFunction>
<BackEase
Amplitude="2"
EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation
Storyboard.TargetProperty="ScaleY"
From="0.5"
To="1.0"
Duration="0:0:0.4">
<DoubleAnimation.EasingFunction>
<BackEase
Amplitude="2"
EasingMode="EaseOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</DataTemplate>
</Page.Resources>
...
<Image
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="620"
Height="300"
Source="Assets/SplashScreen.png"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill">
<Image.RenderTransform>
<ScaleTransform
x:Name="imageScaleTransform" />
</Image.RenderTransform>
</Image>
...
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var sb = (Storyboard)myStoryboardTemplate.LoadContent();
Storyboard.SetTarget(sb, imageScaleTransform);
sb.Begin();
}
来源:https://stackoverflow.com/questions/13944834/reuse-animations-in-windows-8