Desarrollo con Windows Phone–¿No te apetece instalarte el entorno de desarrollo?

Bueno, pues no pasa nada.

¿Sabías que tienes a tu disposición Laboratorios Virtuales en Azure en los que poder practicar y mejorar tus conocimientos?

Pues visita esta página: http://msdn.microsoft.com/en-us/aa570323

No sólo dispones de laboratorios virtuales para Windows Phone 7.

image

También dispones de otros muchos laboratorios: Azure, Windows 7, Office, SharePoint Server.

Venga, no hay excusa. Con una conexión a internet normal ya tienes un entorno de desarrollo completamente disponible.

  1. Necesitarás un equipo con Windows XP o superior.
  2. Un Internet Explorer 5 o superior (¡IE5! ¿Existe eso todavía?)
  3. Tendrás que permitir cookies y que se Instale /habilite algún ActiveX para conectarte remotamente al laboratorio.
  4. Un monitor de 1024×768 como mínimo.
  5. En inglés, eso sí.
  6. Una conexión a Internet (yo tengo 10Mb así que no he podido probar con conexiones más lentas, intentaré enterarme, pero pinta que con una conexión de 2Mb tendrás suficiente, así: a ojo)

Como veis se trata de un conjunto de requerimientos de lo más razonable. Si no te terminas de decidir a instalar en tu máquina las herramientas que necesitas, esta opción es muy útil (eso sí, tienes límite de tiempo para permanecer conectado, muy razonable, eso sí. Un laboratorio que puede llevarte 90 minutos realizarlo si te lo tomas con calma, te permitirá estar conectado cerca de una hora y media).

Empezando con Windows Phone 7.1 (y IX) – Mi Panorama

Dándole vueltas a la organización de pantallas de la aplicación estoy pretendiendo que el usuario pueda disponer de información sobre sus sitios de interés de una manera sencilla y sin que tenga que estar realizando filtros manuales que puedan complicar la utilización de la misma. Así, por ejemplo, un usuario puede querer ver de forma automática, los sitios que son de su interés que se encuentren próximos a su ubicación, quizá los más visitados, o los marcados como favoritos…

Dentro de Windows Phone vais a poder encontrar fundamentalmente dos controles para la presentación de datos (bueno al menos dos, para lo que a esta entrada se refiere). Uno de ellos es el control “Pivot“. Este control es útil para presentar información o colecciones de datos divididos en subconjuntos.

Desde un punto de vista clásico de análisis de la información, las tablas dinámicas o pivot tables son  utilizadas para analizar fracciones o subconjuntos de datos agrupados según alguna característica común. Por ejemplo, una base de datos conteniendo gran información demográfica es difícil de analizar. Normalmente esta información suele segmentarse para facilitar su análisis según el sexo, edad, ingresos, estudios, ubicación geográfica, etc…

Siguiendo esa analogía, el control Pivot tiene una orientación más analítica de la información que quieres presentar en tu aplicación. Un buen ejemplo es el cliente de correo que te permite organizar la vista de tus mensajes de correo según quieras ver “Todos”, “Los mensajes Sin Leer”, “Urgentes”, etc…

Presentación de un Control Pivot

Presentación de un Control Pivot

Existe otro control de presentación, que por lo que estoy viendo es el que más se ajusta a mis necesidades que es el control “Panorama“. Este control es una de las incorporaciones de Presentación y Usabilidad más originales de la interfaz de Windows Phone. Al contrario que en otros casos, donde la vista o página está pensada para adaptarse al tamaño de la pantalla. Panorama es un marco ancho, muy ancho. Tanto que pueden caber varios anchos de pantalla para presentar el total de la información.

Presentación de un Control Panorama

Presentación de un Control Panorama

El objetivo es disponer en una sola pantalla de diferentes presentaciones de datos, así como de servicios que puedan resultar de utilidad para el usuario. Un par de ejemplos son la aplicación a través de la cual puedes ver Imágenes en tu Windows Phone, Zune o la aplicación oficial de Facebook (desde mi humilde punto de vista, todavía no muy lograda aunque rodando por buen camino).

Así pues, voy a decantarme por una vista principal con un control de tipo Panorama. Para ello hay que empezar con la organización de la información.

La anatomía de un control Panorama es la siguiente:

Anatomía Panorama

Anatomía del Control Panorama

