2010-02-26 12 views
8

He creado una subclase simple de StackPanel que puedo mover en la pantalla usando un TranslateTransform animado. Se ve así:¿Por qué estas animaciones no funcionan cuando estoy usando un guión gráfico?

public class MovingStackPanel : StackPanel 
{ 
    public void BeginMove(Point translatePosition) 
    { 
     RenderTransform = new TranslateTransform(); 
     Duration d = new Duration(new TimeSpan(0, 0, 0, 0, 400)); 
     DoubleAnimation x = new DoubleAnimation(translatePosition.X, d); 
     DoubleAnimation y = new DoubleAnimation(translatePosition.Y, d); 
     /* 
     Storyboard.SetTarget(x, RenderTransform); 
     Storyboard.SetTargetProperty(x, new PropertyPath("X")); 

     Storyboard.SetTarget(y, RenderTransform); 
     Storyboard.SetTargetProperty(y, new PropertyPath("Y")); 

     Storyboard sb = new Storyboard(); 
     sb.Children.Add(x); 
     sb.Children.Add(y); 
     sb.Completed += sb_Completed; 
     sb.Begin(); 
     */ 
     RenderTransform.BeginAnimation(TranslateTransform.XProperty, x); 
     RenderTransform.BeginAnimation(TranslateTransform.YProperty, y); 
    } 

    void sb_Completed(object sender, EventArgs e) 
    { 
     Console.WriteLine("Completed."); 
    } 
} 

Y aquí es mi problema: Si el animo propiedades X e Y directamente, ya que el código anterior hace, funciona. Pero si uso el código comentado arriba, que es realmente la creación más simple de un código Storyboard imaginable, no pasa nada. La animación se ejecuta, al menos, el evento Completado se levanta, pero nada cambia en la pantalla.

Claramente estoy haciendo algo mal, pero no puedo ver qué es. Cada ejemplo de creación de guiones gráficos en el código que he visto se ve así. Obviamente, hay algo sobre animaciones y guiones gráficos que aún no conozco: ¿qué es?

+1

FYI - He publicado esto como un error en Microsoft Connect. https://connect.microsoft.com/VisualStudio/feedback/details/723701/storyboard-settarget-only-works-on-uielements-but-throws-no-exception –

Respuesta

10

Como resultado, no se puede utilizar la sintaxis ruta propiedad en este caso, ya que las propiedades están animados no son propiedades de un FrameworkElement. Al menos, así es como interpreto la excepción notable desconcertante que tengo cuando hago el cambio que Anvaka sugirió:

Cannot automatically create animation clone for frozen property values on  
'System.Windows.Media.TranslateTransform' objects. Only FrameworkElement and 
FrameworkContentElement (or derived) types are supported. 

Para animar a los, al parecer, tengo que usar un NameScope y utilizar SetTargetName para nombrar el TransformElement . Luego, mientras pase el FrameworkElement que establecí el alcance del nombre en el método Begin, el guión gráfico puede encontrar el objeto y las propiedades y animarlos y todo funciona. El resultado final se ve así:

public void BeginMove(Point translatePosition) 
{ 
    NameScope.SetNameScope(this, new NameScope()); 

    RenderTransform = new TranslateTransform(); 
    RegisterName("TranslateTransform", RenderTransform); 

    Duration d = new Duration(new TimeSpan(0, 0, 0, 0, 400)); 
    DoubleAnimation x = new DoubleAnimation(translatePosition.X, d); 
    DoubleAnimation y = new DoubleAnimation(translatePosition.Y, d); 

    Storyboard.SetTargetName(x, "TranslateTransform"); 
    Storyboard.SetTargetProperty(x, new PropertyPath(TranslateTransform.XProperty)); 

    Storyboard.SetTargetName(y, "TranslateTransform"); 
    Storyboard.SetTargetProperty(y, new PropertyPath(TranslateTransform.YProperty)); 

    Storyboard sb = new Storyboard(); 
    sb.Children.Add(x); 
    sb.Children.Add(y); 
    sb.Completed += sb_Completed; 

    // you must pass this to the Begin method, otherwise the timeline won't be 
    // able to find the named objects it's animating because it doesn't know 
    // what name scope to look in 

    sb.Begin(this); 

} 
7

Tiene una sintaxis de property path. El siguiente enfoque funciona:

public void BeginMove(Point translatePosition) 
{ 
    RenderTransform = new TranslateTransform(); 
    Duration d = new Duration(new TimeSpan(0, 0, 0, 0, 400)); 
    DoubleAnimation x = new DoubleAnimation(translatePosition.X, d); 
    DoubleAnimation y = new DoubleAnimation(translatePosition.Y, d); 

    Storyboard.SetTarget(x, this); 
    Storyboard.SetTargetProperty(x, 
       new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.X)")); 

    Storyboard.SetTarget(y, this); 
    Storyboard.SetTargetProperty(y, 
       new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.Y)")); 

    Storyboard sb = new Storyboard(); 
    sb.Children.Add(x); 
    sb.Children.Add(y); 
    sb.Completed += sb_Completed; 
    sb.Begin(); 

    //RenderTransform.BeginAnimation(TranslateTransform.XProperty, x); 
    //RenderTransform.BeginAnimation(TranslateTransform.YProperty, y); 
} 
Cuestiones relacionadas