Frage

Wie kann ich ein Storyboard in XAML entfernen (dh Removestoryboard -Aktion in einem DataTrigger), aber den Wert behalten, der animiert wurde. Ähnlich wie Animatable.Beginanimation:

Wenn der BeginTime der Animation null ist, werden aktuelle Animationen entfernt und der aktuelle Wert der Immobilie wird gehalten.

War es hilfreich?

Lösung

Die primäre Verwendung von Removestoryboard besteht darin, die animierten Werte zu entfernen und sie wieder in ihren nicht animierten Zustand zu setzen. In den meisten Fällen können Sie den Anruf auf Pausestoryboard oder StopStoryboard stattdessen abhängig vom spezifischen Fall umstellen. Die einzige Ausnahme ist, wenn Sie Ressourcen freilegen müssen, die vom Storyboard gehalten oder für einen anderen Zweck verwendet werden.

Wenn Sie das Storyboard wirklich entfernen und die Eigenschaftswerte aufbewahren möchten, müssen Sie die animierten Werte direkt auf den Eigenschaften festlegen. Dies kann durch Einstellen jedes Wertes auf den animierten Wert und so etwas erfolgen:

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));

  }
}

Rufen Sie dies direkt an, bevor Sie das Storyboard entfernen, um die animierten Werte zu kopieren.

Bearbeiten Es wurde ein Kommentar abgegeben, dass dieser Code unnötig sein kann, da die Anrufung mit Begintime = null einen ähnlichen Effekt erzielt.

Während es wahr ist, dass BeginniNimation mit Begintime = Null so aussieht, als ob die Werte in lokal kopiert wurden, führt ein späterer Aufruf zum Removestoryboard dazu, dass die Werte zurückgekehrt sind. Dies liegt daran, dass Beginnanimation mit BeginTime = Null dazu führt, dass die vorherige Animation ihre Werte bis zum Beginn der neuen Animation hält, aber nichts, was die lokalen Werte beeinflusst.

Der obige Code überschreibt tatsächlich lokale Werte, sodass alle Animationen entfernt werden können und die Objekte weiterhin ihre neuen Werte haben. Wenn Sie also Removestoryboard wirklich anrufen und Ihre Werte trotzdem behalten möchten, benötigen Sie den oben geschriebenen Code oder so etwas.

Andere Tipps

Ich hatte ein ähnliches Problem, wenn ich benutzte AnimationTimeline. Die einfachste Lösung stellte sich heraus, dass er die erfasst hat Completed Ereignis im Code hinter und vor dem Anruf BeginAnimation mit dem null Parameter Um die Animation zu entfernen, den aktuellen Wert der Eigenschaft abzurufen und mit dieser einzustellen.

Dies erhält den letzten animierten Wert und legt ihn fest.

void OnCompleted( object sender, EventArgs args )
{
    // Required to copy latest animated value to local value.
    o.SomeValue = o.SomeValue;
    o.BeginAnimation( SomeClass.SomeValueProperty, null );
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top