0

How to Wait for a RoutedEvent? Since there is no definition for GetAwaiter i can't use the await keyword. So how should i modify the Code so that it waits for completion of the GIF Animation?

The Code who calls the RoutedEvent:

    public static async Task<Boolean> Draw(List<Point> points, int counter, Polyline current, Color color, MainWindow main)
    {
        current.Stroke = new SolidColorBrush(color);
        current.Points.Clear();

        for (int i = 0; i < points.Count; i++)
        {
            await Task.Delay(TimeSpan.FromMilliseconds(1));
            current.Points.Add(points[i]);

            if(i == points.Count - 1)
            {
                var completed = new XamlAnimatedGif.AnimationCompletedEventArgs(current);
                await ShowExplosion(main, current.Points.ElementAt(i));
            }
        }
        points.Clear();
        current = null;

        return true;
    }

an the RoutedEvent:

    static RoutedEvent ShowExplosion(MainWindow main, Point coordinate)
    {
        Image explosion = new Image();
        explosion.Width = 40;
        explosion.Height = 40;
        Canvas.SetLeft(explosion, coordinate.X - 20);
        Canvas.SetTop(explosion, coordinate.Y - 20);

        //Relative URI
        var resourcePath = new Uri("pack://application:,,,/Resources/GIF/Explosion2_trsp.gif");
        XamlAnimatedGif.AnimationBehavior.SetSourceUri(explosion, resourcePath);

        XamlAnimatedGif.AnimationBehavior.SetRepeatBehavior(explosion, new System.Windows.Media.Animation.RepeatBehavior(1));
        XamlAnimatedGif.AnimationBehavior.SetAutoStart(explosion, true);

        main.canvas_shots.Children.Add(explosion);

        return XamlAnimatedGif.AnimationBehavior.AnimationCompletedEvent;
    }
Chessmate
  • 61
  • 9

1 Answers1

0

You don't await events. Events are synchronous and a different concept than asynchronous methods. While you await asynchronous methods, you listen to events by registering an event handler i.e. callback with the event source (Events (C# Programming Guide), Routed events overview (WPF .NET)).

Unless you have a reference to the event source, you attach an event handler to an element along the event route using the UIElement.AddHandler method. In your case the parent MainWindow:

main.AddHandler(XamlAnimatedGif.AnimationBehavior.AnimationCompletedEvent, OnAnimationCompleted);

Your fixed code:

public static bool Draw(List<Point> points, int counter, Polyline current, Color color, MainWindow main)
{
  current.Stroke = new SolidColorBrush(color);
  current.Points.Clear();

  for (int i = 0; i < points.Count; i++)
  {
    current.Points.Add(points[i]);

    if (i == points.Count - 1)
    {
      var completed = new XamlAnimatedGif.AnimationCompletedEventArgs(current);
      ShowExplosion(main, current.Points.ElementAt(i));
    }
  }
  points.Clear();
  current = null;

  return true;
}

static void ShowExplosion(MainWindow main, Point coordinate)
{
  Image explosion = new Image();
  explosion.Width = 40;
  explosion.Height = 40;
  Canvas.SetLeft(explosion, coordinate.X - 20);
  Canvas.SetTop(explosion, coordinate.Y - 20);

  //Relative URI
  var resourcePath = new Uri("pack://application:,,,/Resources/GIF/Explosion2_trsp.gif");
  XamlAnimatedGif.AnimationBehavior.SetSourceUri(explosion, resourcePath);

  XamlAnimatedGif.AnimationBehavior.SetRepeatBehavior(explosion, new System.Windows.Media.Animation.RepeatBehavior(1));
  XamlAnimatedGif.AnimationBehavior.SetAutoStart(explosion, true);

  main.canvas_shots.Children.Add(explosion);

  // Listen to the event by registering a callback (event handler)
  main.AddHandler(XamlAnimatedGif.AnimationBehavior.AnimationCompletedEvent, OnAnimationCompleted);
}

private void OnAnimationCompleted(object sender, AnimationCompletedEventArgs e)
{
  var main = sender as UIElement;
  main.RemoveHandler(XamlAnimatedGif.AnimationBehavior.AnimationCompletedEvent, OnAnimationCompleted);

  // TODO::Do something after the animation has completed...
}
BionicCode
  • 1
  • 4
  • 28
  • 44