在Windows 8中重用动画

时间:2012-12-19 02:51:08

标签: c# xaml windows-8 microsoft-metro windows-runtime

我正在构建Windows应用商店应用程序(Winrt,Metro,Windows 8应用程序)。我尝试在gridview动画中提供图像:从web加载图像并打开后,它会填充其单元格。

我有故事板:

            <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>

我有这样的C#代码来处理加载和打开图像的事件:

    private void Image_ImageOpened(object sender, RoutedEventArgs e)
    {
        Storyboard.SetTarget(PopupImageStoryboard, sender as Image);
        PopupImageStoryboard.Begin();
    }

它不起作用,我无法更改目标并在运行时重新运行相同的故事板。但是我希望同时运行这个动画的多个图像。你能推荐任何动画重用的解决方案吗?

1 个答案:

答案 0 :(得分:4)

您应该从每个子动画中删除它:

Storyboard.TargetName="image"

然后我认为单个Storyboard可能无法同时在两个目标元素上使用,因此解决方法是将其放在DataTemplate中,例如。

<Page.Resources>
    <DataTemplate
        x:Name="myStoryboard">
        <Storyboard ... />
    </DataTemplate>
</Page.Resources>

然后在代码中你会说

var sb = (Storyboard)myStoryboard.LoadContent();
Storyboard.SetTarget(sb, sender as Image);
sb.Begin();

BTW - 不要为“宽度”和“高度”属性设置动画。在您的情况下,这几乎肯定不是最好的主意。您应该为RenderTransform属性设置动画,例如:定位ScaleTransform的ScaleX和ScaleY属性。如果动画是依赖动画 - 它将导致每帧中的布局更新效率非常低并且会降低动画帧速率。

*编辑

一个更好的解决方案就是这样:

<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();
}