2009-11-05 13 views

Antwort

4

Die primäre Verwendung von RemoveStoryboard besteht darin, die animierten Werte zu entfernen und sie in ihren nicht animierten Status zurückzusetzen. In den meisten Fällen können Sie den Aufruf einfach in PauseStoryboard oder StopStoryboard umschalten, abhängig vom jeweiligen Fall. Die einzige Ausnahme ist, wenn Sie Ressourcen freigeben müssen, die vom Storyboard gehalten werden, oder sie für einen anderen Zweck verwenden.

Wenn Sie das Storyboard wirklich entfernen und die Eigenschaftswerte beibehalten möchten, müssen Sie die animierten Werte direkt in den Eigenschaften festlegen.

dieses Recht
void CopyAnimatedValuesToLocalValues(DependencyObject obj) 
{ 
    // Recurse down tree 
    for(int i=0; i<VisualTreeHelper.GetChildrenCount(obj); i++) 
    CopyAnimatedValuesToLocalValues(VisualTreeHelper.GetChild(obj, i)); 

    var enumerator = obj.GetLocalValueEnumerator(); 
    while(enumerator.MoveNext()) 
    { 
    var prop = enumerator.Current.Property; 
    var value = enumerator.Current.Value as Freezable; 

    // Recurse into eg. brushes that may be set by storyboard, as long as they aren't frozen 
    if(value!=null && !value.IsFrozen) 
     CopyAnimatedValuesToLocalValues(value); 

    // *** This is the key bit of code *** 
    if(DependencyPropertyHelper.GetValueSource(obj, prop).IsAnimated) 
     obj.SetValue(prop, obj.GetValue(prop)); 

    } 
} 

Anruf, bevor Sie das Storyboard entfernen Sie die animierten Werte zu kopieren: Dies kann durch Setzen jeden Wert auf den animierten Wert, so etwas getan werden.

bearbeiten Ein Kommentar gemacht wurde, dass dieser Code nicht notwendig sein kann, weil mit Beginanimation Begintime = null erreicht einen ähnlichen Effekt aufrufen.

Obwohl es zutrifft, dass BeginAnimation mit BeginTime = null so aussieht, als ob die Werte in local kopiert würden, führt ein späterer Aufruf von RemoveStoryboard dazu, dass die Werte zurückgesetzt werden. Dies liegt daran, dass BeginAnimation mit BeginTime = null bewirkt, dass die vorherige Animation ihre Werte bis zum Beginn der neuen Animation enthält, sich jedoch nicht auf die lokalen Werte auswirkt.

Der obige Code überschreibt tatsächlich lokale Werte, sodass alle Animationen entfernt werden können und die Objekte immer noch ihre neuen Werte haben. Wenn Sie also RemoveStoryboard wirklich aufrufen und Ihre Werte beibehalten möchten, benötigen Sie den Code, den ich oben geschrieben habe, oder etwas Ähnliches.

+0

Wie ich in meiner Frage erwähnt, möchte ich dazu in XAML. Das Hauptziel ist hier, eine neue Animation basierend auf einem DataTrigger zu starten, der mit dem aktuellen Wert beginnt. AFAIK, wie ich weiß, kann nicht erreicht werden, indem das aktuelle Storyboard angehalten oder gestoppt wird, weil es den aktuellen Wert entweder halten oder zurücksetzen würde. Beachten Sie auch, dass Ihr Code in WPF nicht benötigt wird. Sie können Animatable.BeginAnimation einfach mit einer Animation aufrufen, bei der BeginTime auf null gesetzt ist. Es hat den gleichen Effekt, dass der Wert auf local kopiert wird. – bitbonk

+0

Ich bin mir nicht sicher, ob ich deine Bedürfnisse verstehe. Wenn Sie nur eine neue Animation starten möchten, tun Sie dies einfach, ohne dass Sie eine RemoveAnimation-Aktion ausführen müssen. WPF soll in dieser Situation mit den aktuellen Werten beginnen. Tut es das nicht? –

+0

Es stimmt nicht, dass der Aufruf von BeginAnimation mit BeginTime = null den gleichen Effekt hat wie mein Code. Spezifisch kopiert es keine Werte nach local. Wenn Sie BeginAnimation mit BeginTime = null aufrufen und später RemoveAnimation aufrufen, werden die Werte auf Original zurückgesetzt, da die lokalen Werte nie geändert wurden.Aber wenn Sie meinen Code verwenden, bleiben die Werte erhalten, weil sie tatsächlich nach lokal kopiert werden. Ich habe erklärt, was notwendig ist, um die lokalen Werte zu erhalten, selbst nach RemoveAnimation, und Code, wie ich es geschrieben habe, ist notwendig. Ist das sinnvoll? –

1

Ich hatte ein ähnliches Problem bei der Verwendung AnimationTimeline. Die einfachste Lösung bestand darin, das Ereignis Completed im Code hinter und vor dem Aufruf BeginAnimation mit dem Parameter null einzufangen, um die Animation zu entfernen, den aktuellen Wert der Eigenschaft abzurufen und diesen zu verwenden.

Damit wird der letzte animierte Wert abgerufen und festgelegt.

void OnCompleted(object sender, EventArgs args) 
{ 
    // Required to copy latest animated value to local value. 
    o.SomeValue = o.SomeValue; 
    o.BeginAnimation(SomeClass.SomeValueProperty, null); 
} 
Verwandte Themen