El control Panorama está formado por tres capas diferentes:

  • Background: Un panel que permite mostrar y animar el contenido del fondo.
  • Title: Un panel utilizado para mostrar y animar el título.
  • Items: La capa que muestra los diferentes PanoramaItems que definamos en nuestro control y que se distribuyen horizontalmente.

Dice la documentación que, en el caso de que estés utilizando una imagen como fondo para tu control Panorama, y dejas la propiedad “Build Action” asociada a dicha imagen en modo “Content”, la carga del fichero se produce de manera asíncrona y puede llegar a apreciarse cierto retardo en la carga de la imagen. Es mejor dejar dicha propiedad como “Resource” de esta manera, la imagen se incluirá como un recurso más de la aplicación cargándose en el lanzamiento de la misma. Siendo sincero, yo no he percibido mucho cambio a simple vista (no he hecho ninguna prueba metódica de tiempos de carga). Simplemente tenedlo en cuenta.

Uno de los aspectos visuales más llamativos del control panorama es que, Fondo, Título y Contenido se mueven a distintas velocidades cuando deslizas la pantalla con el ratón (difícil de mostrar sólo con imágenes) dando así cierta sensación de profundidad muy lograda.

Vamos a algo concreto: Me gusta la fotografía pero mi habilidad como diseñador gráfico está fuera de toda discusión (todo el muno estará de acuerdo en que es desastrosa). Decidí montar dos fondos muy sencillos para mi Panorama. El primero es una sección de una fotografía que tomé a un tronco un día con los amigos en el campo y, la otra, es una variación de la misma, pero dejando un buen espacio en blanco para facilitar el contraste entre el fondo y las fuentes utilizadas para mostrar los contenidos. Tendré que hacer pruebas, pero la idea queda ahí.

Ejemplos de Fondo Panorama

Ejemplos de Fondo Panorama

En mi caso, como podéis ver un poco más arriba, he decidido utilizar como fondo una imagen. Esta imagen tiene unas dimensiones de 2048×800 píxeles. Los 800 px de alto son importantes para que no haya ningún redimensionamiento vertical de la imagen que pueda afectar a su aspecto.

Mientras no engañe a mi amigo Dannan (o no se deje engañar) para que me ayude con cosas muy básicas de retoque fotográfico, mis herramientas se reducirán al Paint (tengo instalado Gimp y Expression Designer, pero todavía no me he puesto con ello) Visual Studio y Expression Blend.

Este último es fundamental para hacerte una idea de cómo va a quedar tu aplicación y os recomiendo encarecidamente que lo utilicéis si disponéis de él (en próximos posts miraremos qué cosas podemos hacer con Blend que no podemos hacer con Visual Studio de forma inmediata).

Bien, pues pongamos un control Panorama en nuestra aplicación. ¿Cómo? La verdad es que lo más fácil es pedirle a Visual Studio que lo haga por nosotros (también podrías hacerlo manualmente). Simplemente, botón derecho sobre la solución -> Add New Item -> Panorama Page.

Nueva Página Panorama

Nueva Página Panorama

Si no lo habías hecho ya cuando creaste la aplicación, sigue estos pasos y podrás écharle un vistazo al (horror) que ha montado Visual Studio. Después, borra casi todo su contenido, para quedarte con lo mínimo.

De momento, voy a montar una página Panorama con el fondo que os indiqué arriba y con tresPanoramaItem

  1. Sitios Favoritos
  2. Sitios Cercanos
  3. Sitios Recientes

En las futuras versiones incluiré algún control más para poder mostrar (probablemente) mis Sitios Favoritos en un mapa de Bing o similar.

Panorama con tres PanoramaItem

Panorama con tres PanoramaItem

Como podéis ver en el código puesto más arriba, he añadido tres PanoramaItem prácticamente idénticos, en este momento sólo se diferencian en el literal (extraído del fichero de recursos de la aplicación) que se mostrará en el texto. Los tres contienen en este momento un ListBox que debería de mostrar elementos del “ViewModel”.

Merece la pena reseñar que, mientras estamos en modo de Diseño (es decir, mientras te encuentras diseñando tu página con la ayuda de Visual Studio o Blend) es interesante que puedas hacerte una idea de qué aspecto tienen los controles que estás montando. Para ello existe una característica muy interesante que te permite definir un contexto de datos en diseño de forma que puedas consumir información en un XML (por ejemplo) que te ayude a hacerte una idea del aspecto de tu aplicación cuando esta contiene información. Dentro de los atributos de una página de Windows Phone es posible definir un Contexto de Datos (DataContext) y que dicho contexto de datos sea utilizado sólo en modo de diseño tal y como se indica a continuación.

