Windows Phone. Control MetroFlow.

En esta entrada vamos a analizar todas las posibilidades que podemos encontrar en el control MetroFlow. El control MetroFlow forma parte del conjunto de controles ofrecidos por el Condin4Fun Toolkit del que hablamos en esta entrada.

El control MetroFlow nos permite crear de manera muy rápida y sencilla pequeñas galerías de imágenes. Todas las imágenes de la galería estarán siempre contraidas excepto una. A continuación, puedes ver una captura donde podemos comenzar a hacernos una idea de su estructura.

Vamos a realizar un ejemplo práctico para entender mejor que nos aporta el control y como aprovechar todas sus posibilidades. Creamos un nuevo proyecto:

La plantilla seleccionada será “Windows Phone Application” para simplificar al máximo el ejemplo.

Agregamos dentro del Grid principal de la página MainPage.xaml:

<!--ContentPanel. Colocar aquí el contenido adicional-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
     <StackPanel>
          <Button x:Name="btnSimple" Content="Más simple"/>
          <Button x:Name="btnPropiedadesXAML" Content="Propiedades desde XAML"/>
          <Button x:Name="btnPropiedadesCB" Content="Propiedades desde Code Behind"/>
          <Button x:Name="btnEventos" Content="Eventos"/>
          <Button x:Name="btnPersonalizacion" Content="Personalización"/>
     </StackPanel>
</Grid>

Conseguiremos la siguiente interfaz:

Vamos a añadir el manejador del evento Click de cada uno de los botones:

<!--ContentPanel. Colocar aquí el contenido adicional-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
     <StackPanel>
          <Button x:Name="btnSimple" Content="Más simple" Click="btnSimple_Click"/>
          <Button x:Name="btnPropiedadesXAML" Content="Propiedades desde XAML" Click="btnPropiedadesXAML_Click"/>
          <Button x:Name="btnPropiedadesCB" Content="Propiedades desde Code Behind" Click="btnPropiedadesCB_Click"/>
          <Button x:Name="btnEventos" Content="Eventos" Click="btnEventos_Click"/>
          <Button x:Name="btnPersonalizacion" Content="Personalización" Click="btnPersonalizacion_Click"/>
     </StackPanel>
</Grid>

Al pulsar sobre cada uno de los botones llevaremos al usuario a una nueva página por lo que necesitamos antes que nada añadir al proyecto las 5 páginas necesarias que utilizaremos. En el ejemplo que podéis descargar al final de la entrada se añadieron 5 páginas llamadas:

  • Simple
  • PropiedadesXAML
  • PropiedadesCodeBehind
  • Eventos
  • Personalizacion

A continuación, vamos a ver que se hace en cada uno de los botones.

private void btnSimple_Click(object sender, RoutedEventArgs e)
{
     NavigationService.Navigate(new Uri("/MetroFlow/Simple.xaml", UriKind.Relative));
}

private void btnPropiedadesXAML_Click(object sender, RoutedEventArgs e)
{
     NavigationService.Navigate(new Uri("/MetroFlow/PropiedadesXAML.xaml", UriKind.Relative));
}

private void btnPropiedadesCB_Click(object sender, RoutedEventArgs e)
{
     NavigationService.Navigate(new Uri("/MetroFlow/PropiedadesCodeBehind.xaml", UriKind.Relative));
}

private void btnEventos_Click(object sender, RoutedEventArgs e)
{
     NavigationService.Navigate(new Uri("/MetroFlow/Eventos.xaml", UriKind.Relative));
}

private void btnPersonalizacion_Click(object sender, RoutedEventArgs e)
{
     NavigationService.Navigate(new Uri("/MetroFlow/Personalizacion.xaml", UriKind.Relative));
}

Nada fuera de lo común. Utilizamos el servicio de navegación NavigationService para enviar al usuario a la página correspondiente. Puedes ver todo lo relacionado con el servicio de navegación NavigationService en esta entrada.

Dado que el control forma parte del conjunto de controles disponibles en el Coding4Fun SDK, debemos agregar la referencia a la librería Coding4Fun.Phone.Controls.dll. Tras añadir la librería podemos incluir en las páginas que acabamos de crear:

xmlns:c4f="clr-namespace:Coding4Fun.Phone.Controls;assembly=Coding4Fun.Phone.Controls"

Vamos a centrarnos en la primera de las páginas donde realizaremos el ejemplo más sencillo de todos:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
     <c4f:MetroFlow>
          <c4f:MetroFlowData Title="Item 1" />
          <c4f:MetroFlowData Title="Item 2" />
          <c4f:MetroFlowData Title="Item 3" />
          <c4f:MetroFlowData Title="Item 4" />
          <c4f:MetroFlowData Title="Item 5" />
     </c4f:MetroFlow>
</Grid>

Como puedes ver en el primer ejemplo añadimos tantas instancias de MetroFlowData como elementos deseamos tener. Veamos las propiedades básicas correspondientes al MetroFlowData:

  • ImageUri.  Propiedad de dependencia de tipo Uri. Es la imágen correspondiente al elemento.
  • Title. Propiedad de dependencia de tipo String. Es el texto que aparecerá en la parte inferior del elemento.

