WPF如何在代码背后轻松链接动画

本文关键字:链接 动画 背后 代码 WPF | 更新日期: 2023-09-27 18:27:01

我有一个画布:

<Canvas x:Name="testCanvas" Height="40" Width="460" VerticalAlignment="Top">
    <Image Source="versus2-top-p1.png"/>
    <Label x:Name="testLabel" Content="TEST" />
</Canvas>

我把它动画化如下:

private void button_Click(object sender, RoutedEventArgs e)
{
    testCanvas.BeginAnimation(Canvas.MarginProperty,
        new ThicknessAnimation(new Thickness(0, -40, 0, 0), TimeSpan.FromSeconds(1))
    );
    testLabel.Content = "ANIMATION TEST";
    testCanvas.BeginAnimation(Canvas.MarginProperty,
        new ThicknessAnimation(new Thickness(0, 0, 0, 0), TimeSpan.FromSeconds(1))
    );
}

问题是动画没有链接。所有3行代码都在同一时间被激发。我想按顺序运行这三行代码:

  1. 将上边距移动到-40
  2. 更改testLabel中的文本
  3. 将上边距移动到0

做这件事最简单的方法是什么?

WPF如何在代码背后轻松链接动画

想好了。。。使用动画。已完成事件处理程序。

    private void button_Click(object sender, RoutedEventArgs e)
    {
        ThicknessAnimation animate = new ThicknessAnimation(new Thickness(0, -40, 0, 0), TimeSpan.FromSeconds(1));
        animate.Completed += new EventHandler(animate_Completed);
        testCanvas.BeginAnimation(Canvas.MarginProperty, animate);
    }
    private void animate_Completed(object sender, EventArgs e)
    {
        testLabel.Content = "ANIMATION TEST";
        testCanvas.BeginAnimation(Canvas.MarginProperty,
            new ThicknessAnimation(new Thickness(0, 0, 0, 0), TimeSpan.FromSeconds(1))
        );
    }

作为使用Completed事件启动下一个动画的代码隐藏替代方案,您可以将所有后续动画放在一个故事板中,并设置它们的BeginTimes。

这样做的好处是,你最终不会得到一组方法,你可以使用故事板控制(开始、暂停、停止、加速)动画。

也就是说,我仍然认为动画作为Xaml资源是一个更好的选择。要将参数传递给动画,可以使用数据绑定,我认为Xaml动画的可读性/可维护性优于C#编码的动画。

private void button_Click(object sender, RoutedEventArgs e)
{
    var moveTopUpDuration = TimeSpan.FromSeconds(1);
    var storyboard = new Storyboard();
    var moveTopUp = new ThicknessAnimation(
                        new Thickness(0, -40, 0, 0), 
                        moveTopUpDuration);
    Storyboard.SetTarget(moveTopUp, testCanvas);
    Storyboard.SetTargetProperty(moveTopUp, Canvas.MarginProperty);
    moveTopUp.Completed += MoveTopUpCompleted;
    var moveTopDown = new ThicknessAnimation(
                          new Thickness(0, 0, 0, 0),
                          TimeSpan.FromSeconds(1));
    Storyboard.SetTarget(moveTopDown, testCanvas);
    Storyboard.SetTargetProperty(moveTopDown, Canvas.MarginProperty);
    moveTopDown.BeginTime = moveTopUpDuration;
    storyboard.Childeren.Add(moveTopUp);
    storyboard.Childeren.Add(moveTopDown);       
    storyboard.Begin();
}
private void MoveTopUp_Completed(object sender, EventArgs e)
{
    testLabel.Content = "ANIMATION TEST";
}