Although XAML is not dependent on WPF, visual elements are not. In particular, animation and layout are part of WPF and depend on the presence of the WPF system — through an Application, PresentationSource object such as HwndSource, XBAP PresentationHost.exe, etc.
So you can read in your XAML and get a graphical object of the Test object with a child Storyboard object, but this test object is not connected to the animation or layout mechanisms until it is placed in the WPF context. All that XAML receives is a dumb graphic object in memory: it is WPF, not XAML, which makes the objects “live”.
Since, as Ben says, you will probably have to “push or push” the animation. I don't know any documentation on how to do this, but because it works in Reflector, it looks like the Storyboard.SeekAlignedToLastTick API key the docs are talking about:
The values ​​updated immediately reflect the changes caused by SeekAlignedToLastTick, although the screen does not reflect these changes until the screen refreshes.
Please note that the second sentence. Typically, WPF handles updating the screen as the values ​​of visual objects change. If you are not using WPF, you need to read the changed values ​​and redraw the screen accordingly: you do not have a WPF layout manager to process it.
Finally, note that I have not tested whether SeekAlignedToLastTick will work in an environment without loading WPF plumbing. It seems like it should be, because it doesn’t matter if it is WPF or the user code that controls the clock, but I can’t make any promises ... although I admit I'm curious!
UPDATE: I did it quickly and it seems to work. Here is a demonstration of hosting animations in Windows Forms (in this case using a simple Windows Forms timer, but in XNA I assume that the structure will provide you with a game timer - I haven’t tried because I don’t know XNA). Suppose you have a vanilla Windows form with a timer (timer1) and a label (label1), and the project references WPF assemblies.
Firstly, my simplified version of your class:
[ContentProperty("Animation")] public class Fie : DependencyObject { public double Test { get { return (double)GetValue(TestProperty); } set { SetValue(TestProperty, value); } } public static readonly DependencyProperty TestProperty = DependencyProperty.Register("Test", typeof(double), typeof(Fie), new FrameworkPropertyMetadata(0.0)); public Storyboard Animation { get; set; } }
Now, the WPF code to load one of these babies from XAML and start the animation:
private Fie _f; private DateTime _startTime; public Form1() { InitializeComponent(); string xaml = @"<local:Fie xmlns:local=""clr-namespace:AnimationsOutsideWpf;assembly=AnimationsOutsideWpf"" xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" > <Storyboard> <DoubleAnimation Storyboard.TargetProperty=""Test"" From=""0"" To=""360"" Duration=""00:00:10.0""/> </Storyboard> </local:Fie>"; _f = (Fie)XamlReader.Load(XmlReader.Create(new StringReader(xaml))); Storyboard.SetTarget(_f.Animation, _f); _f.Animation.Begin(); _startTime = DateTime.Now; timer1.Enabled = true; }
Please note that I needed to set the storyboard target as the XAML object I just downloaded. This does not happen automatically. I tried to do this using Storyboard.TargetName in XAML, but that didn't seem to work - you might have more luck.
The final lines are just a setting for a timer callback:
private void timer1_Tick(object sender, EventArgs e) { TimeSpan sinceStart = DateTime.Now - _startTime; _f.Animation.SeekAlignedToLastTick(sinceStart); label1.Text = _f.Test.ToString(); }
I saved the start time of the animation and used this to calculate how far we are in the animation. WinForms timers are a little rude, but that's enough to prove the concept; no doubt XNA will have something better. Then I call Storyboard.SeekAlignedToLastTick, which updates the animated values. Nothing is displayed automatically because my XAML object is not connected for display, but I can check its Test property and make sure it really animates. In fact, I would use this to update the position or orientation of any XNA visual element represented by an XAML object.