ПРИМЕЧАНИЕ: значения точек, о которых я здесь говорю, относятся к исходному местоположению объекта, а не к конкретным значениям точек.
Я думаю, что проблема в том, что раскадровка, хотя и играла до конца, на самом деле не остановилась. Когда вы устанавливаете конечную точку (-20, -20), это относительно ее начальной точки. Повторное воспроизведение анимации (при условии отсутствия ключевого кадра в нулевое время) переместит объект из его существующего местоположения (-20, -20) в целевое местоположение, которое также (-20, -20). Это создает впечатление отсутствия анимации, которая технически не точна. Если бы у вас была отдельная анимация без ключевого кадра в нуле, которая перемещала тот же объект, она начиналась бы с того места, где этот объект находился, до первого ключевого кадра в анимации.
Если вы на самом деле остановите анимацию, объект вернется к своему первоначальному значению в (0,0). Проверьте это, добавив другую кнопку, которая выдает Stop [для этого я использую поведение ControlStoryboardAction]. Вот пример, который вы можете использовать для проверки:
<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="Animation1.MainPage"
Width="640"
Height="480">
<UserControl.Resources>
<Storyboard x:Name="Storyboard1">
<DoubleAnimation Duration="0:0:0.8"
To="-20"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)"
Storyboard.TargetName="rectangle"
d:IsOptimized="True" />
<DoubleAnimation Duration="0:0:0.8"
To="-20"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Storyboard.TargetName="rectangle"
d:IsOptimized="True" />
</Storyboard>
</UserControl.Resources>
<Grid x:Name="LayoutRoot"
Background="White">
<Button Content="Play"
HorizontalAlignment="Left"
Height="37"
Margin="35,53,0,0"
VerticalAlignment="Top"
Width="65">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:ControlStoryboardAction Storyboard="{StaticResource Storyboard1}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Rectangle x:Name="rectangle"
Fill="#FF0303FF"
Height="99"
Margin="275,0,207,57"
Stroke="Black"
VerticalAlignment="Bottom"
RenderTransformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<CompositeTransform />
</Rectangle.RenderTransform>
</Rectangle>
<Button Content="Stop"
HorizontalAlignment="Left"
Height="40"
Margin="35,115,0,0"
VerticalAlignment="Top"
Width="65">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:ControlStoryboardAction ControlStoryboardOption="Stop"
Storyboard="{StaticResource Storyboard1}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
Я думаю, вам придется по-другому подойти к этой конкретной проблеме. Проще всего было бы поместить это в Canvas и управлять значениями Top и Left (желательно через привязку). Идея состоит в том, чтобы зафиксировать завершение раскадровки и обновить значения в привязке, а затем остановить анимацию. Это должно дать правильную отправную точку для следующего воспроизведения анимации. Извините, у меня нет времени, чтобы собрать это воедино, но, надеюсь, это продвинет вас дальше.