Como implementar TemplateSelector en el ListBox de Windows Phone 7

Si solo has trabajando con Silverlight nunca has conocido el TemplateSelector de WPF, que como su nombre indica permite hacer un selector por discriminador para las plantillas de datos. En el caso que nos atañe ListBox, tiene una propiedad llamada ItemTemplate en la que se establece la plantilla de datos para cada uno de los ítems.

¿Para qué se puede querer cambiar la plantilla?

Imaginaros el escenario de estar haciendo una aplicación para mostrar una lista de noticias provenientes de un rss, podemos tener una plantilla para las noticias con imágenes, otra plantilla para las noticias sin imágenes y además podemos querer una plantilla especial para una noticia destacada. Este tipo de escenario que es el más común es bastante difícil de conseguir con Silverlight puesto que no tiene TemplateSelector.

Para conseguir esta funcionalidad tenemos que implementarlo a mano.

Hay varias maneras de llegar hasta esta aproximación la que desde mi punto de vista es la más adecuada es crear un ListBox personalizado, porque nos permite tener toda la funcionalidad y aspecto existente del ListBox pero con el selector de plantillas.

El proceso de creación de un ListBox personalizado se hace en dos partes, la primera se tiene que hacer una clase que herede de ListBox. En esta clase, que llamaremos DataTemplateListBox, tenemos que sobrescribir dos métodos virtuales:

  • GetContainerForItemOverride: este método devuelve un objeto que será el ítem container que el ListBox usará para alojar los ítems que se establezcan en el ItemSource. En el caso del ListBox, la implementación predeterminada de este método devuelve un ListBoxItem que es el contenedor predeterminado del ListBox. En nuestro ejemplo tenemos que generar un ListBoxItem personalizado que tendrá la funcionalidad de establecer el DataTemplate.
  • PrepareContainerForItemOverride: Este método es llamado cuando el ListBox está a punto de empezar a hacer la pasada de Layout, y es el momento justo para establecer el código de nuestros discriminador. Este método acepta dos parámetros, uno llamado element de tipo DependencyObject que es el contenedor del ListBox, y el otro ítem de tipo object que es el objeto que nosotros estamos estableciendo al ListBox.
public class DataTemplateListBox : ListBox
{
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new DataTemplateListBoxItem();
    }
    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
    {
        base.PrepareContainerForItemOverride(element, item);
        DataTemplateListBoxItem lbi = (DataTemplateListBoxItem)element;
        if (item is News)
        {
            News newItem = (News)item;
            if (!newItem.IsHighLighted)
            {
                lbi.CustomTemplate = (DataTemplate)App.Current.Resources["NewsDataTemplate"];
            }
            else
            {
                lbi.CustomTemplate = (DataTemplate)App.Current.Resources["HighLightedNewsDataTemplate"];
            }
        }
    }
}

Como hemos dicho anteriormente en el proceso de creación del ListBox tenemos que crear también un ListBoxItem que será el contenedor neutro que tendrá una propiedad de tipo DataTemplate, que será el DataTemplate usado para dibujar ese elemento con una plantilla especifica.

[TemplatePart(Name = "DisplayContent", Type = typeof(ContentControl))]
public class DataTemplateListBoxItem : ListBoxItem
{
    #region Properties
    
    public DataTemplate CustomTemplate
    {
        get { return (DataTemplate)GetValue(CustomTemplateProperty); }
        set { SetValue(CustomTemplateProperty, value); }
    }

    public static readonly DependencyProperty CustomTemplateProperty =
        DependencyProperty.Register(
            "CustomTemplate", 
            typeof(DataTemplate), 
            typeof(DataTemplateListBoxItem), 
            new PropertyMetadata(null));

    #endregion

    #region Constructors
    public CategoryItemsListBoxItem()
    {
        DefaultStyleKey = typeof(DataTemplateListBoxItem);
    }
    #endregion
}

Este es el código de ejemplo de un DataTemplateListBoxItem, pero también necesitamos generar un estilo predeterminado que contenga un elemento de tipo ContentControl que será el elemento que tendrá la interfaz del usuario del elemento.

<Style TargetType="controls:DataTemplateListBoxItem" >
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="controls:DataTemplateListBoxItem">
                <ContentControl x:Name="DisplayContent" Content="{TemplateBinding DataContext}" 
                                ContentTemplate="{TemplateBinding CustomTemplate}"  />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Como se puede apreciar en el código xaml lo que se hace es agregar a la plantilla un ControlTemplate y en ese ControlTemplate se establecen dos propiedades Content con un binding de plantilla (TemplateBinding) a la propiedad DataContext, con eso conseguirnos establecer el objeto como contenido y que se dibuje. La otra propiedad que falta por establecer es justamente la propiedad ContentTemplate que en este caso se hace lo mismo, hacer un binding de plantilla con la propiedad CustomTemplate que es de la clase DataTemplateListBoxItem.

