Thursday, 20 March 2008

XAML Animation Differences Between WPF and Silverlight 2

I was working recently on adding some basic animations to a WPF application, and assumed I would simply be able to utilise the same syntax that I would if I was doing the same animation in Silverlight. Wrong!

I started by adding a couple of Storyboards to a Grid.Resources section:

<Page x:Class="LearningGames.NumbersPage"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     Title="NumbersPage" Height="260">
     <Grid>
         <Grid.Resources>
          <Storyboard x:Name="storyboardWrong">
             <DoubleAnimation x:Name="da1" Storyboard.TargetName="labelWrong" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.5" />
             <DoubleAnimation x:Name="da2" Storyboard.TargetName="labelWrong" Storyboard.TargetProperty="Opacity" From="1" To="0" BeginTime="0:0:1" Duration="0:0:0.5" />
         </Storyboard>
         <Storyboard x:Name="storyboardRight">
             <DoubleAnimation x:Name="da3" Storyboard.TargetName="labelRight" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.5" />
             <DoubleAnimation x:Name="da4" Storyboard.TargetName="labelRight" Storyboard.TargetProperty="Opacity" From="1" To="0" BeginTime="0:0:1" Duration="0:0:0.5" />
         </Storyboard>
         </Grid.Resources>

In Silverlight 2, this would be enough. You could simply call storyboardWrong.Begin() in the code behind. But in WPF, things are a bit more complicated:

  • You need to specify x:Key for each Storyboard
  • The XAML compiler doesn't auto-generate member variables for each Storyboard.
  • Storyboards must be found using TryFindResource:
    storyboardWrong = (Storyboard)TryFindResource("storyboardWrong");
  • TryFindResource will only work if the Storyboard is in the Page.Resources section of the XAML
  • When you get round to running the Storyboard, it will need a parameter to the begin method. You can pass the "this" pointer:
    storyboardWrong.Begin(this);

So rather counter-intuitively, Silverlight actually makes some things easier than its more fully featured desktop counterpart WPF. Or am I missing some easier way of doing animation in WPF?

Post a Comment