Contexto de Datos de Diseño de Página

Contexto de Datos de Diseño de Página

Para crear un contexto de datos en modo diseño podéis revisar este post.

A ver, vamos a intentar dejarlo más claro. Empecemos por las clases que intervienen en el proceso de presentación de la página principal.

Diagrama de Clases para la Presentación de MainPage

Diagrama de Clases para la Presentación de MainPage

Como se ve en la imagen más arriba disponemos de cuatro elementos en juego.

  1. App: Es la clase que representa el contexto o la aplicación que está en ejecución. Contiene (como vimos en el post anterior) los métodos para gestionar el ciclo de vida.
  2. IMainViewModel: Se trata de una interfaz y es un pequeño cambio realizado a la estructura que por defecto presenta Visual Studio. La clase App dispone de una referencia al ViewModel, sin embargo, en mi caso he preferido cambiar el tipo y hacer que la referencia sea a la Interfaz que ha de implementar dicho modelo. De esta forma mejoramos el acoplamiento (reduciéndolo) y favorecemos la posible inclusión de patrones como la Inversión de Control (IoC) aunque en este momento App instancie directamente la clase y todavía no haga uso del patrón.
  3. MainViewModel: Se trata de la VistaModelo para la página principal. Implementa la Interfaz IMainViewModel y, en este momento se trata de una clase que prácticamente hace sólo dos cosas: Definir una lista de elementos (a través de la propiedad Items) y carga dicha lista de elementos (a través del método LoadData).
  4. MainPage: Por último la clase que representa la página en sí misma y que será la Vista de presentación (la que contiene nuestro elemento Panorama). Esta página se comunica con el MainViewModel a través de la interfaz IMainViewModel que expone la clase App cuando la página es cargada (en la gestión del evento Loaded) tal y como se muestra en el diagrama de secuencia a continuación.
MainPage_Loaded

MainPage_Loaded

En breve nos centraremos en el proceso de DataBinding y veremos cómo podemos hacer para realizar filtros de los elementos que componen nuestro conjunto de lugares.

Empezando con Windows Phone 7.1 (y X) – Creando un Contexto de Datos de Prueba con Blend

Cuando comienzas con el diseño de la aplicación es importante tener presente el aspecto que tendrá la misma. Para ello Blend resulta de mucha ayuda.

Mis Sitios Favoritos en Blend

Mis Sitios Favoritos en Blend

Como podéis ver, se muestra una página (en este caso con un control Panorama) y tres PanoramaItem. Dentro de cada uno de ellos existe un ListBox que, actualmente está vacío. Vamos a ver cómo es posible con Blend, crear una fuente de datos de prueba para poder ver el aspecto que tendrá el control en tiempo de diseño.

Para ello abriemos la pestaña Data y, para el proyecto, escogeremos la creación de una nueve fuente de datos a partir de un Objeto (Object Data Source).

Create Object Data Source

Create Object Data Source

La idea es decirle a Blend, que genere un fichero de datos de ejemplo partiendo del ViewModel que tenemos asociado a nuestra página. En mi caso, después de una pantalla de error debida a que estoy utilizando SQL CE en Windows Phone “No se puede cargar el archivo o ensamblado ‘Microsoft.Phone.Data.Internal'” (el ensamblado no está localizado en mi máquina, está dentro del propio teléfono o del emulador. Hablé de ello en este post).

Error Load Microsoft.Phone.Data.Internal

Error Load Microsoft.Phone.Data.Internal

Como decía, después de este bonito error, que podemos ignorar, seleccionamos la clase que implementa el ViewModel para el cual queremos generar el conjunto de datos de ejemplo.

Seleccionar la Clase que implementa el ViewModel

Seleccionar la Clase que implementa el ViewModel

A partir de aquí, es posible editar el fichero XAML que se crea para nutrirlo con datos de ejemplo.

Xaml con datos de ejemplo

Xaml con datos de ejemplo

En Visual Studio, será necesario marcar la propiedad BuildAction del fichero a “DesignData”

BuildAction a "Design Data"

BuildAction a "Design Data"

