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 :)