Ahora lo que tenemos que hacer es insertar nuestro DataTemplateListBox en el control MainPage y enlazarle un ViewModel con datos para mostrar un par de noticias generadas por código:

<Grid x:Name="ContentPanel" Grid.Row="1">
   <DataTemplateDemo_Controls:DataTemplateListBox ItemsSource="{Binding Items}"/>
</Grid>

Con eso conseguimos tener un ListBox en el nosotros decidimos en cada uno de los elementos como queremos aplicarle una plantilla de datos. Este es el resultado:

image

La demo no es muy impresionante en sí, pero permite tener la flexibilidad de poder elegir elemento por elemento cual es la plantilla que vamos a usar de manera programática.

La demo completa la podéis descargar de aquí.

Luis Guerrero.

Entrevista a plain concepts, equipo de desarrolladores de bye bye brain

Entrevista realizada en http://wp7connect.blogspot.com/

¿Podeis hacer una breve presentación sobre el equipo?

 

El equipo lo formamos Ricardo Acosta, Rodrigo Diaz y Luis Guerrero. Ricardo Acosta es nuestro diseñador gráfico, modelador 3d y texturizador, y tanto Rodrigo Diaz como yo somos programadores de .NET.

Supongo que os habéis dado cuenta que la mayoría de blogs especializados en el sector ,de medio mundo, están hablando de vosotros después de que anunciarais en vuestros blogs personales, Bye Bye Brain, el juego para WP7 que estáis desarrollando ¿Os esperabais tanta repercusión en tan poco tiempo? ¿Cómo surgió la idea de desarrollar Bye Bye Brain?

No esperábamos tener tanta acogida como la que hemos tenido, empezamos con el video en vimeo y la cosa fue subiendo hasta que fuimos portada de gizmodo.com toda una hazaña.
La idea de desarrollar ByeByeBrain surgió a principio de año cuando nos enteramos que Microsoft iba a desarrollar una nueva plataforma móvil, nuestra empresa Plain Concepts es Partner Gold de Microsoft y pensábamos en hacer un juego.

¿Por qué consideráis que WP7 es una buena plataforma para lanzar vuestro proyecto, aún cuando todavía no se ha lanzado?


Esta pregunta es complicada de responder, pero supongo que nos lanzamos por ser afines a Microsoft, porque no esperábamos que hubiera muchos desarrolladores haciendo cosas, porque las dos tecnologías en las que se desarrolla XNA y Silverlight las utilizamos a diario así que pensamos que era la oportunidad perfecta para nosotros.

Muchos comentarios resaltan el hecho de que un equipo de tres personas ha realizado un desarrollo tan bueno ¿Cuánto tiempo os ha supuesto desarrollar Bye Bye Brain? ¿Cuál ha sido el aspecto o proceso más difícil?


El primer checking del proyecto se hizo el día 2 de julio a las 12 de la mañana y desde ese momento no hemos parado de trabajar, eso implica definir un pequeño prototipo del juego, pantallas funcionalidad y demás. La parte más difícil del proyecto para mí fue acomodarme a XNA, venia de Silverlight que es un framework de alto nivel con cosas muy cómodas y en XNA no teníamos nada, así en unos de las primeras semanas, definimos un pequeño framework de animaciones basada en Silverlight y un sistema para definir controles y relaciones entre los controles en XNA. Evidentemente no podemos definir los controles igual que en Silverlight pero queríamos definir una relación padre hijo con los DrawableGameComponents de XNA para que fuera más fácil trabajar con ellos. Definimos las DependencyProperties para XNA y alguna que otra cosa más. Con todo eso pudimos después hacer todas las animaciones de los elementos 2D de una manera cómoda ya que animar es tan fácil como en Silverlight.

¿Qué ventajas pensáis que tiene realizar juegos en XNA respecto a los desarrollos que se pueden realizar en otras plataformas móviles como Iphone o Android?

Las ventajas para nosotros en el .NET Framework y C# ya que son nuestros lenguajes principales de desarrollo diario. .NET Framework tiene todo lo que un desarrollador puede soñar y XNA también, así que nos sentimos muy cómodos trabajando con las herramientas. Además de la perfecta integración con Visual Studio 2010.

¿Qué breves consejos le daríais a desarrolladores independientes que están empezando a plantearse desarrollar juegos o aplicaciones para WP7?

Pues que es el momento de hacerlo ya que no hay muchos desarrolladores interesados y eso puede hacer que les sea fácil brillar ya que la plataforma es nueva. Además, desde mi punto de vista, las herramientas de Microsoft son las mejores.

¿Qué opináis de las herramientas de desarrollo para WP7? ¿Cuáles son sus puntos fuertes y sus puntos débiles?


