2011-01-11 7 views
6

En mi Application.Resources Tengo el siguiente Storyboard definido.WP7 - Uso de Storyboard define en Application.Resources

<Application.Resources> 
    <!--Storyboard animation for fading out a UI element--> 
    <Storyboard x:Key="FadeOutAnimation"> 
    <DoubleAnimation From="1" 
        To="0" 
        Duration="0:0:0.25" 
        Storyboard.TargetProperty="Opacity" 
        AutoReverse="False" /> 
    </Storyboard> 
</Application.Resources> 

En código subyacente que estoy usando esta a desaparecer algunos TextBlock s cuando el usuario pulsa sobre ellos.

// Get the storyboard from application resources 
Storyboard sb = (Storyboard)App.Current.Resources["FadeOutAnimation"]; 
// Setup the animation target for fade out 
Storyboard.SetTarget(sb.Children.ElementAt(0) as DoubleAnimation, myTextBlock); 
// Set the animation completed handler 
sb.Completed += (s, e1) => { 
    // Stop the Storyboard 
    sb.Stop(); 
    // Hide the TextBlock 
    myTextBlock.Visibility = Visibility.Collapsed; 
}; 
// Start the Storyboard 
sb.begin(); 

La pregunta es, ¿Qué necesito de alguna manera 'desenganche' myTextBlock de ser el blanco de la DoubleAnimation?

Si es así, ¿cómo lo hago?

La razón por la que estoy pidiendo es que me preocupa una referencia a esa TextBlock dando vueltas hasta que este guión gráfico se utiliza de nuevo.

Gracias por su ayuda!

Respuesta

12

No siempre tenemos que utilizar Xaml en Sliverlight si su conseguir en nuestro camino: -

public static AnimationHelper 
    { 
     public static void FadeOutAndCollapse(UIElement target) 
     { 
      DoubleAnimation da = new DoubleAnimation(); 
      da.From = 1.0; 
      da.To = 0.0; 
      da.Duration = TimeSpan.FromSeconds(0.25); 
      da.AutoReverse = false; 

      StoryBoard.SetTargetProperty(da, new PropertyPath("Opacity")); 
      StoryBoard.SetTarget(da, target); 

      StoryBoard sb = new StoryBoard(); 
      sb.Children.Add(da); 

      EventHandler eh = null; 
      eh = (s, args) => 
      { 
       target.Visiblity = Visibility.Collapsed; 
       sb.Stop(); 
       sb.Completed -= eh; 
      } 
      sb.Completed += eh; 

      sb.Begin(); 
     } 
} 

Con esto en su lugar puede desaparecer y contraer cualquier elemento de interfaz de usuario con: -

AnimationHelper.FadeOutAndCollapse(myTextBox); 

me han inclinado a retirar el From = 1.0 para que sea más general, de manera que los elementos que tienen una opacidad inicial más baja no destellan repentinamente a una opacidad total antes de desaparecer.

+0

Tienes razón, es mejor hacer esto en código subyacente. – Praetorian

+0

@Praetorian: No todo el código es "código subyacente", lo anterior no lo es. Puedes imaginar una clase de ayuda con varios métodos útiles. Simplemente se convierte en una parte de tu propio juego de herramientas. – AnthonyWJones

+0

¿Qué se necesita para usar la instancia del guion gráfico? – kabuto178

0

No se preocupe por colgar referencias a elementos de interfaz de usuario ligeros; serán basura recolectada cuando ya no haya más referencias. Su problema más apremiante es que se utiliza un solo guión gráfico para múltiples objetos de texto y si se superponen, hará lo incorrecto.

Por ejemplo, si se inicia una animación y luego inicia otra, entonces van a parar tanto al mismo tiempo, ya que sólo hay un guión gráfico y su manejador llama parada. O asocia un guión gráfico separado con cada elemento de texto en XAML o crea un nuevo guión gráfico en el código subyacente para cada animación que quieras hacer.

Además, si tuviera que usar un solo guión gráfico, debe tener cuidado de eliminar el controlador de eventos completo porque actualmente seguirá acumulándolos y se invocará a los controladores antiguos cuando el guión gráfico se complete.

+0

Desde el guión gráfico se ponga en marcha por un evento del grifo y sólo dura un cuarto de segundo no estoy demasiado preocupado por los múltiples que encienden simultáneamente. Pero tiene un buen punto sobre el controlador Completed. ¿Cómo puedo eliminar el último? Debido a que estoy usando una lambda, no sé cómo hacerlo. – Praetorian