Y, posteriormente, crear una fuente de datos de diseño que apunte al fichero (yo lo he hecho a nivel de página, pero es posible hacerlo a nivel de control)

Contexto de Datos de Diseño de Página

Contexto de Datos de Diseño de Página

Con este pequeño esfuerzo ya tenemos elementos que pueden mostrarse en pantalla.

Algunos datos en modo diseño

Algunos datos en modo diseño

Ahora queda adaptar un poco el aspecto que tendrá cada elemento, pero esto lo dejaremos para otro post más adelante.

Empezando con Windows Phone 7.1 (y VIII) – El Ciclo de Vida de una Aplicación

Antes de seguir escribiendo más código, es el momento de hacer un alto en el camino para repasar un poco de teoría. Y parece que lo más apropiado (al menos desde mi punto de vista) es comprender primero cuál es el ciclo de vida de una aplicación en Windows Phone: Desde que aprietas el icono en tu lista de aplicaciones o en un “tile” (baldosa) hasta que sales (o crees haber salido) de tu aplicación.

Empecemos con una referencia para contextualizar -> Aquí.

En la primera versión de Windows Phone, el sistema operativo permitía la ejecución de una única aplicación en primer plano en un momento dado. Para facilitarle la vida al programador el S.O. activaba y desactivaba aplicaciones de manera automática pero exponía una serie de eventos que el programador podía manejar  para almacenar y recuperar el estado de la aplicación. Con Mango, el S.O. además mantiene una imagen de la aplicación en memoria tanto tiempo como le sea posible . De esta manera, se crea la sensación para el usuario de que la aplicación continua su ejecución desde el punto donde la dejó la última vez.

Al proceso por el cual el sistema operativo finaliza el proceso asociado a tu aplicación cuando navegas fuera de la misma se le llama “tombstoning” o “tombstone”. Tombstone significa “Lápida” y no quisiera traducir “tombstoning” como lapidar ya que esto último es más bien matar a pedradas, cosa que de momento asumiré que el Sistema Operativo no va a hacer con el proceso de tu aplicación. En cualquier caso, tanto el nombre como la acción, son bastante descriptivas.

El sistema operativo está llevando a tu proceso a mejor vida pero en un estado de “animación suspendida” almacenando información sobre el estado en que quedó la misma (última página de la aplicación y el historial de navegación dentro de la misma). Si decides navegar de vuelta a tu aplicación, el sistema operativo restaura el proceso de la misma y le pasa el estado en que se quedó cuando saliste de ella por última vez.

En Mango, este modelo se mejoró y es conocido como “fast application switching” o “FAS”. Intercambio Rápido de Aplicaciones.

Siguiendo con ello: si quieres controlar este proceso, deberás de manejar los eventos asociados a esta desactivación y posible tombstoning. Generalmente vas a querer mantener información sobre dos cosas:

  1. El Estado de la Aplicación (Application State). Que no se encuentra asociado a ninguna página en particular y que puede gestionarse mediante los eventos que expone la clase PhoneApplicationService. Esencialmente cuatro: Activated, Closing, Deactivated, Launching. Para aquellos que no controlen el inglés, el matiz es importante, cuando se utiliza el pasado, terminado con la partícula “ed” en este caso el significado es que el evento se lanza cuando ha finalizado la acción que maneja el evento. Es decir, en este caso, cuando la aplicación ya se ha activado o ya se ha desactivado. En el caso del gerundio, terminado con la partícula “ing”, el significado es que el evento se está lanzando en algún momento, desde que se comenzó la acción que maneja el evento, pero sin que esta haya terminado todavía. Así, en este caso, los eventos Closing y Launching se lanzan en algún momento antes de que la aplicación termine de cerrarse o antes de que la aplicación termine de estar lista para arrancar.
  2. El Estado de la Página (Page State). Que representa el estado (posición del cursor, información almacenada, etc…) de la página donde quedó la aplicación en el momento del cierre. Normalmente se suele manejar dicho estado desde los manejadores de eventos OnNavigatedTo y OnNavigatedFrom.

Vale. ¿Cómo sé cuándo el sistema operativo va a ponerle la lápida a mi aplicación y cuándo no? Existe alguna regla al respecto, en general supón que ocurrirá siempre que navegues fuera de tu aplicación… Pero, no podía ser de otra manera, existen excepciones.