Los puntos fuertes ya los he comentado, las API o frameworks, XNA y Silverlight, son súper productivos para desarrolla aplicaciones, ya que Silverlight con Visual Studio 2010 y con Expression Blend se puede hacer cosas muy chulas en muy poco tiempo. Sobre las cosas malas, son herramientas beta eso significa que contienen algunos bugs que no tienen workaround y que quizás el tiempo de despliegue de tu aplicación al emulador y al devices es muy lento.

¿Desde vuestro punto de vista y habiendo podido acceder a un terminal para desarrolladores qué crees que debe mejorar WP7 a corto-medio plazo?


Esto es una pregunta trampa, Microsoft lo está haciendo bien con WP7 pero realmente es su primera versión del SO, las otras plataformas van por la versión 2.2 o 4 así que evidentemente le falta muchas cosas, pero es un buen comienzo.

¿Cuánto tiempo calculáis que pasará desde que enviéis una aplicación a Microsoft hasta que esté evaluada e incorporada al Marketplace? ¿Cuáles son los puntos críticos de este proceso?

Por ahora no lo sabemos pero Microsoft ha prometido que el proceso será rápido.

Si podéis contarnos algo ¿qué proyectos futuros tenéis en mente respecto a WP7?


Pues tenemos pensado seguir con el desarrollo de ByeByeBrain con más mapas, ataques especiales, más mini juegos, etc. Además de empezar el desarrollo de otros juegos o aplicaciones.

¿Quereis añadir algo más que creas interesante para los usuarios interesados en WP7?


Pues decirles que si son desarrolladores este es su momento de que se bajen el SDK y se pongan en serio a hacer su proyecto con calma.

Podéis saber más sobre Plain Concepts (Luis Guerrero, Rodrigo Díaz y Ricardo Acosta) y sus desarrollos en la web de Plain Concepts y sus blogs personales.

Les damos las gracias a los tres por concedernos esta entrevista y les deseamos un gran éxito en este y otros proyectos sobre WP7. Estamos seguros que Bye Bye Brain será uno de los juegos más populares del Marketplace de WP7.

ByeByeBrain – Juego de Tower defence de Plain Concepts

Hola a todos, estamos orgullosos de presentar desde Plain Concepts Game Studio, ByeByeBrain. Un juego de tower defence para Windows Phone 7. El juego ha sido desarrollado en XNA usando 3D para el gameplay, con 5 tipos de torretas y 4 tipos de zombines incluyendo un mini juego para los ataques especiales. El juego combina el clásico de defensa de torres con mini juegos y una cámara interactiva durante el juego. Tambien cuenta con integración de Facebook y Twitter para publicar tu puntuación.

Podeis ver un video en Vimeo http://vimeo.com/14723559 y una versión en HD con Silverlight en: http://games.plainconcepts.com/.

También unos fondos de pantalla.

cleaner1920x1200colonel1920x1200fuzz1920x1200nerd1920x1200spanker1920x1200

Algunas cosas interesantes sobre el juego:

· Tiene un sistema de propiedades basado en el de DependencyProperty como WPF y Silverlihgt

· Tiene un sistema de animacions como BeginAnimation y SingleAnimation.

· Approx. 20Mb de fichero XAP.

· 61139 lineas de codigo (Visual Studio 2010 metric system)

· El juego ha sido desarrollado en tres localizaciones diferentes durante los 2 meses de desarrollo

· Uno de los miembros es adicto a los donnetes

Luis Guerrero.

Primer dispositivo de Windows Phone 7 en Plain Concepts

Hola a todos!

Ya tenemos teléfono de Windows Phone 7 en Plain Concepts, hoy mismo lo hemos recibido de Fedex. Es de la marca LG y parece que a todos los que estamos desarrollando para WP7 tenemos el mismo modelo.

El teléfono arranca es unos escasos 10 segundos desde que le das al teléfono hasta que aparece la lista de Tiles disponibles o la pantalla para introducir el pin, es impresionante la velocidad. Por lo demás muy chulo todo, el correo se configura súper rápido, la cuenta de Facebook y todo lo demás.

Para sincronizarlo con el PC el software de Zune, una versión que tenemos la gente que estamos en el TAP de WP7 y además puedes activarlo para ejecutar tus aplicaciones en él. Hay algunas aplicaciones en el marketplace de ejemplo y puedes depurar directamente en el dispositivo.

Os adjunto algunas fotos!.

_DSC0841_DSC0842_DSC0843_DSC0844_DSC0845_DSC0846_DSC0847

Por cierto también me gustaría presentaros, http://games.plainconcepts.com/ el nuevo departamento de desarrollo de video juegos de Plain Concepts.

Saludos.

Luis Guerrero.