WPF:检测动画或取消Timeline.Completed事件?怎么样?

时间:2009-05-20 00:01:51

标签: c# wpf events animation

我正在这样移动3D相机:

    Point3DAnimation pa;

    // Triggered by user click
    void MoveCamera(object sender, EventArgs e)
    {

        pa = new Point3DAnimation(myPoint3D, TimeSpan.FromMilliseconds(2000));
        pa.Completed += new EventHandler(pa_Completed);
        Camera.BeginAnimation(PerspectiveCamera.PositionProperty, pa); // anim#1
    }

    // we're in place. do some idle animation
    void pa_Completed(object sender, EventArgs e)
    {
        pa = new Point3DAnimation(myPoint3Ddz, TimeSpan.FromMilliseconds(5000));
        Camera.BeginAnimation(PerspectiveCamera.PositionProperty, pa); // anim#2
    }
  1. 用户点击。
  2. 相机移动到选择位置(动画#1)。
  3. 当动画#1结束动画#2时播放。
  4. 一切正常......直到用户在上一个动画#1未完成时触发MoveCamera。

    在那种情况下:

    1. 新动画#1正在开始。
    2. 触发旧动画#1的完成事件。
    3. anim#2是立即启动的(重叠新动画#1)。
    4. 2& 3这里错了。我怎么能避免这种情况?

      我认为pa_Completed()应该检测到新的anim#1已经在播放,或者MoveCamera()应该从旧的anim#1取消注册Complete事件。但是正确的做法是什么?

1 个答案:

答案 0 :(得分:1)

如果目标是将两个动画链接在一起,让WPF使用Point3DAnimationUsingKeyFrames类来完成繁重的工作。

首先,在XAML中构建关键帧动画(在代码中执行它是一个熊):

  <Window.Resources>
    <Point3DAnimationUsingKeyFrames x:Key="CameraMoveAnimation" Duration="0:0:7">
      <LinearPoint3DKeyFrame KeyTime="28%" />
      <LinearPoint3DKeyFrame KeyTime="100%" />
    </Point3DAnimationUsingKeyFrames>
  </Window.Resources>

接下来,使用它并设置实际的Point3D值(使用您的代码名称):

private void MoveCamera(object sender, EventArgs e) {
    Point3DAnimationUsingKeyFrames cameraAnimation = 
        (Point3DAnimationUsingKeyFrames)Resources["CameraMoveAnimation"];
    cameraAnimation.KeyFrames[0].Value = myPoint3D;
    cameraAnimation.KeyFrames[1].Value = myPoint3dz;
    Camera.BeginAnimation(PerspectiveCamera.PositionProperty, cameraAnimation);
}