Imagina que dentro del contexto de tu aplicación (muchas lo hacen) necesitas sacar una foto o video, escoger una imagen de tu biblioteca, seleccionar un contacto de tu agenda, lanzar el reproductor de medios… En, general, realizar una acción que (estando estrictamente fuera de tu aplicación) tiene para el usuario un sentido dentro del discurso de la misma. Bien, en esos casos, el Sistema Operativo no le va a poner la lápida a tu aplicación (tobmstone, ya sabes). Salvo, claro está que se esté quedando sin memoria, en cuyo caso no se va a andar con miramientos, compréndelo.

Bien. Momento de tomar un respiro y ver si hemos digerido lo anterior.

¿Lo tienes? Bien, sigamos pues que ya queda poco.

Cuál es entonces el ciclo de vida de una aplicación. Pues voy a poner mi versión de un gráfico que he visto por ahí en varios sitios, no porque me sienta original, simplemente porque se entiende mejor cuando intentas hacer un blog en español.

Windows Phone Application Lifecycle

Ciclo de vida de una aplicación en Windows Phone

Si no le has echado un vistazo al artículo que enlacé al comienzo, hazlo ahora. Encontrarás una diferencia importante entre los diagramas que se pintan ahí y el que he pintado aquí. Esencialmente el diagrama en el artículo de la MSDN distingue entre dos estados (no transiciones) de “desactivación” de tu aplicación. En el que el sistema operativo mantiene tu aplicación en memoria (un durmiente, dormant) y en el que lo ha enterrado y puesto la lápida (tombstone).

En esta entrada he preferido no hacer la distincion ya que no tienes forma de saber cuándo el sistema operativo va a realizar a ciencia cierta la operación de tombstone, así que prepárate para ella y te curarás en salud.

Bien, espero que con esto quede claro. A mi, desde luego, me ha ayudado aunque es probable que tenga que repasar algún que otro concepto más antes de seguir adelante con la aplicación.

Empezando con Windows Phone 7.1 (y VII) – Pequeño problema con Code Analysis

Este post será breve (y poco satisfactorio, me temo).

Pensando en la gestión de literales en el código – échale un vistazo a la entrada Empezando con Windows Phone 7.1 (y V) – Soportando varios idiomas – y en cómo podría evitar olvidarme de meter algún literal en el correspondiente fichero de recursos, decidí activar las reglas de “Code Analysis”.

Para quien no lo sepa, estas reglas realizan análisis estático del código. Es decir, aplican un número sorprendentemente alto de reglas para garantizar que el código escrito (y no en ejecución) cumple con una serie de requisitos mínimos de calidad. Definir un conjunto razonable de reglas que todo equipo de programación debe de superar es un buen hábito que recomiendo que incorpores a tu lista (si no lo has hecho ya).

Ayuda a localizar cosas tan evidentes como buenas prácticas en la nomenclatura de tus clases, métodos y miembros (tanto públicos como privados) hasta cosas igual de evidentes, pero mucho más críticas cuando se trata de poner una aplicación en un entorno de producción, como que un objeto que implemente la interfaz IDisposable, efectivamente es liberado cuando deja de utilizarse (a todos aquellos que penséis que, por tener un recolector de basura os podéis olvidar de los recursos del sistema os recomiendo ochenta flexiones en penitencia y volvéroslo a pensar).

Pues bien, alguna de las cosas que Code Analysis puede ayudarte a encontrar son literales que no están incluidos dentro de ficheros de recursos (herramientas como Resharper también ayudan en esto).

Pues ahí que te va: Habilité el análisis de código para mi solución y limité el número de reglas que quería aplicar (no me gusta mucho ver docenas de advertencias /warnings en mi código y el número de reglas a habilitar puede ser muy elevado, así que empecé por un conjunto mínimo).

Revisando la salida de compilación de mi código me encontré con esta advertencia.

Warning 1 CA0060 : The indirectly-referenced assembly ‘Microsoft.Phone.Data.Internal, Version=7.0.0.0, Culture=neutral, PublicKeyToken=24eec0d8c86cda1e’ could not be found. This assembly is not required for analysis, however, analysis results could be incomplete. This assembly was referenced by: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\Profile\WindowsPhone71\System.Data.Linq.dll.  Jdmveira.MisSitiosFavoritos

Bonito. ¿Eh?

¿Qué significa?

