Aplicar animaciones de guión gráfico a varios objetos XAML

Applies to Windows and Windows Phone

A continuación te mostramos cómo evitar tener que crear varias animaciones de guión gráfico y, en lugar de ello, aplicar el mismo guión gráfico a varios objetos.

Mira esta página XAML desde una aplicación, en la que se muestra una cuadrícula de imágenes de teclado. Cuando el usuario pulsa uno de estos botones, queremos animar el botó para que parezca que se mueve.

Un archivo XAML con varios botones: ¿realmente deseas crear una animación de guión gráfico para cada uno de ellos?

Como hemos visto en el tema Aplicar máscaras y animación a un botón, a diferencia de iOS donde modificamos parámetros tales como la opacidad en el tiempo en un bloque de animación, Windows 8 usa objetos de guión gráfico. SI tienes varios objetos XAML similares en pantalla, como ocurre, por ejemplo, en nuestra cuadrícula de botones, quizás te preguntes si es necesario crear un único guión gráfico para cada uno de ellos. Te gustará saber que no es necesario, y ahora te mostraremos cómo aplicar la misma animación a varios objetos.

Nota   Recuerda que en Windows 8 un guión gráfico es una animación, no una forma de diseñar la aplicación como en Xcode.

El secreto es cambiar a nivel de programación la propiedad s TargetName del guión gráfico, como se muestra en el siguiente ejemplo.

Definir el guión gráfico

En primer lugar, define una animación de guión gráfico. Puedes usar Blend o definirla manualmente en XAML. Para obtener un ejemplo de uso de Blend, consulta Aplicar máscaras y animación a un botón. Si usas Blend, elimina las propiedades TargetName, de lo contrario la animación solo se aplicará a un destino en concreto. Este es un ejemplo:


    <Page.Resources>
        <Storyboard x:Name="TapAnimation">
			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" >
				<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
				<EasingDoubleKeyFrame KeyTime="0:0:0.05" Value="0.95"/>
				<EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="1"/>
			</DoubleAnimationUsingKeyFrames>
			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" >
				<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
				<EasingDoubleKeyFrame KeyTime="0:0:0.05" Value="0.95"/>
				<EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="1"/>
			</DoubleAnimationUsingKeyFrames>
		</Storyboard>
    </Page.Resources>

Acuérdate de agregar una etiqueta <RenderTransform> a cualquier objeto XAML que cambie tu guión gráfico, así como el marcador de posición de la transformación específica que se va a animar, si no, tu aplicación arrojará una excepción. Aquí tienes un ejemplo de un objeto Image listo para aplicarle un guión gráfico:


 <Image x:Name="myImage" Width="256" Height="160" RenderTransformOrigin= "0.5,0.5" >
                        <Image.RenderTransform>
                            <CompositeTransform/>
                        </Image.RenderTransform>
                    </Image>

Nota  El uso de la propiedad RenderTransformOrigin= "0.5,0.5" garantiza que cualquier animación se centre en la parte central del objeto.

Aplicar el guión gráfico

A continuación, asocia el guión gráfico con un objeto y un desencadenador según sea necesario. Solo una advertencia: no puedes cambiar la propiedad TargetName mientras se reproduce la animación, de lo contrario la aplicación generará una excepción. Para evitarlo, llama a Stop() antes de cambiar el destino.

Sugerencia  La llamada a GetCurrentState() puede detectar si se está ejecutando un guión gráfico.

A continuación te mostramos el código para desencadenar la animación para un objeto Image específico. Por ejemplo, este código podría ser como respuesta al momento en que el usuario pulsa la imagen mediante un evento PointerPressed. Es tan sencillo como aplicarlo a un a Button, con un evento Click.


 // Add using Windows.UI.Xaml.Media.Animation;
            TapAnimation.Stop();
            TapAnimation.SetValue(Storyboard.TargetNameProperty,"myImage");
            TapAnimation.Begin();

Este método es mucho más útil si generas el nombre del nuevo destino automáticamente desde el control que ha desencadenado el evento, de este modo:


  private void someImages_PointerPressed(object sender, PointerRoutedEventArgs e)
        {
            TapImage.Stop();
            TapImage.SetValue(Storyboard.TargetNameProperty, (sender as Image).Name);
            TapImage.Begin();
        }

Aquí, el objeto Image que el usuario ha pulsado crea el evento, y usamos su nombre como destino. Si todas las imágenes de la página generan el mismo evento cuando se pulsan, se animarán con el mismo guión gráfico. Por consiguiente, en nuestro ejemplo de teclado, se animará cada una de las teclas y solo debemos crear un guión gráfico.

Nota  Quizás no hayas visto antes el teclado as: realiza una conversión en el emisor para que pase a ser un Image.

Varios botones, un controlador de eventos

Con una aplicación con varios botones similares, tiene sentido disponer de un controlador de eventos maestro, en lugar de un controlador de eventos para cada botón. Cada botón puede usar el mismo evento de clic, pero debemos usar algo para diferenciar los distintos botones en el código: aquí es adecuado usar tags.

Como ocurre en iOS, cada control u objeto puede tener una etiqueta: un valor que puedes usar para identificarlos de forma unívoca. Por ejemplo, en nuestro ejemplo de teclado, podrías definir los botones como en este XAML: observa que los botones son casi idénticos, pero presentan un valor de etiqueta distinto


	<Button Content="1" HorizontalAlignment="Left" Margin="446,78,0,0" VerticalAlignment="Top" Width="120" Height="120" FontSize="48" FontWeight="Bold" Click="Button_Click" Tag="1">
    		<Button.Background>
    			<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    				<GradientStop Color="Black"/>
    				<GradientStop Color="#FF838383" Offset="1"/>
    			</LinearGradientBrush>
    		</Button.Background>
    	</Button>
        <Button Content="2" HorizontalAlignment="Left" Margin="446,543,0,0" VerticalAlignment="Top" Width="460" Height="120" FontSize="48" FontWeight="Bold" Click="Button_Click" Tag="2">
    		<Button.Background>
    			<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    				<GradientStop Color="Black"/>
    				<GradientStop Color="#FF838383" Offset="1"/>
    			</LinearGradientBrush>
    		</Button.Background>
    	</Button>
        <Button Content="3" HorizontalAlignment="Left" Margin="446,393,0,0" VerticalAlignment="Top" Width="120" Height="120" FontSize="48" FontWeight="Bold" Click="Button_Click" Tag="3">
    		<Button.Background>
    			<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    				<GradientStop Color="Black"/>
    				<GradientStop Color="#FF838383" Offset="1"/>
    			</LinearGradientBrush>
    		</Button.Background>
    	</Button>

Todos los botones apuntan al mismo controlador de eventos, Button_Click. Aquí te mostramos cómo podemos leer el valor de la etiqueta y reaccionar de forma adecuada en el controlador:


        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var tag = (sender as Button).Tag;

            int t = Convert.ToInt16(tag);

            switch (t)
            {
                case 0: break;
                case 1: break;
                case 2: break;
                default: break;
            }
        }

Temas relacionados

Trabajar con animaciones mediante programación
Tareas iniciales: animación
Cómo: crear interfaces de usuario con XAML y Expression Blend
Animaciones con guion gráfico

 

 

Mostrar:
© 2015 Microsoft