Microsoft Surface: When is Storyboard#completed called?

592 views Asked by At

I have the following code:

 private void Package_ContactDown(object sender, ContactEventArgs e)
        {
            ScatterViewItem svi = new ScatterViewItem();
            svi.Orientation = 0;
            removeShadow(svi);
            svi.IsActive = true;
            PackageView view = new PackageView(sourceFile, this);
            view.setScatterViewItem(svi);
            svi.Width = 1024;
            svi.Height = 768;
            svi.Center = new Point(512, 384);

            Viewbox box = new Viewbox();
            box.Name = "box";
            box.Child = view;
            this.RegisterName(box.Name, box);

            Viewbox boxSmall = new Viewbox();
            boxSmall.Name = "boxSmall";
            this.RegisterName(boxSmall.Name, boxSmall);
            TextBlock txt = new TextBlock();

            txt.Foreground = Brushes.White;
            txt.Text = "Package of class";
            boxSmall.Child = txt;
            boxSmall.Opacity = 0;
            boxSmall.IsHitTestVisible = false;

            Rectangle border = new Rectangle();
            border.Name = "border";
            this.RegisterName(border.Name, border);
            border.Fill = Brushes.Transparent;
            border.Stroke = Brushes.White;
            border.StrokeThickness = 2;
            border.Opacity = 0;

            Grid g = new Grid();
            g.Background = this.FindResource("WindowBackground") as ImageBrush;
            g.Children.Add(box);
            g.Children.Add(boxSmall);
            g.Children.Add(border);
            svi.Content = g;

            window.IconDisplay.Items.Add(svi);

            DoubleAnimation animation = new DoubleAnimation();
            animation.From = 0.0;
            animation.To = 1.0;
            animation.Duration = new Duration(TimeSpan.FromSeconds(3));
            animation.AutoReverse = false;

            Storyboard storyboard = new Storyboard();
            storyboard.Children.Add(animation);
            Storyboard.SetTargetName(animation, boxSmall.Name);
            Storyboard.SetTargetProperty(animation, new PropertyPath(Viewbox.OpacityProperty));

            DoubleAnimation animation2 = new DoubleAnimation();
            animation2.From = 1.0;
            animation2.To = 0.0;
            animation2.Duration = new Duration(TimeSpan.FromSeconds(3));
            animation2.AutoReverse = false;

            Storyboard storyboard2 = new Storyboard();
            storyboard2.Children.Add(animation2);
            Storyboard.SetTargetName(animation2, box.Name);
            Storyboard.SetTargetProperty(animation2, new PropertyPath(Viewbox.OpacityProperty));

            DoubleAnimation animation3 = new DoubleAnimation();
            animation3.From = 0.0;
            animation3.To = 1.0;
            animation3.Duration = new Duration(TimeSpan.FromSeconds(3));
            animation3.AutoReverse = false;

            Storyboard storyboard3 = new Storyboard();
            storyboard3.Children.Add(animation3);
            Storyboard.SetTargetName(animation3, border.Name);
            Storyboard.SetTargetProperty(animation3, new PropertyPath(Rectangle.OpacityProperty));

            svi.SizeChanged += delegate(object s, SizeChangedEventArgs args)
            {
                if (args.NewSize.Width < 150 && args.NewSize.Height < 150 && !isSmall)
                {
                    svi.CanScale = false;
                    storyboard.Begin(this);
                    storyboard2.Begin(this);
                    storyboard3.Begin(this);
                    storyboard3.Completed += delegate(object sender2, EventArgs args2)
                    {
                        Console.WriteLine("Storyboard completed");
                        svi.CanScale = true;
                    };
                    isSmall = true;
                }

                if (args.NewSize.Width > 150 && args.NewSize.Height > 150 && isSmall)
                {
                    isSmall = false;
                }
            };

        }

And I noticed that the Storyboard#completed Event is never triggered. Why? And an additional question... Is there any way to reverse all these 3 animations? If I want to display the animations the other way round?

1

There are 1 answers

0
evanb On BEST ANSWER

The completed event will not fire the first time around because it is not set before you call the begin method. Set the completed handler then call the begin and you should see the handler get called.

Is there a reason that you have three storyboards? Storyboards can contain multiple animations and you could just put all the animations into one storyboard. This would simplify reversing the storyboard.

        DoubleAnimation animation = new DoubleAnimation();
        animation.From = 0.0;
        animation.To = 1.0;
        animation.Duration = new Duration(TimeSpan.FromSeconds(3));
        animation.AutoReverse = false;

        DoubleAnimation animation2 = new DoubleAnimation();
        animation2.From = 1.0;
        animation2.To = 0.0;
        animation2.Duration = new Duration(TimeSpan.FromSeconds(3));
        animation2.AutoReverse = false;

        DoubleAnimation animation3 = new DoubleAnimation();
        animation3.From = 0.0;
        animation3.To = 1.0;
        animation3.Duration = new Duration(TimeSpan.FromSeconds(3));
        animation3.AutoReverse = false;

        Storyboard storyboard = new Storyboard();
        storyboard.AutoReverse = true;
        storyboard.Children.Add(animation);
        Storyboard.SetTargetName(animation, boxSmall.Name);
        Storyboard.SetTargetProperty(animation, new PropertyPath(Viewbox.OpacityProperty));

        storyboard.Children.Add(animation2);
        Storyboard.SetTargetName(animation2, box.Name);
        Storyboard.SetTargetProperty(animation2, new PropertyPath(Viewbox.OpacityProperty));

        storyboard.Children.Add(animation3);
        Storyboard.SetTargetName(animation3, border.Name);
        Storyboard.SetTargetProperty(animation3, new PropertyPath(Rectangle.OpacityProperty));

        svi.SizeChanged += delegate(object s, SizeChangedEventArgs args)
        {
            if (args.NewSize.Width < 150 && args.NewSize.Height < 150 && !isSmall)
            {
                svi.CanScale = false;
                storyboard.Completed += (o, s) =>
                {
                    Console.WriteLine("Storyboard completed");
                    svi.CanScale = true;
                };
                storyboard.Begin(this);
                isSmall = true;
            }

            if (args.NewSize.Width > 150 && args.NewSize.Height > 150 && isSmall)
            {
                isSmall = false;
            }
        };