Esencialmente, que hay un assembly (Microsoft.Phone.Data.Internal) referenciado desde otro que ya está incluido en tu solución (System.Data.Linq.dll) que no está incluido en tu solución y que, en consecuencia, Code Analysis no puede revisar y, potencialmente, te puede dar un análisis incompleto.

El siguiente paso que uno puede pensar es. ¡Eh, no hay problema! ¡Lo añado a mi solución y listo!

Pues bien, me temo que va a ser que no.

Como todos sabéis existen una serie de APIs de Windows Phone que no están accesibles para el común de los mortales. Estas APIs se encuentran en tu emulador o en tu teléfono, pero tú, oh pobre programador. ¡No puedes acceder a ellas! Reviando un poquitín por ahí, puedes encontrar esta referencia aquí. Y una referncia al tipo de advertencia CA0060 de Code Analysis aquí (donde te dice que si añades la referencia a la DLL que no encuentra, solucionarás la advertencia).

¿Qué nos queda hacer? Pues bien. Si perteneces a un equipo donde tienes establecidas reglas de calidad que no te van a dejar promocionar o entregar el código a tu servidor de código fuente si hay un simple warning de Code Analysis, entonces lo tienes complicado. Porque no vas a poder.

Si, como yo, tener una advertencia (warning) te provoca un leve escozor. Déjalo estar y esperemos a que a los chicos de Microsoft se les ocurra cómo solucionarlo.

¿Quién sabe? Igual en un futuro liberan todas las APIs a todos los desarrolladores.

Soñar es gratis.

Empezando con Windows Phone 7.1 (y VI) – El Contexto de Datos

En esta primera aplicación, estoy creando un modelo de datos muy sencillo: esencialmente se trata de una colección de lugares de interés para el usuario. Poco más que añadir en esta primera iteración ya que, de momento, no daré soporte anidamientos y no habrá relaciones con otras entidades (al menos no las he identificado todavía). Queda para más adelante anidar lugares dentro de lugares y relacionar lugares con personas.

Para la creación del modelo de datos he comenzado con la entidad principal MiLugar: Se trata de una clase muy sencilla que proporciona dos propiedades. un identificador único y un nombre.

Entidad MiLugar en Iteración 1

Entidad MiLugar en Iteración 1

Caben destacar muy poquitas cosas de la entidad:

  1. Implementa la interfaz INotifyPropertyChanged que es de gran utilidad para comunicar cambios en propiedades de la entidad (una buena forma de que, por ejemplo, una vista sepa que la propiedad que tiene asociada a, digamos por ejemplo, un campo de texto ha cambiado y que, en consecuencia, ha de redibujar dicho campo de texto para mostrar el cambio). Veréis más adelante que esta interfaz está en el corazón de la forma en la que se asocian datos y vistas (llamadlas pantallas, si queréis).
  2. Que la entidad ha sido decorada con el atributo TableAttribute y que ambos campos han sido decorados, a su vez con el atributo ColumnAttribute. De esta manera estamos estableciendo las reglas con las que el contexto de datos podrá crear su implementación física a partir de la definición de mi entidad.
DetalleCodigoMiLugar_Iteracion1

Detalle de la entidad MiLugar en Iteración 1: Atributos Table y Column.

Como veis no tiene gran cosa (el código que veis aquí aun no ha sido probado, así que cruzo los dedos para que no me de ningún susto).

Actualización: Cabe decir que el código reflejado ahí arriba compila, pero no funciona en Windows Phone. ¿La razón? El tipo GUID no existe en SQL Server CE, poned en cambio uniqueidentifier y todo irá como la seda.

El siguiente paso es crear la clase encargada de representar el contexto de datos.

DataContext_Iteracion1

Diagrama de clases para el Contexto de Datos en Iteración 1

En este caso se trata de una clase que implementa el patrón Singleton y hereda de la clase DataContext. La única instancia del contexto de datos se puede obtener a través de la propiedad Instancia y contiene una colección de MiLugar que representamos como una propiedad de la clase Table (LugaresDeInteres).

En general, el contexto de datos tiene como propósito abstraernos de los detalles de acceso de la base de datos, limitándose a proporcionar colecciones (tablas) de entidades y mecanismos para buscar, insertar, editar y borrar elementos de dichas colecciones. En ningún momento nuestro código conocerá una sola línea orientada a abrir, crear, consultar o actualizar una base de datos.

