UWP 动画重置为 From 状态

UWP Animation resets to From state

我在 UWP 应用程序中有一个动画按预期工作(生产 Windows 商店应用程序),直到 Windows 更新 1809。某些内容已更改,现在动画重置为 From完成后的价值。

示例代码:

动画(旋转):

<Storyboard x:Key="FlipTest">
    <DoubleAnimation
                        Storyboard.TargetName="TestRotation"
                        Storyboard.TargetProperty="RotationY"
                        From="180"
                        To="10"
                        Duration="0:0:1.40"
                        />
</Storyboard>

动画项目:

    <TextBlock Text="Test" FontSize="18">
        <TextBlock.Projection>
            <PlaneProjection x:Name="TestRotation" RotationY="0" />
        </TextBlock.Projection>
    </TextBlock>

从按钮点击开始调用:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Storyboard sb = (Storyboard)Resources["FlipTest"];
    sb.Begin();
}

预期行为(适用于 Windows 1803): 当您单击按钮时,TextBlock 旋转 并保持 在此状态。

Windows1809 上的行为: TextBox 在动画结束后立即重置为 From(180 度)值,但在调用 Storyboard.Completed 事件之前。

有趣的是,如果我输入To="0",它会保持这种状态。如果我设置 10、190 或 360 度,它会重置。请注意,它不是重置为原始状态(即 0 度),而是重置为 From 值(180 度)。

我也将 Microsoft.NETCore.UniversalWindowsPlatform 更新到最新版本 (6.1.9),但没有任何变化。

任何人都可以解释这种行为或告诉如何解决它吗?我是否遗漏了一些明显的东西?

更新(丑陋的解决方法)

我发现我可以使用以下丑陋的技巧:

    sb.Completed += (s, ee) =>
    {
        TestRotation.RotationY = 0.01; // ugly hack for Windows Build 1809
    };

但它不仅在代码上看起来很糟糕。在屏幕上你可以看到可怕的 blink,因为在动画之后项目重置然后再次设置为正常值。

我还注意到 RotationY 在动画完成后保持正确的值,尽管在视觉上该项目旋转了。您可以看到代码(在完整动画中)或 Live Property Explorer 中的值为 0,而视觉上项目旋转了 180 度。

我认为这是一个错误 并且与 StoryboardFillBehavior 相关联。

从第一个 Windows 10 Build 10240 开始,我一直都在发生这种情况。由于某种原因,如果结果是 != 0,那么 FillBehavior.HoldEnd 状态将重置为 From 值而不是 To 值(Storyboard 结尾的值)。

我没有查看开源代码(最好是 IMO),我做了以下导致我做出这个假设的事情。

在 Windows 的构建上验证了现有代码,一直追溯到 Windows 10 的第一个版本。测试了 To = 10To = 0To = 10 重置为起始 From 值。 To = 0 重置为原始值。您已经记录了这一点。

From 值修改为超过 To 值 360 度(使用随机值),以便执行完整旋转。此时它确实停在 From 值,看起来也像 To 值,这只能说明 Storyboard.FillBehavior = FillBehavior.HoldEnd 保持 From 值。我知道它不是 Storyboard.FillBehavior = FillBehavior.Stop 因为它每次都会重置为 Storyboard 之前的初始值(这是 FillBehavior.Stop 应该做的)。

我假设这是基于我所做的各种测试,包括手动编写 Storyboard

假设:

如果 Storyboard.FillBehavior = FillBehavior.HoldEndStoryboard.To 值不为 0,那么它将在完成后保留 Storyboard.From 值。

如果 Storyboard.FillBehavior = FillBehavior.Stop 那么它会按预期工作,并且 returns 到动画之前值所处的任何状态。

建议的解决方法:

虽然我看到您可以通过使用 Storyboard.Completed 事件来解决问题,但我还有另一种选择(尽管它仍然令人不快),它可能更干净并消除了闪烁;它对我有用。

我已将受影响的 Timelines 设置为 FillBehavior.Stop,然后我将它们正在设置动画的属性的初始值设置为 To 值。

注意:在您的示例中,您的 DoubleAnimation.Duration 大于 Storyboard.Duration。这将始终导致它重置为该起始值(在本例中为 From 值),因为 DoubleAnimation 永远不会完成。确保您的 Storyboard.Duration 至少与最高 child Timeline 一样长,以防止闪烁和不良影响。

我最初认为这是您的问题,但在将 Storyboard 设置为匹配或更好后,您的问题仍然存在。只是知道持续时间的差异可能会导致不需要的结果,尤其是当您的 Storyboard 比 child Timeline(s) 短时。

<Storyboard x:Key="FlipTest"
            Duration="0:0:1.40">
    <DoubleAnimation Storyboard.TargetName="TestRotation"
                     Storyboard.TargetProperty="RotationY"
                     From="180"
                     To="10"
                     Duration="0:0:1.40" 
                     FillBehavior="Stop"/>
</Storyboard>


TestRotation.RotationY = 10;
Storyboard sb = (Storyboard)Resources["FlipTest"];
sb.Begin();