En este primer ejemplo hemos establecido la propiedad Title pero no la propiedad ImageUri. Sencillamente los elementos no cuentan con imágen.

¿Existe un número máximo de elementos?

No. Podemos añadir tantos como necesitemos. Sin embargo, ten en cuenta que a más elementos más pequeño es el ancho de cada elemento contraido dificultando la interacción adecuada por parte del usuario. Recomendaría utilizar un máximo de 6 elementos en total.

Veamos el código utilizado en la página “PropiedadesXAML”:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<c4f:MetroFlow>
<c4f:MetroFlowData ImageUri="../IMGS/Lumia610.jpg" Title="Nokia Lumia 610"/>
<c4f:MetroFlowData ImageUri="../IMGS/Lumia710.jpg" Title="Nokia Lumia 710"/>
<c4f:MetroFlowData ImageUri="../IMGS/Lumia800.jpg" Title="Nokia Lumia 800"/>
<c4f:MetroFlowData ImageUri="../IMGS/Lumia900.jpg" Title="Nokia Lumia 900"/>
</c4f:MetroFlow>
</Grid>

En este caso hemos utilizado en cada elemento las propiedades Title e ImageUri.

Nota: En el ejemplo anterior hace uso de varias imágenes. Para ello se ha añadido una carpeta “IMGS” en el proyecto donde hemos añadido las imágenes utilizadas. Las imágenes utilizadas en el ejemplo las puedes ver a continuación:

Hasta ahora en todos los ejemplos realizados definimos en control MetroFlow con sus elementos en el XAML pero … ¿Es obligatorio?.

Para nada. Como cualquier control podemos trabajar con el desde el code behind de la aplicación. En el tercer ejemplo que vamos a ver a continuación veremos como hacerlo:

//Creamos el MetroFlow dinamicamente:
Coding4Fun.Phone.Controls.MetroFlow metroFlow = new Coding4Fun.Phone.Controls.MetroFlow();

// Añadimos cada MetroFlowData:
metroFlow.Items.Add(new MetroFlowData { Title = "Nokia Lumia 610", ImageUri = new Uri(@"..\IMGS\Lumia610.jpg", UriKind.RelativeOrAbsolute) });
metroFlow.Items.Add(new MetroFlowData { Title = "Nokia Lumia 710", ImageUri = new Uri(@"..\IMGS\Lumia710.jpg", UriKind.RelativeOrAbsolute) });
metroFlow.Items.Add(new MetroFlowData { Title = "Nokia Lumia 800", ImageUri = new Uri(@"..\IMGS\Lumia800.jpg", UriKind.RelativeOrAbsolute) });
metroFlow.Items.Add(new MetroFlowData { Title = "Nokia Lumia 900", ImageUri = new Uri(@"..\IMGS\Lumia900.jpg", UriKind.RelativeOrAbsolute) });

// Indicamos el MetroFlowData que estará expandido:
metroFlow.SelectedColumnIndex = 3;

//Añadimos el control al Grid principal de la página:
ContentPanel.Children.Add(metroFlow);

Visualmente el resultado final conseguido es exactamente el mismo que en el ejemplo anterior (te invito a comparar el código utilizado en cada uno de ellos para lograr el mismo resultado). Lo único a destacar en el ejemplo es la propiedad SelectedColumnIndex. Es una propiedad de dependencia de tipo entero (int) que utilizamos para indicar el elemento que estará expandido. El control MetroFlow cuenta con más propiedades  entre las que destacamos la siguiente:

  • AnimationDuration. Propiedad de dependencia de tipo TimeSpan. Determina el tiempo que durará la animación que se ejecuta cada vez que cambiamos de elemento.

Hasta ahora hemos visto la estructura, definición y las propiedades básicas del control. Sin embargo, puedes estar preguntandote … ¿Que eventos podemos llegar a necesitar?.

En ese punto en concreto nos detendremos en el siguiente ejemplo (Eventos). Veamos primero la definición de la interfaz:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
     <c4f:MetroFlow SelectionChanged="MetroFlow_SelectionChanged" SelectionTap="MetroFlow_SelectionTap">
          <c4f:MetroFlowData ImageUri="../IMGS/Lumia610.jpg" Title="Nokia Lumia 610"/>
          <c4f:MetroFlowData ImageUri="../IMGS/Lumia710.jpg" Title="Nokia Lumia 710"/>
          <c4f:MetroFlowData ImageUri="../IMGS/Lumia800.jpg" Title="Nokia Lumia 800"/>
          <c4f:MetroFlowData ImageUri="../IMGS/Lumia900.jpg" Title="Nokia Lumia 900"/>
     </c4f:MetroFlow>
</Grid>

Como podemos ver en el ejemplo anterior hacemos uso de dos eventos:

  • SelectionChanged. Este evento ocurre cuando el elemento seleccionado cambia.
  • SelectionTap. Este evento ocurre cuando se pulsa sobre un elemento (Tap).

