Trouble Animating Transforms in GroupTransform

2019-03-27 10:42发布

问题:

I have an image of a fish in a WPF project (VB.net code behind), and I'm attempting to animate it swimming back and forth using two transforms.

For some reason, while if I only animate the ScaleTransform (with ScaleTransform alone, and no TransformGroup), the animation works fine, the TranslateTransform animation does not. Additionally, the ScaleTransform does not work when inside the TransformGroup.

Here is the code I'm using. What am I doing wrong?

<Image Height="90" HorizontalAlignment="Left" Name="Fish1" Stretch="Fill" VerticalAlignment="Top" Width="260" Source="/VBP-WORD4WORD;component/Images/IMG-FISH1.png" Canvas.Left="24" Canvas.Top="67" Margin="-28,70,0,0">
    <Image.RenderTransform>
        <TransformGroup>
            <ScaleTransform ScaleX="1"/>
            <TranslateTransform X="0"/>
        </TransformGroup>
    </Image.RenderTransform>
    <Image.Triggers>
        <EventTrigger RoutedEvent="Image.Loaded">
            <EventTrigger.Actions>
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimationUsingKeyFrames Duration="0:0:30" Storyboard.TargetProperty="RenderTransform.(TransformGroup.TranslateTransform.X)" RepeatBehavior="Forever">
                            <LinearDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
                            <LinearDoubleKeyFrame KeyTime="0:0:14.9" Value="407"/>
                            <LinearDoubleKeyFrame KeyTime="0:0:15" Value="680"/>
                            <LinearDoubleKeyFrame KeyTime="0:0:29.9" Value="265"/>
                            <LinearDoubleKeyFrame KeyTime="0:0:30" Value="0"/>
                        </DoubleAnimationUsingKeyFrames>
                        <DoubleAnimationUsingKeyFrames Duration="0:0:30" Storyboard.TargetProperty="RenderTransform.(TransformGroup.ScaleTransform.ScaleX)" RepeatBehavior="Forever">
                            <LinearDoubleKeyFrame KeyTime="0:0:14.9" Value="1"/>
                            <LinearDoubleKeyFrame KeyTime="0:0:15" Value="-1"/>
                            <LinearDoubleKeyFrame KeyTime="0:0:29.9" Value="-1"/>
                            <LinearDoubleKeyFrame KeyTime="0:0:30" Value="1"/>
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger.Actions>
        </EventTrigger>
    </Image.Triggers>
</Image>

回答1:

Those property paths are all wrong, but i would vote for just avoiding the whole trouble of only using those paths by utilizing Storyboard.TargetName; this works:

<!-- ... -->
<TransformGroup>
    <ScaleTransform  x:Name="scaleTransform" ScaleX="1"/>
    <TranslateTransform x:Name="translateTransform" X="0"/>
</TransformGroup>
  <!-- ... -->
    <Storyboard>
        <DoubleAnimationUsingKeyFrames Duration="0:0:30"
                                       Storyboard.TargetProperty="ScaleX"
                                       Storyboard.TargetName="scaleTransform"
                                       RepeatBehavior="Forever">
            <LinearDoubleKeyFrame KeyTime="0:0:14.9" Value="1"/>
            <LinearDoubleKeyFrame KeyTime="0:0:15" Value="-1"/>
            <LinearDoubleKeyFrame KeyTime="0:0:29.9" Value="-1"/>
            <LinearDoubleKeyFrame KeyTime="0:0:30" Value="1"/>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Duration="0:0:30"
                                       Storyboard.TargetProperty="X"
                                       Storyboard.TargetName="translateTransform"
                                       RepeatBehavior="Forever">
            <LinearDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
            <LinearDoubleKeyFrame KeyTime="0:0:14.9" Value="407"/>
            <LinearDoubleKeyFrame KeyTime="0:0:15" Value="680"/>
            <LinearDoubleKeyFrame KeyTime="0:0:29.9" Value="265"/>
            <LinearDoubleKeyFrame KeyTime="0:0:30" Value="0"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>

If you really want to do it using Storyboard.TargetProperty only, these would be the correct paths as i found out just now:

Storyboard.TargetProperty="RenderTransform.Children[0].ScaleX"
Storyboard.TargetProperty="RenderTransform.Children[1].X"

Which does make perfect sense if you think about it.