2010-02-26 16 views
8

Ich habe eine einfache Unterklasse von StackPanel erstellt, die ich mit einem animierten TranslateTransform auf dem Bildschirm bewegen kann. Es sieht wie folgt aus:Warum funktionieren diese Animationen nicht, wenn ich ein Storyboard verwende?

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

Und hier ist mein Problem: Wenn ich die X- und Y-Eigenschaften direkt zu animieren, wie der obige Code funktioniert, es funktioniert. Aber wenn ich den auskommentierten Code darüber verwende, der wirklich die einfachste Kreation eines Storyboard im Code ist, passiert nichts. Die Animation wird ausgeführt - mindestens wird das Ereignis Completed ausgelöst -, aber auf dem Bildschirm ändert sich nichts.

Offensichtlich mache ich etwas falsch, aber ich kann nicht sehen, was es ist. Jedes Beispiel zum Erstellen von Storyboards in Code, die ich gesehen habe, sieht genau so aus. Es gibt offensichtlich etwas über Animationen und Storyboards, die ich noch nicht kenne: Was ist das?

+1

FYI - Ich habe dies als einen Fehler auf Microsoft Connect geschrieben. https://connect.microsoft.com/VisualStudio/feedback/details/723701/storyboard-settarget-only-works-on-uielements-but-throws-no-exception –

Antwort

10

Wie sich herausstellt, können Sie keine Eigenschaft Pfadsyntax in diesem Fall verwendet werden, da sich die Eigenschaften animiert werden, sind nicht Eigenschaften eines FrameworkElement. Zumindest das ist, wie ich die bemerkenswert verwirrende Ausnahme interpretieren, dass ich, wenn ich die Änderung, dass Anvaka vorgeschlagen:

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

Die zu animieren, so scheint es, muß ich ein NameScope verwenden und SetTargetName die TransformElement zu nennen . Dann, solange ich die FrameworkElement übergeben, dass ich den Namen Geltungsbereich auf die Begin-Methode festlegen, kann das Storyboard das Objekt und die Eigenschaften finden und animieren und alles funktioniert. Das Endergebnis sieht folgendermaßen aus:

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

Es ist property path Syntax. Der folgende Ansatz funktioniert:

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); 
} 
Verwandte Themen