2010-02-26 9 views
8

Ho creato una sottoclasse semplice di StackPanel che è possibile spostare sullo schermo utilizzando un TranslateTransform animato. Ecco come si presenta:Perché queste animazioni non funzionano quando utilizzo uno storyboard?

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."); 
    } 
} 

E qui è il mio problema: Se io animare le proprietà X e Y direttamente, come il codice di cui sopra fa, funziona. Ma se uso sopra il codice commentato sopra, che è davvero la creazione più semplice di un codice Storyboard immaginabile, non succede nulla. L'animazione viene eseguita - almeno, l'evento Completato viene sollevato - ma nulla cambia sullo schermo.

Chiaramente sto facendo qualcosa di sbagliato, ma non riesco a vedere cosa sia. Ogni esempio di creazione di storyboard nel codice che ho visto sembra proprio questo. C'è ovviamente qualcosa riguardo le animazioni e gli storyboard che ancora non conosco: cos'è?

+1

FYI - Ho postato questo come un bug su Microsoft Connect. https://connect.microsoft.com/VisualStudio/feedback/details/723701/storyboard-settarget-only-works-on-uielements-but-throws-no-exception –

risposta

10

Come si è visto, non è possibile utilizzare la sintassi percorso proprietà in questo caso, perché le proprietà di essere animati non sono proprietà di un FrameworkElement. Almeno, è così che io interpreto l'eccezione notevolmente sconcertante che ottengo quando faccio il cambiamento che Anvaka suggerito:

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

Per animare coloro che, a quanto pare, devo usare un NameScope e utilizzare SetTargetName di nominare il TransformElement . Quindi, finché passo lo FrameworkElement che imposto l'ambito del nome sul metodo Begin, lo storyboard può trovare l'oggetto e le proprietà e animarle e tutto funziona. Il risultato finale è il seguente:

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

È la sintassi property path. Il seguente approccio funziona:

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); 
} 
Problemi correlati