XAML Without WPF - Animations

animation, wpf, xaml, xna

Solution

Just for reference, I will now document how I managed to make this work with XNA. Thanks to itowlson for providing the missing link: otherwise I had to create an empty Application with an invisible Window...

We define the class with its animation in XAML (notice the xmlns directives):

<l:Test 
      xmlns:l="clr-namespace:XAMLAndXNA;assembly=XAMLAndXNA"
      xmlns:a1="clr-namespace:System.Windows.Media.Animation;assembly=PresentationFramework"
      xmlns:a2="clr-namespace:System.Windows.Media.Animation;assembly=PresentationCore"
  Text="Testo" Position="55,60" Color="0,255,255,255">
  <a1:Storyboard>
    <a2:DoubleAnimation a1:Storyboard.TargetProperty="Rotation"
                              From="0"
                              To="6.28"
                              Duration="00:00:2.0"
                              RepeatBehavior="Forever"/>
  </a1:Storyboard>
</l:Test>

The "code-behind" class Test is the following:

[ContentPropertyAttribute("Animation")]
public class Test : DependencyObject
{
  public string Text { get; set; }
  public Vector2 Position { get; set; }
  public Color Color { get; set; }
  public Storyboard Animation { get; set; }

  public static DependencyProperty RotationProperty =
    DependencyProperty.Register("Rotation", typeof(double), typeof(Test), new PropertyMetadata(0.0));
  public double Rotation { get { return (double)GetValue(RotationProperty); } set { SetValue(RotationProperty, value); } }
}

In the Initialize function of the XNA Game class we deserialize our xaml file and start the animation:

test = XamlReader.Load(new XmlTextReader("SpriteBatchStuff.xaml")) as Test;
Storyboard.SetTarget(test.Animation, test);
test.Animation.Begin();

The Update function takes as input a GameTime, which offers the TotalGameTime field that stores the TimeSpan of the amount of time passed since the app launch: that is exactly what a Storyboard needs to tick:

protected override void Update(GameTime gameTime)
{
  // Allows the game to exit
  if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
    this.Exit();

  test.Animation.SeekAlignedToLastTick(gameTime.TotalGameTime);

  base.Update(gameTime);
}

In the draw method we can just draw some text using the Rotation property, which will now be correctly animated:

protected override void Draw(GameTime gameTime)
{
  GraphicsDevice.Clear(Color.CornflowerBlue);

  spriteBatch.Begin();
  spriteBatch.DrawString(Content.Load<SpriteFont>("font"), test.Text, test.Position, test.Color, (float)test.Rotation, Vector2.Zero, 1.0f, SpriteEffects.None, 0.0f);
  spriteBatch.End();

  base.Draw(gameTime);
}

Problem

I am trying to use XAML completely outside WPF, in particular inside an XNA application. So far, I have managed (quite easily, I am surprised to admit) to load some data inside my XNA application from a XAML file. The problems start when I decided that I wanted to animate one of the properties of my class...Nothing happens :( Here is the main class I load from the XAML file: ``` [ContentPropertyAttribute("Animation")] public class Test : FrameworkContentElement { public string Text { get; set; } public Vector2 Position { get; set; } public Color Color { get; set; } public Storyboard Animation { get; set; } public static DependencyProperty RotationProperty = DependencyProperty.Register("Rotation", typeof(double), typeof(Test), new PropertyMetadata(0.0)); public double Rotation { get { return (double)GetValue(RotationProperty); } set { SetValue(RotationProperty, value); } } } ``` Here is the XAML file: ``` <l:Test xmlns:l="clr-namespace:XAMLAndXNA;assembly=XAMLAndXNA" xmlns:a1="clr-namespace:System.Windows.Media.Animation;assembly=PresentationFramework" xmlns:a2="clr-namespace:System.Windows.Media.Animation;assembly=PresentationCore" Text="Testo" Position="55,60" Color="0,255,255,255"> <a1:Storyboard> <a2:DoubleAnimation a1:Storyboard.TargetProperty="Rotation" From="0" To="360" Duration="00:00:10.0"/> </a1:Storyboard> </l:Test> ``` And here is the loading and animation launching (attempt): ``` Test test = XamlReader.Load(new XmlTextReader("SpriteBatchStuff.xaml")) as Test; test.Animation.Begin(test); ``` I am dying of curiosity :)

Original source