5

Estoy jugando con Storyboards en una aplicación Metro XAML. Tengo que crear un Storyboard en el código. Me gustaría establecer el Storyboard.TargetProperty a CompositeTransform.RotationNo se puede establecer Storyboard.TargetProperty en CompositeTransform.Rotation en la aplicación de estilo Metro desde el código

Parece imposible ...

Mi Storyboard en XAML se ve así:

<Storyboard> 
    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="grid"> 
     <EasingDoubleKeyFrame KeyTime="0" Value="0"/> 
     <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="60"/ 
    </DoubleAnimationUsingKeyFrames> 
</Storyboard> 

me gustaría crear algo similar.
Importante: No estoy tratando de recrear este Storyboard exacto. Estoy dentro del código de un ContentControl personalizado, así que this es el Control, y no hay una "cuadrícula" para apuntar a la animación. El objetivo es el control en sí, que tiene CompositeTransform previamente establecido.

Mi código hasta ahora es así:

var turnSB = new Storyboard(); 

var doubleAnim = new DoubleAnimationUsingKeyFrames(); 
doubleAnim.KeyFrames.Add(new EasingDoubleKeyFrame() { KeyTime = TimeSpan.FromMilliseconds(0), Value = currentAngle }); 
doubleAnim.KeyFrames.Add(new EasingDoubleKeyFrame() { KeyTime = TimeSpan.FromMilliseconds(500), Value = targetAngle }); 

turnSB.Children.Add(doubleAnim); 

Storyboard.SetTarget(doubleAnim, this.RenderTransform); 
Storyboard.SetTargetProperty(doubleAnim, "(CompositeTransform.Rotation)"); 

turnSB.Begin(); 

Tan pronto como llega el método Begin consigo una excepción diciendo que (CompositeTransform.Rotation) no puede ser resuelto. Así que supongo que no obtuve el camino correcto. He intentado diferentes variaciones, pero de acuerdo con PropertyPaths, esta debería ser la correcta, ¿no es así? : S

Si esto es un problema sin solución, estoy abierto a sugerencias sobre una solución ...

EDIT:

Creo que he resuelto el problema por el momento. Aunque tengo algunos hallazgos interesantes ...

Si hago un UserControl, puedo hacer prácticamente cualquier cosa. Todo funciona, puedo configurar Storyboard.Targetproperty, y la animación se reproduce correctamente.

Sin embargo, si uso un control personalizado o heredo de otro control (digamos ContentControl), no puedo iniciar un Storyboard desde el código, solo en algunos casos.

Por ejemplo: si hago un guión gráfico (definido en XAML) para animar la rotación (o cualquier propiedad de transformación para ese caso) e intento iniciar desde el código, obtengo la excepción anterior. Pero si animo una propiedad simple, digamos Opacidad, funciona bien.
(Hice lo mismo con un UserControl, y funcionó.)

¿Alguien puede explicar esto?

+0

estoy teniendo el mismo problema, tener una clase herede del control de cuadrícula, guiones gráficos, simplemente ganó' comenzar –

+0

Una cosa a tener en cuenta es que Grid no se hereda de Control, por lo que no es realmente un control personalizado que está creando. –

+0

No estaba usando Grid, heredaba de ContentControl. El xaml era de un intento anterior, donde tenía un UserControl que tenía una Grilla, y ese era el objetivo de la animación. Pero en cuanto a esta situación, el objetivo debería ser el control en sí mismo. Lo cual, si lo lees cuidadosamente, lo describí en la sección "Importante". – Tenshiko

Respuesta

4

Desde el MSDN docs parece que necesita establecer toda la ruta de la cadena. Así que para la animación se describe en el XAML, lo que se necesita para establecer el TargetProperty como tal

Storyboard.SetTargetProperty(doubleAnim, "(UIElement.RenderTransform).(CompositeTransform.Rotation)"); 

ACTUALIZACIÓN: encontrado este blog post que se suma la línea de tiempo como un hijo del guión gráfico. Pruebe lo siguiente:

Storyboard.SetTarget(doubleAnim, this.RenderTransform); 
Storyboard.SetTargetProperty(doubleAnim, "Rotation"); // maybe "CompositeTransform.Rotation" 
storyboard.Children.Add(doubleAnim); 
+0

He intentado todas las combinaciones de estos. Los resultados fueron siempre los mismos – Tenshiko

+0

He llegado a la conclusión de que el problema no está en la configuración del guión gráfico. De hecho, su primera sugerencia funciona ahora, pero solo con UserControls. Me gustaría saber más sobre el tema, tal vez alguien pueda arrojar algo de luz sobre él. Pero si no, aceptaré tu respuesta. Thx :) – Tenshiko

+0

¿Así que esto está dentro de un control personalizado? –

4

Creo que la razón por la que obtiene este error es debido a que no ejemplariza la propiedad RenderTransform del control personalizado.

