Utilizando animaciones – Play WPF

En el anterior post hice una pequeña introducción sobre lo que podían ofrecernos las animaciones y en esta entrada voy a ponerlo en práctica con la creación de un control .La idea consiste en que, inicialmente, dicho control muestre una vista en miniatura y que, pulsando un botón, se amplie el área mostrando más información. A diferencia de las entradas anteriores y la temática del blog, en esta ocasión la entrada se va a desarrollar utilizando WPF con la que, debido a cuestiones de trabajo, he podido profundizar  un poco más en relación con las animaciones.

Se trata de unas animaciones sencillas pero que bien puede servir como ejemplo de lo que se puede llegar a hacer. El resultado final se muestra a continuación:

La creación de este control respondía a la necesidad de mostrar más detalles sobre los elementos que conformaban un esquema eléctrico.

El control tendrá la siguiente estructura:

  • Un Grid que contendrá la vista en miniatura y un botón en la parte superior derecha con el que se ampliará el área de visualización.
  • Un segundo Grid que contendrá la vista ampliada y un botón en la parte superior derecha con el que se volverá  a la vista en miniatura.
  • Varias propiedades de dependencia que representarán los controles a mostrar en la vista en miniatura y en la ampliada, y las anchuras y alturas inicial y final del control.

Animaciones

Al pulsar los botones que controlan el área de visualización se lanzarán tres animaciones diferentes: una que cambiará el tamaño del propio control, otra su posición dentro del contenedor y otra la visibilidad de los contenedores de la vista en miniatura y la ampliada.

Las dos primeras son animaciones básicas y ambas modifican propiedades de tipo Double, (Height y Width para el tamaño del control, y Canvas.Top y Canvas.Left para su posición) mientras que para llevar a cabo la última, se utiliza una animación avanzada discreta que, como decía en el post anterior, nos permite modificar propiedades que no sean las predefinidas (Color, Double y Point) y que modifiicará la propiedad Visibility.

<EventTrigger RoutedEvent="Button.Click">
     <BeginStoryboard>
          <Storyboard>
               <DoubleAnimation Storyboard.TargetName="ExpandableContent"
                Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:3" To="0" />

               <DoubleAnimation Storyboard.TargetName="ExpandableContent"
                Storyboard.TargetProperty="(Canvas.Top)" Duration="0:0:3" To="0"/>

               <DoubleAnimation Storyboard.TargetName="ExpandableContent"
                Storyboard.TargetProperty="Width" Duration="0:0:3"
                To="{Binding FinalWidth, ElementName=ExpandableContent}"/>

               <DoubleAnimation Storyboard.TargetName="ExpandableContent"
                Storyboard.TargetProperty="Height" Duration="0:0:3"
                To="{Binding FinalHeight, ElementName=ExpandableContent}"/>

               <ObjectAnimationUsingKeyFrames Storyboard.TargetName="LargeView"
                                              Storyboard.TargetProperty="Visibility">
                    <DiscreteObjectKeyFrame KeyTime="0:0:2" Value="{x:Static Visibility.Visible}" />
               </ObjectAnimationUsingKeyFrames>

               <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SmallView"
                                              Storyboard.TargetProperty="Visibility">
                    <DiscreteObjectKeyFrame KeyTime="0:0:2" Value="{x:Static Visibility.Collapsed}" />
               </ObjectAnimationUsingKeyFrames>
          </Storyboard>
     </BeginStoryboard>
</EventTrigger>

Propiedades de dependencia

En la ampliación del área,  las propiedades Canvas.Top y Canvas.Left son las modificadas en la animación hasta situar el control en la esquina superior izquierda, a la vez que son modificadas las propiedades Height y Width hasta alcanzar los valores  especificados en las propiedades FinalHeight y FinalWidth , respectivamente, y que definiremos más adelante  Durante el tiempo que dura este proceso se cambia la visibilidad del control del área ampliada a Visible y a Collapsed la del área reducida.

Además de estas propiedades, se añadirán otras cuatro más para almacenar el estado inicial, Top y Left con la posición en el contenedor e, InitialWidth e InitialHeight con el tamaño. En la animación de vuelta a la vista en miniatura, tomaremos como valores iniciales para el tamaño FinalHeight y FinalWidth, y cero para Canvas.Top y Canvas.Left.

Todas estas propiedades de dependencia se han de especificar en el code behind de la clase. Las propiedades de dependencia son un tipo de propiedades que ofrecen una infraestructura que nos permite realizar una serie de operaciones relacionadas con el valor que tomará, como validar dicho valor, notificar cambios u obligar a que se encuentre dentro de un rango de valores, entre otras. En esta entrada no profundizaré en ello, pero sí comentaré cómo registrarlas y cómo se utilizarán dentro del control que estoy desarrollando.

En la siguienta pieza de código se muestra la definición de la propiedad SmallContent que es de tipo UserControl y que contendrá el control que se mostrará en la vista en miniatura.

public static readonly DependencyProperty SmallContentProperty =
              DependencyProperty.Register("SmallContent", typeof(UserControl),
              typeof(ExpandableElement), null);

public UserControl SmallContent
{
     get { return (UserControl)GetValue(SmallContentProperty);
     set { SetValue(SmallContentProperty, value); }
}

Después, ya en el xaml, podemos especificar el contenido de la propiedad SmallContent como si se tratara de un contenedor cualquiera como puede ser en un ContentControl.

<my:ExpandableElement Canvas.Left="30.997" Canvas.Top="104"
                      FinalHeight="{Binding ActualHeight,
                                    RelativeSource={RelativeSource FindAncestor,
                                    AncestorType={x:Type Canvas}}}"
	              FinalWidth="{Binding ActualWidth,
                                    RelativeSource={RelativeSource FindAncestor,
                                    AncestorLevel=1, AncestorType={x:Type Canvas}}}"
                      Height="130" Width="70.333" >
     <my:ExpandableElement.SmallContent>
          <my:SmallContent />
     </my:ExpandableElement.SmallContent>
     <my:ExpandableElement.LargeContent>
	  <my:LargeContent />
     </my:ExpandableElement.LargeContent>
</my:ExpandableElement>

A la propiedad SmallContent, añadiremos LargeContent que se definirá exactamente igual que SmallContent y que contendrá el control de usuario que se mostrará al expandir el área de visualización.

Conclusión

Hasta aquí el desarrollo de este control. Se trata de una primera versión, mejorable en varios aspectos, pero que puede valernos como prueba de concepto. Dejo aquí el código del mismo para quien quiera realizar mejoras y refinar el resultado.

ExpandableControlSample (Eliminar extensión .doc y descomprimir)

 

Anuncios
Esta entrada fue publicada en Animaciones, WPF y etiquetada , , . Guarda el enlace permanente.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s