Veamos los manejadores de dichos eventos:

private void MetroFlow_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
     MessageBox.Show("Este evento se dispara cada vez que se cambia de item.");
}

private void MetroFlow_SelectionTap(object sender, Coding4Fun.Phone.Controls.SelectionTapEventArgs e)
{
     MessageBox.Show(string.Format("Este evento se dispara cuando se pulsa sobre un item en concreto. Item pulsado: {0}", e.Data.Title));
     //Hay más propiedades de interés en el SelectionTapEventArgs como: e.Data.ImageUri
}

Hasta ahora hemos utililizado el control sin preocuparnos de su visualización (forma o colores). Sin alterar nada se consigue un resultado bastante atractivo visualmente. Sin embargo, ¿qué podemos hacer si no nos convence?

Podemos modificar su estilo para adaptarlo visualmente a nuestras necesidades. Hablaremos de recursos, estilos, plantillas, etc. con muchísima profundidad en próximas entradas. De momento, veremos que debemos hacer para modificar el control visualmente.

Debemos definir los recursos a utilizar(de forma breve podemos indicar que son trozos de XAML a los que les podemos poner un identificador para poder reaprovecharlos posteriormente). Para ello, en nuestra página podemos utilizar la colección Resources para especificarlos.

<phone:PhoneApplicationPage.Resources>
</phone:PhoneApplicationPage.Resources>

A continuación, dentro de la colección de recursos definimos:

<Style x:Key="MetroFlowItemTextBlockStyle" TargetType="TextBlock">
     <Setter Property="FontSize" Value="18" />
     <Setter Property="Margin" Value="12, 3, 0, 3" />
     <Setter Property="HorizontalAlignment" Value="Left" />
     <Setter Property="VerticalAlignment" Value="Bottom" />
</Style>

<Style x:Key="MetroFlowItemRectangleUnderlay" TargetType="Rectangle">
     <Setter Property="Fill" Value="Yellow" />
     <Setter Property="Margin" Value="0, -.5" />
     <Setter Property="Opacity" Value=".6" />
</Style>

<Style x:Key="MetroFlowItemImage" TargetType="Image">
     <Setter Property="Margin" Value="0, -.5, 0, 0" />
     <Setter Property="Stretch" Value="UniformToFill" />
     <Setter Property="HorizontalAlignment" Value="Center" />
     <Setter Property="VerticalAlignment" Value="Center" />
</Style>

<Style x:Key="MetroFlowItemMainBody" TargetType="Panel">
     <Setter Property="Background" Value="Orange" />
     <Setter Property="Margin" Value="6, 0" />
</Style>

<Style TargetType="c4f:MetroFlowItem">
     <Setter Property="Template">
          <Setter.Value>
               <ControlTemplate TargetType="c4f:MetroFlowItem">
                    <Grid>
                         <Grid Style="{StaticResource MetroFlowItemMainBody}">
                              <Image
                              Source="{TemplateBinding ImageSource}"
                              Visibility="{TemplateBinding ImageVisibility}"
                              Opacity="{TemplateBinding ImageOpacity}"
                              Style="{StaticResource MetroFlowItemImage}" />
                              <Grid VerticalAlignment="Bottom">
                                   <Rectangle
                                   Style="{StaticResource MetroFlowItemRectangleUnderlay}" />
                                   <TextBlock
                                   Text="{TemplateBinding Title}"
                                   Visibility="{TemplateBinding TitleVisibility}"
                                   Opacity="{TemplateBinding TitleOpacity}"
                                   Style="{StaticResource MetroFlowItemTextBlockStyle}"
                                   Foreground="Green"/>
                                   <TextBlock
                                   Text="{TemplateBinding ItemIndexString}"
                                   Visibility="{TemplateBinding ItemIndexVisibility}"
                                   Opacity="{TemplateBinding ItemIndexOpacity}"
                                   Style="{StaticResource MetroFlowItemTextBlockStyle}"
                                   Foreground="Blue"/>
                              </Grid>
                         </Grid>
                         <Rectangle Fill="Transparent" />
                    </Grid>
               </ControlTemplate>
          </Setter.Value>
     </Setter>
</Style>

Como podemos observar en la captura superior, hemos establecido el color de fondo a naranja, el color de fondo del Title en amarillo y  el color del Title en azul exceptuando el color del Title correspondiente al elemento seleccionado que es de color verde. De manera muy sencilla podemos personalizar a nuestro gusto la visualización del control.

Puedes ver en video el resultado de nuestro ejemplo a continuación:

También puedes descargar el ejemplo realizado:

Nada más en esta entrada. Hemos visto un control bastante interesante (yo lo utilizo en una de mis aplicaciones). Os recomiendo que lo probéis. Si os surgen dudas o sugerencias podéis dejarlas en los comentarios.

Más Información:

WindowsPhoneGeek: Getting Started with the Coding4Fun toolkit MetroFlow Control.

DZone: Addition to the Coding4Fun Toolkit – MetroFlow.

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