Pregunta

¿Cómo puedo eliminar un guión gráfico en XAML (acción RemoveStoryboard es decir, en un DataTrigger) pero mantener el valor que se ha animado. Al igual que en el Animatable.BeginAnimation :

  

Si BeginTime de la animación es nulo, las animaciones actuales serán eliminados y se llevará a cabo el valor actual de la propiedad.

¿Fue útil?

Solución

El uso principal de RemoveStoryboard es eliminar los valores animados y establecer de nuevo a su estado no animada. En la mayoría de los casos basta con cambiar la llamada a PauseStoryboard o StopStoryboard lugar, dependiendo del caso específico. La única excepción es cuando se necesita para liberar los recursos mantenidos por el guión gráfico o utilizarla para otro propósito.

Si realmente desea eliminar el guión gráfico y mantener los valores de la propiedad, debe establecer los valores de animación directamente en las propiedades. Esto se puede hacer mediante el establecimiento de cada valor con el valor de animación, algo como esto:

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

  }
}

Llamada este derecho antes de quitar el guión gráfico para copiar los valores animados.

Editar Se hizo un comentario que este código puede ser innecesario porque llamando BeginAnimation con BeginTime = null logra un efecto similar.

Si bien es cierto que con BeginAnimation BeginTime = null hace parece como si los valores se copian en locales, una llamada posterior a RemoveStoryboard hará que los valores que se revierten. Esto se debe a BeginAnimation con BeginTime = null provoca la animación antes de mantener sus valores pendientes del inicio de la nueva animación, pero no hace nada para afectar a los valores locales.

El código anterior en realidad sobrescribe los valores locales, por lo que todas las animaciones pueden ser retirados y los objetos todavía tendrán sus nuevos valores. Así que si realmente desea llamar RemoveStoryboard y aún así mantener sus valores, necesitará el código que escribí más arriba o algo parecido.

Otros consejos

Yo tenía un problema similar cuando se utiliza AnimationTimeline . La solución más fácil resultó ser captura el evento Completed en código detrás y antes de llamar BeginAnimation con el parámetro null para eliminar la animación, obtener el valor actual de la propiedad y el uso que para configurarlo.

Esto nos lleva al último valor de animación, y lo establece.

void OnCompleted( object sender, EventArgs args )
{
    // Required to copy latest animated value to local value.
    o.SomeValue = o.SomeValue;
    o.BeginAnimation( SomeClass.SomeValueProperty, null );
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top