Aunque XAML es independiente de WPF, los elementos visuales no lo son. En particular, la animación y el diseño son parte de WPF, y depende de la instalación de cañerías de WPF estar presente - a través de un objeto de aplicación, un PresentationSource tales como HwndSource, el XBAP PresentationHost.exe, etc.
Por lo que puede lee en tu XAML y obtén un gráfico de objeto de un objeto Test con un objeto Child Storyboard, pero ese objeto Test no está conectado a los motores de animación o diseño hasta que se coloca en un contexto WPF. Todo lo que obtiene XAML es un gráfico de objetos en memoria: es WPF, no XAML, lo que hace que los objetos "vivan".
Así que, como dice Ben, probablemente termines necesitando "empujar o pinchar" la animación tú mismo. No estoy al tanto de ninguna documentación sobre cómo hacer esto, pero a partir de hurgar en el reflector, parece que la API clave es Storyboard.SeekAlignedToLastTick, de los cuales los documentos dicen:
Los valores se actualizan de inmediato a reflejan la cambios debido a SeekAlignedToLastTick, aunque la pantalla no refleja estos cambios hasta que la pantalla se actualice.
Observe esa segunda cláusula. Normalmente, WPF maneja la actualización de la pantalla a medida que cambian los valores del objeto visual. Si no está utilizando WPF, le corresponde a usted leer los valores modificados y volver a dibujar la pantalla en consecuencia: no tiene el administrador de diseño WPF para manejarlo por usted.
Finalmente, tenga en cuenta que no he probado si SeekAlignedToLastTick funcionará en un entorno sin la tubería WPF cargada. Es suena como debería, porque no importa si es WPF o código de usuario el que está manejando los relojes, pero no puedo hacer ninguna promesa ... ¡aunque admito que me tienes curiosidad!
ACTUALIZACIÓN: le he dado un ir rápido, y parece que no funciona. Aquí hay una demo de alojar una animación dentro de Windows Forms (en este caso usando un simple temporizador de Windows Forms, pero en XNA supongo que el marco proporcionará un temporizador de juego para ti, no lo intenté porque no sé XNA). Supongamos que tiene un Windows Form de vanilla con un temporizador (timer1) y una etiqueta (label1), y que el proyecto hace referencia a los ensamblajes de WPF.
En primer lugar, mi versión simplificada de su clase:
[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; }
}
Ahora, el código de WPF para cargar uno de estos bebés de XAML y comenzar la animación:
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;
}
Tenga en cuenta que tenía que establecer el objetivo del guión gráfico para que sea el objeto XAML que acababa de cargar. Esto no sucede automáticamente Intenté hacer esto con Storyboard.TargetName en el XAML, pero eso no pareció funcionar; es posible que tengas más suerte.
Las líneas finales son sólo para la configuración de la devolución de llamada de temporizador:
private void timer1_Tick(object sender, EventArgs e)
{
TimeSpan sinceStart = DateTime.Now - _startTime;
_f.Animation.SeekAlignedToLastTick(sinceStart);
label1.Text = _f.Test.ToString();
}
me he guardado la hora de inicio de la animación, y se utiliza para el cálculo de que hasta qué punto en la animación que somos. Los temporizadores de WinForms son un tanto toscos, pero esto es suficiente como prueba de concepto; sin dudas, XNA tendrá algo mejor. Luego llamo Storyboard.SeekAlignedToLastTick, que actualiza los valores animados. Nada se muestra automáticamente porque mi objeto XAML no está conectado para su visualización, pero puedo verificar su propiedad de prueba y verificar que de hecho esté animando. En realidad, usaría esto para actualizar la posición u orientación del elemento visual XNA que representa el objeto XAML.
¡Qué idea tan genial! ¿Has probado la depuración de animaciones en las aplicaciones normales de WPF para ver qué componentes activan las actualizaciones? –
Sé que esta es una vieja pregunta, pero tengo curiosidad sobre qué tan lejos llegaste con esto? He estado jugando con la idea de alojar XAML dentro de XNA yo mismo. Incluso esta pregunta que muestra cómo agregar animaciones básicas es un gran comienzo. –