Como podéis ver, el proceso de creación de la instancia de DataContext es bastante sencillo. Se pretende garantizar la concurrencia de hilos (cosa que, en esta aplicación será muy sencillo). A continuación, una implementación típica de Singleton y un pequeño detalle. Si la base de datos no ha sido creada todavía: la creamos mediante la línea _dataContext.CreateDatabase (); Fijaos que la cadena de conexión nos indica que la base de datos se referenciará en nuestro Almacén Aislado (IsolatedStorage)

DetalleInstanciaDataContext_Iteracion1

Detalle de la instanciación del DataContext en Iteración 1

A continuación, vamos a llevarnos el contexto de datos hacia arriba en nuestras capas de aplicación. La idea es utilizarlo en nuestras pantallas y, para eso, vamos a aprovechar la infraestructura que crea Visual Studio 2010 para implementar un patrón de capa de presentación llamado Modelo Vista – Vistamodelo (MVVM: Model view – ViewModel). Probablemente le dedique alguna entrada a este patrón, pero no ahora que todavía no lo tengo demasiado claro. Un par de trazos: los patrones de diseño para la capa de presentación llevan dando vueltas por ahí décadas. En un patrón típico Modelo Vista Presentación tienes lo siguiente:

  1. La Vista: Puedes asemejarla sin problemas a tu pantalla
  2. El Modelo: Los datos que se muestran en la vista.
  3. La Presentación: Lo que junta ambas cosas (definición donde las haya. ¿Eh?)

El MVVM es un patrón específico para Windows Presentation Foundation (WPF) que, os recuerdo, es un superconjunto de Silverlight que es con lo que montáis vuestras pantallas en Windows Phone.

Si no os parece mal, dejaremos la capa de presentación y su asociación con los datos para la siguiente entrada.

Empezando con Windows Phone 7.1 (y V) – Soportando varios idiomas

Uno de los primeros pasos que he realizado ha sido dotar a la aplicación de infraestructura necesaria para dar soporte a múltiples idiomas. Esto no significa que la aplicación salga inicialmente soportando varios idiomas, significa que, cuando haya que hacerlo, los cambios que tendré que llevar a cabo serán mínimos.

Imaginad que comenzáis creando una aplicación sin tener esto en cuenta. Cada uno de los literales que introduzcas en tu código (y no me limito únicamente a los que aparecen en la capa de presentación) estarán mejor o peor organizados, pero probablemente dispersos por todo tu código.

Cuando llegue el momento de dar soporte a varios idiomas, tendrás que empezar a buscar estos literales por toooodo tu código, sacarlos a ficheros de recursos y, una vez ahí, comenzar con el proceso de prueba /error hasta que estés seguro de que lo has contemplado todo. A partir de este punto, podrás comenzar a añadir más ficheros de rescursos que den soporte a diferentes idiomas.

Mi aproximación es diferente. He creado la infraestructura necesaria para dar este soporte desde el comienzo. Ahora lo que hay que contar es con la disciplina suficiente como, cada vez que necesites crear un nuevo literal, hacerlo en el fichero de recursos en vez de directamente en tu código.

Ficheros de Recursos en el Proyecto

Varios ficheros de recursos añadidos al Proyecto

A continuación he configurado el idioma neutral del proyecto para que sea el español (de España).

Idioma Neutral por defecto

Configuración del Idioma Neutral para que sea español (España)

Una cosa que me ha llamado la atención es la siguiente: Para indicar qué idiomas soporta la aplicación, es necesario editar el fichero .csproj para indicar dentro del tag <SupportedCultures/> qué idiomas soporta la aplicación. Este fichero tiene un formato XML, sin embargo, abrir el XML en vez del proyecto no es tarea fácil dentro de Visual Studio. Así que he abierto mi fichero con Notepad++ y he introducido dentro de dicho tag (de momento) sólo el español. He guardado, recargado el proyecto en Visual Studio y… Ya está, mi aplicación dice que soporta el español. Para el inglés queda un poquito (tendré que acordarme de separar los idiomas con puntos y comas).

SupportedCultures en el proyecto

Elemento <SupportedCultures/> en el proyecto

En relación a la inclusión de ficheros de recursos, la idea es buena, pero las prisas, el cansancio o la inexperiencia pueden hacer que olvides incluir literales en tus ficheros y sigas metiéndolos en código. ¿Qué hacer en este caso? Pues habrá que mirar Code Analysis. Eso haré y os tendré al tanto.