public class CustomControl2 : Control 
{ 
    public CustomControl2() 
    { 
     this.DefaultStyleKey = typeof(CustomControl2); 
    } 

    protected override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 
    } 

    public void RunAnimation() 
    { 
     //this.RenderTransform = new CompositeTransform(); 
     this.Background = new SolidColorBrush(Color.FromArgb(0xFF, 0x33, 0xC8, 0x9C)); 

     var turnSB = new Storyboard(); 

     var doubleAnim = new DoubleAnimationUsingKeyFrames(); 
     doubleAnim.KeyFrames.Add(new EasingDoubleKeyFrame() { KeyTime = TimeSpan.FromMilliseconds(0), Value = 10 }); 
     doubleAnim.KeyFrames.Add(new EasingDoubleKeyFrame() { KeyTime = TimeSpan.FromMilliseconds(500), Value = 30 }); 

     turnSB.Children.Add(doubleAnim); 

     Storyboard.SetTarget(doubleAnim, this.RenderTransform); 
     Storyboard.SetTargetProperty(doubleAnim, "(CompositeTransform.Rotation)"); 

     turnSB.Begin(); 
    } 
} 

Nota en el código anterior, si comento hacia fuera de la primera línea bajo el método RunAnimation, me va a lanzar el mismo error que está recibiendo.

Luego creé este control en mi página principal, y también creé un Button para iniciar la animación.

private void Button_Click_1(object sender, RoutedEventArgs e) 
{ 
    this.MyControl.RunAnimation(); 
} 

Probé el código anterior y funcionó bien.

+0

Veo por qué esto debería funcionar, pero como dije en mi publicación original, configuré la Transformación (lea de nuevo la sección "Importante"). Y qué más, pude reproducir el mismo efecto con una solución más simple. Déjame revisarlo de nuevo y luego volveré contigo. – Tenshiko

+0

Una cosa en la que puedo pensar es, ¿quizás comienzas la anmiación antes de que se llame a 'OnApplyTemplate'? –

1

lo resolvió

El problema está en la ruta de acceso al elemento estás usando, su tiene que derivar de la clase padre extenderla a la propiedad en sí. Tengo que trabajar en mi propio control de modo hizo un pequeño ejemplo, puede copiar y pegar (CÓDIGO no probado):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls; 
using Windows.UI.Xaml.Media; 
using Windows.UI.Xaml.Media.Animation; 

namespace CustomControls 
{ 
    /// <summary> 
    /// Author: Frank Wolferink 
    /// Note: example is untested and comes as is. I hope it save's you the time i lost figering this out 
    /// </summary> 
    public class CustomControl : Control 
    { 

     private Storyboard _compositeTransformExampleStoryBoard; 

     private const string TRANSLATE_X_TARGET = "Control.RenderTransform.CompositeTransform.TranslateX"; 
     private const string TRANSLATE_Y_TARGET = "Control.RenderTransform.CompositeTransform.TranslateY"; 
     private const string TRANSLATE_ROTATE_TARGET = "Control.RenderTransform.CompositeTransform.Rotation"; 


     public CustomControl() 
     { 
      this.RenderTransform = new CompositeTransform(); 

      TimeSpan duration = new TimeSpan(0,0,0,0,500); 
      double translateX = 10; 
      double translateY = 10; 
      double rotation = 40; 

      _compositeTransformExampleStoryBoard = BuildStoryboard(duration, translateX, translateY, rotation); 

      this.Loaded += CustomControl_Loaded; 
     } 

     void CustomControl_Loaded(object sender, RoutedEventArgs e) 
     { 
      _compositeTransformExampleStoryBoard.Begin(); 
     } 


     private Storyboard BuildStoryboard(TimeSpan animationDuration, double transistionValueX, double transistionValueY, double rotation) 
     { 
      Storyboard storyboard = new Storyboard(); 

      if (transistionValueX != 0) 
       CreateAnimation(storyboard, transistionValueX, animationDuration, TRANSLATE_X_TARGET); 

      if (transistionValueY != 0) 
       CreateAnimation(storyboard, transistionValueY, animationDuration, TRANSLATE_Y_TARGET); 

      if (rotation != 0) 
       CreateAnimation(storyboard, rotation, animationDuration, TRANSLATE_ROTATE_TARGET); 


      return storyboard; 
     } 

     private void CreateAnimation(Storyboard storyboard, double transistionValue, TimeSpan animationDuration, string targetProperty) 
     { 
      DoubleAnimation da = CreateDoubleAnimation(transistionValue, animationDuration); 
      storyboard.Children.Add(da); 
      Storyboard.SetTarget(da, this); 
      Storyboard.SetTargetProperty(da, targetProperty); 
     } 

     private DoubleAnimation CreateDoubleAnimation(double transistionValue, TimeSpan duration) 
     { 
      return new DoubleAnimation() 
      { 
       Duration = duration, 
       To = transistionValue 
      }; 
     } 

    } 
} 

Cuestiones relacionadas