Domanda

Come posso rimuovere uno storyboard in XAML (vale a dire l'azione RemoveStoryboard in un DataTrigger), ma mantenere il valore che è stato animato. Simile al Animatable.BeginAnimation :

  

Se BeginTime dell'animazione è nullo, qualsiasi animazione correnti verranno rimossi e si terrà il valore corrente della proprietà.

È stato utile?

Soluzione

uso primario di RemoveStoryboard è quello di rimuovere i valori animati e impostare di nuovo al loro stato di non-animato. Nella maggior parte dei casi si può semplicemente passare la chiamata a PauseStoryboard o StopStoryboard invece, a seconda del caso specifico. L'unica eccezione è quando si ha bisogno per liberare risorse detenute dalla storyboard o utilizzarlo per altri scopi.

Se davvero si vuole rimuovere la storyboard e mantenere i valori di proprietà, è necessario impostare i valori animati direttamente sulle proprietà. Questo può essere fatto impostando ogni valore al valore d'animazione, qualcosa di simile a questo:

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

  }
}

Chiama questo diritto prima di rimuovere lo storyboard per copiare i valori animati.

Modifica Un commento è stato fatto che questo codice potrebbe essere inutile perché chiamando BeginAnimation con BeginTime = null ottiene un effetto simile.

Se è vero che BeginAnimation con BeginTime = null rende sembra come se i valori sono stati copiati in locale, una chiamata più tardi per RemoveStoryboard farà sì che i valori per ritornare. Questo perché BeginAnimation con BeginTime = null fa sì che l'animazione prima di tenere i suoi valori in attesa dell'inizio della nuova animazione, ma non fa nulla per influenzare i valori locali.

Il codice sopra effettivamente sovrascrive valori locali, quindi tutte le animazioni può essere rimosso e gli oggetti avranno ancora i nuovi valori. Quindi, se si vuole veramente chiamare RemoveStoryboard e ancora mantenere i vostri valori, è necessario il codice che ho scritto sopra o qualcosa di simile.

Altri suggerimenti

Ho avuto un problema simile quando si utilizza AnimationTimeline . La soluzione più semplice si è rivelato essere catturare l'evento Completed in codice dietro e prima di chiamare BeginAnimation con il parametro null per rimuovere l'animazione, ottenere il valore corrente della proprietà e l'uso che per impostarlo.

Questo diventa l'ultimo valore d'animazione, e lo imposta.

void OnCompleted( object sender, EventArgs args )
{
    // Required to copy latest animated value to local value.
    o.SomeValue = o.SomeValue;
    o.BeginAnimation( SomeClass.SomeValueProperty, null );
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top