title: WPF - Storyboard completed event
body: <p>I'm designing a game like this</p>
  
  <pre><code>class Anima
  {
      Storyboard story;
      Random rand;
      Canvas canvas;
      Ellipse target;
  
      public Anima() {
          rand = new Random();
          canvas = new Canvas();
          target = new Ellipse();
  
          target.Fill = Brushes.Red;
          target.Width = 50;
          target.Height = 50;
          Canvas.SetLeft(target, rand.NextDouble() * 300);
          Canvas.SetTop(target, rand.NextDouble() * 300);
          canvas.Children.Add(target);
  
          story = new Storyboard();
          story.BeginTime = TimeSpan.FromMilliseconds(rand.Next(500, 5000));
  
          DoubleAnimation a = new DoubleAnimation();
          a.To = rand.NextDouble() * 300;
          a.Duration = new Duration(TimeSpan.FromMilliseconds(50));
  
          Storyboard.SetTarget(a, target);
          Storyboard.SetTargetProperty(a, new PropertyPath(Canvas.LeftProperty));
          story.Children.Add(a);
  
          DoubleAnimation b = new DoubleAnimation();
          b.To = rand.NextDouble() * 300;
          b.Duration = new Duration(TimeSpan.FromMilliseconds(50));
  
          Storyboard.SetTarget(b, target);
          Storyboard.SetTargetProperty(b, new PropertyPath(Canvas.TopProperty));
          story.Children.Add(b);
  
          story.Completed += new EventHandler(story_Completed);
  
          Window win = new Window();
  
          win.Loaded += delegate(object sender, RoutedEventArgs e) {
              story.Begin();
          };
  
          win.Content = canvas;
          win.Show();
      }
  
      void story_Completed(object sender, EventArgs e) {
          int next = rand.Next(500, 5000);
          double left = rand.NextDouble() * 300;
          double top = rand.NextDouble() * 300;
  
          Console.WriteLine("position: ({0:G6}, {1:G6})", Canvas.GetLeft(target), Canvas.GetTop(target));
          Console.WriteLine("state   : wait for " + next + " ms");
          Console.WriteLine("next    : ({0:G6}, {1:G6})", left, top);
          Console.WriteLine();
  
          (story.Children[0] as DoubleAnimation).To = left;
          (story.Children[1] as DoubleAnimation).To = top;
  
          story.BeginTime = TimeSpan.FromMilliseconds(next);
          story.Begin();
      }
  }
  </code></pre>
  
  <p>Everything is great, but I found that the ellipse didn't get the right position and make an error about 2% to 50%. It seems like the Storyboard.Completed event triggered before the end of animation.</p>
  
  <p>What's wrong with it?</p>