Another Silverlight 2.0 Animation Issue

Location: BlogsRainer's BlogSilverlight   
Posted by: Rainer Stropek2008-03-16 13:27:06Z

Today I found another issue concerning Silverlight 2.0 animations: If you reference the same object in one storyboard multiple times you receive a "Catastrophic Failure" error:

Catastrophic Failure in Visual Studio

You can use the following code to reproduce the error. This code snippet should fade in an image and fade it out again immediately after the first animation has finished:

<UserControl x:Class="SilverlightApplication2.Page"
    xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
    <Canvas x:Name="LayoutRoot" Background="White">
  <Image x:Name="Image2" Source="/6_Schuss_2_klein.png" Opacity="0" Width="54" Canvas.ZIndex="1" />
  <Image x:Name="Image1" Source="/6_Schuss_1_klein.png" Opacity="0" Canvas.ZIndex="0" />
 </Canvas>
</UserControl>

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;

namespace SilverlightApplication2
{
 public partial class Page : UserControl
 {
  Storyboard storyboard;

  public Page()
  {
   InitializeComponent();
   Loaded+=new RoutedEventHandler(Page_Loaded);
  }

  void Page_Loaded(object sender, RoutedEventArgs e)
  {
   try
   {
    storyboard = new Storyboard();

    var animation = new DoubleAnimation();
    Storyboard.SetTargetName(animation, "Image1");
    Storyboard.SetTargetProperty(animation, "Opacity");
    animation.To = 1;
    animation.Duration = TimeSpan.FromSeconds(2);
    storyboard.Children.Add(animation);
    Resources.Add(storyboard);

Note that this second animation starts after the first animation (because of BeginTime). It references the same image as the first animation!

    animation = new DoubleAnimation();
    Storyboard.SetTargetName(animation, "Image1");
    Storyboard.SetTargetProperty(animation, "Opacity");
    animation.To = 0;
    animation.Duration = TimeSpan.FromSeconds(2);
    animation.BeginTime = TimeSpan.FromSeconds(2);
    storyboard.Children.Add(animation);

    storyboard.Begin();
   }
   catch (Exception ex)
   {
   }
  }
 }
}

storyboard.Begin throws the exception shown above.

However, if you try the same code with two different images everything runs fine:

using [...];

namespace SilverlightApplication2
{
 public partial class Page : UserControl
 {
  [...]
  void Page_Loaded(object sender, RoutedEventArgs e)
  {
   try
   {
    storyboard = new Storyboard();

    var animation = new DoubleAnimation();
    Storyboard.SetTargetName(animation, "Image1");
    Storyboard.SetTargetProperty(animation, "Opacity");
    animation.To = 1;
    animation.Duration = TimeSpan.FromSeconds(2);
    storyboard.Children.Add(animation);
    Resources.Add(storyboard);

Note that this time the second animation refrences a different image object than the first one!

    animation = new DoubleAnimation();
    Storyboard.SetTargetName(animation, "Image2");
    Storyboard.SetTargetProperty(animation, "Opacity");
    animation.To = 1;
    animation.Duration = TimeSpan.FromSeconds(2);
    animation.BeginTime = TimeSpan.FromSeconds(2);
    storyboard.Children.Add(animation);

    storyboard.Begin();
   }
   catch (Exception ex)
   {
   }
  }
 }
}

If you try the first sample which throws the exception in Silverlight in WPF you will see that it works fine there. Therefore I think the behavior described above is a bug in Silverlight 2.0 Beta 1.

Just for the sake of completeness here is the WPF code that demonstrates two animations on a single object. In contrast to Silverlight it works:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;

namespace WpfApplication2
{
 public partial class Window1 : Window
 {
  Storyboard storyboard;

  public Window1()
  {
   InitializeComponent();
   Loaded += new RoutedEventHandler(Page_Loaded);
  }

  void Page_Loaded(object sender, RoutedEventArgs e)
  {
   try
   {
    storyboard = new Storyboard();

    var animation = new DoubleAnimation();
    Storyboard.SetTargetName(animation, "Image1");
    Storyboard.SetTargetProperty(animation, new PropertyPath(Image.OpacityProperty));
    animation.To = 1;
    animation.Duration = TimeSpan.FromSeconds(1);
    storyboard.Children.Add(animation);
    Resources.Add("sb", storyboard);

    animation = new DoubleAnimation();
    Storyboard.SetTargetName(animation, "Image1");
    Storyboard.SetTargetProperty(animation, new PropertyPath(Image.OpacityProperty));
    animation.To = 0;
    animation.Duration = TimeSpan.FromSeconds(1);
    animation.BeginTime = TimeSpan.FromSeconds(1);
    storyboard.Children.Add(animation);

    storyboard.Begin(this);
   }
   catch (Exception ex)
   {
   }
  }
 }
}

Permalink | Trackback

Your name:
Title:
Comment:
Add Comment  Cancel 

Search Blog

Blog List

Blog Archive