Incorporando búsquedas a nuestra aplicación Metro

El desarrollo de aplicaciones Metro incluye algunos cambios relativos a la interoperabildad entre aplicaciones, lo que nos permite compartir imágenes, texto y multimedia entre aplicaciones mediante el uso del contrato Share, proporcionar una fuente de ficheros usando el contrato FilePicker, y la última opción, que es la que cubre este artículo, es la de poder realizar búsquedas en nuestra aplicación desde cualquier punto del sistema, y desde cualquier aplicación.

En este artículo se verá cómo agregar un contrato de búsqueda a un proyecto existente, MetroTask, así como la lógica necesaria para poder tener un ejemplo funcional.

Agregar el contrato

Para agregar el contrato de búsqueda, el proceso es el mismo que con el otros contratos, en un proyecto existente, se hace click derecho en el icono del proyecto, a continuación en Add new item… Posteriormente se selecciona Search Contract y se agrega a la solución.

Lo que se agregará al proyecto es un fichero xaml que contendrá la interfaz gráfica de búsqueda, así como el código fuente que procesará el término y mostrará los resultados.

En este caso, no es necesaria una configuración adicional, ya que el fichero appxmanifest, que contiene la configuración de declaraciones, capacidades y detalles como el nombre y el icono de nuesta aplicación, se actualiza automáticamente al agregar el fichero.

Tras agregarlo, se puede compilar el proyecto y ejecutarlo, para comprobar que se ejecuta correctamente, si carga el charm de búsqueda desde cualquier punto de la apliacación, o desde cualquier otro punto de la interfaz metro, lo que se mostrará será la siguiente imagen:

Una vez introducido el término de búsqueda, se mostrará una pantalla similar a la siguiente:

Enlazandolo con los datos

Para este ejemplo, agregaré al servicio web de Tareas una función para buscar proyectos, simplemente una pequeña selección, gracias al uso de LINQ. Con ello se puede hacer una consulta, y devolver solamente los proyectos que cumplan dicha consulta (por nombre, en este caso).

        public IEnumerable<Project> getProjectByName(string name)
        {
            ProjectContext p = new ProjectContext();
            return p.Projects.Where(proj => proj.Name.Contains(name)).AsEnumerable();
        }

Una vez comprobado que el servicio funciona, se agrega en el código una nueva función para gestionar el contenido:

        async void getProjectsByName(string search)
        {
            PageTitle.Text = "Proyectos (Cargando)";
            TaskServiceClient client = new TaskServiceClient();
            try
            {
                this.CollectionViewSource.Source = await client.getProjectByNameAsync(search);
                client.CloseAsync();
                PageTitle.Text = "Proyectos";
            }
            catch (Exception)
            {
                PageTitle.Text = "Se ha producido un error";
                //Show a Message dialog
            }
        }

Posteriormente se agrega la siguiente línea dentro de la función “Activate”

getProjectsByName(queryText);

Finalmente, se agrega el siguiente GridView (tomado de la página “CollectionPage.xaml”)

            <GridView x:Name="ItemGridView" ItemsSource="{Binding Source={StaticResource CollectionViewSource}}" ItemTemplate="{StaticResource GroupedItemTemplate}" ItemContainerStyle="{StaticResource GridTileStyle}" ItemsPanel="{StaticResource GridItemsPanelTemplate}"
              Grid.Row="1" Background="{StaticResource PageBackgroundBrush}" BorderThickness="0" VerticalAlignment="Stretch"
               Margin="0"/>

Esta vista cargará el estilo del fichero App.xaml, usando la misma visualización que la página de colección. Un par de detalles gráficos más, y el resultado es el siguiente:

Conclusiones y posibles mejoras

En este artículo se ha visto cómo agregar la capacidad de búsqueda a la aplicación, y cómo usarla desde cualquier lugar del sistema. Como posibles mejoras está el uso del cuadro de sugerencia de búsqueda, que mostraría los datos según los vamos escribiendo (ver enlace al final del artículo), y se pueden filtrar los resultados una vez obtenidos, ya que el botón que indica All(0) puede llegar a ser bastante descriptivo :).

Más información:

  • Código editado en Codeplex
  • Ejemplo de uso del contrato de búsqueda en MSDN

Ejemplo práctico de desarrollo Metro: MetroTask

Estos días, en la serie de desarrollo para Windows 8 usando la interfaz Metro se han visto varias características que lo hacen bastante diferente, y qué mejor manera que mostrarlas que con un ejemplo completo?

Para ello ha surgido MetroTask, un simple gestor de tareas, organizadas en proyectos. Consiste en 3 proyectos:

  • Una aplicación Metro (C#).
  • Un servicio web WCF.
  • Una aplicación de consola que uso para depuración.
Para poder abrir el proyecto, se necesita Windows Developer Preview, así como Visual Studio 11 Developer Preview.

Es un proyecto en curso, y por ahora es poco funcional, pero espero que se convierta en un ejemplo completo que poder mostrar y continuar su desarrollo.

Entre las características comentadas, y que se incluyen, están:

  • Conexión a un servicio WCF
  • Uso de la App Bar para crear tareas
  • Uso de la opción de compartir para crear tareas a partir de otras aplicaciones.
Las características que pienso incluir de cara a una primera versión estable son:
  • Creación, edición y eliminación de tareas.
  • Creación, edición y eliminación de proyectos.
  • Alertas cuando la tarea caduque.
  • Uso de los tiles para recuento de tareas pendientes, y similar.
Por ahora la funcionalidad, como he comentado antes, es limitada, por lo tanto solamente se pueden agregar tareas a proyectos actuales, que solo se pueden editar en la base de datos de manera manual (estoy trabajando en ello, y portar la App Bar a la otra ventana).
Cualquier funcionalidad adicional, o crítica sobre el estilo de código será amablemente recibida, se puede dejar el comentario aquí en el blog, o en la página del proyecto en CodePlex.

Más información

Windows Phone Mango Roadshow: Impresiones

Durante el mes de octubre se está celebrando en España una serie de eventos para desarrolladores de Windows enfocados a las novedades que trae la nueva versión de Windows Phone, de nombre en clave Mango y de denominación oficial 7.5. Tuve la oportunidad de asistir a las dos sesiones que se celebraron en Madrid, y las resumo a continuación.

Primer día

La maestra de ceremonias ha sido Isabel Gómez, responsable del desarrollo de aplicaciones y juegos para Windows Phone 7 en Microsoft Iberica.

La presentación estuvo a cargo de Manuel Reverte, de Nokia, donde comentó la necesidad de crear un ecosistema donde el fabricante de teléfonos pudiera tener un caracter diferenciador, así como poder influenciar, algo que la alianza con Microsoft iba a permitir, así mismo nos animó a seguir el evento Nokia World 2011, que será el próximo 26 de octubre.

Tras ello, Ben Riga, Technical Evangelist de Microsoft Corporation explicó qué elementos hacían de Windows Phone una plataforma diferente así como los cambios que ha traido “Mango” para los usuarios, como la integracíón de diferentes redes sociales como Twitter, Facebook y LinkedIn, el nuevo navegador de serie (IE9) o las live Tiles, iconos con información contextual que hereda Windows 8.

Posteriormente pasamos al resto de las sesiones técnicas, impartidas por Eduardo Ortega Bermejo y Jose Antonio Gallego Salinas.

La primera, relacionada con la plataforma de desarrollo, e impartida por En ella se describió, entre otras novedades de Mango, la posibidad de crear aplicaciones que combinen XNA y Silverlight para poder aprovechar los menús de una y las capacidades 3D de otra, la introducción de SQL Server Compact como motor de base de datos relacional local, o el uso de Sockets para juegos o aplicaciones de streaming.

Respecto a las herramientas, contamos con Visual Studio 2010 Express, así como una versión especial de Blend, completamente gratuitas.

Tras hablar de las herramientas, hubo una sesión de datos, servicios y live tiles, donde se comentó cómo usar SQL Server Compact en nuestras aplicaciones usando LINQ to SQL, cómo usar los servicios de notificaciones Push que provee Microsoft para enviar datos a nuestras aplicaciones, y cómo emplear Live Tiles para dar vida a nuestras aplicaciones una vez cerradas.

Después de la comida, una sesión enfocada a la nueva multitarea de Mango, los agentes en segundo plano, las tareas periódicas, como alarmas y recordatorios, las tareas de audio o transferencia de ficheros y cómo se puede aprovechar para que el usuario recupere el estado de la aplicación tras haber sido cerrada por el sistema (por consumo de memoria, por ejemplo).

Tras esta sesión, se mostró de manera práctica el desarrollo de una aplicación paea WP7, diseñandola primero mediante Blend, el uso de datos de ejemplo, las animaciones, y luego la codificación usando Visual Studio.

El dia se cerró con una sesión sobre comercialización de aplicaciones, alternativas como la publicidad, y algunos trucos para que nuestras aplicaciones de WP7 brillen en el marketplace, así como una recopilación de recursos, iniciativas y ayudas.

Segundo día

El segundo día también estuvo lleno de charlas técnicas, así como la oportunidad para que los asistentes pudiera plantear sus dudas a los más de 10 expertos de Silverlight, XNA y representantes de Microsoft presentes en la sala. Los temas que se discutieron fueron:

  • Diseño con Expression Blend, donde se dio una introducción a la herramienta, creación de interfaces, manejo de eventos y lineas de tiempo.
  • Networking con WP7, donde se describieron diferentes maneras de acceder a los datos en un servicio web.
  • Unit Testing, donde se describieron buenas prácticas y el por qué de probar nuestro código, además de un ejemplo práctico.
  • Integración Silverlight-XNA, donde se mostró un ejemplo de cómo usar ambas tecnologías en una sola aplicación.
  • Localización, donde se describió cómo permitir que nuestra aplicación se muestre en varios idiomas usando ficheros de recursos.

En resumen, una buena experiencia que personalmente me ha dado una idea bastante global del ecosistema WP7, además de sus características más destacadas, puede que veas alguna app mía por aquí, y si tienes la suerte de estar en una ciudad donde se celebre, aún puedes pasarte y echar un vistazo.

Más información sobre el evento:

Roslyn CTP: Compiler as a service

Microsoft acaba de lanzar la Comunity Tech Preview de la herramienta Roslyn, que representa otra herramienta para los desarrolladores, esta vez en un servicio basado en extender capacidades del compilador para dar funcionalidades a los programas bastante más allá de nuestra imaginación.

Qué hace un compilador

Hasta la fecha los compiladores han sido, para algunos, una caja negra que generaba el ejecutable de manera mágica. Para otros un programa que convertía el fichero en un código objeto y posteriormente lo enlazaba, y, finalmente para los que hemos sufrido asignaturas del tipo Procesadores de lenguaje, es un programa que realiza varios pasos:

  • Análisis morfológico: Comprueba que los caracteres signifiquen variables, comandos, no nos falte ningún punto y coma o que no pongamos caracteres ilegales en el código
  • Análisis sintáctico: Comprueba que la formación del código sea la correcta, te falta un paréntesis o una llave que has borrado accidentalmente? esto lo detecta el analizador sintáctico.
  • Análisis semántico: Comprueba que el significado del código sea correcto, estás asignando un entero a una variable de tipo cadena?, o no devuelves un valor en una función declarada como void. Esto lo detecta el analizador semántico.
  • Generación de tabla de símbolos: La tabla de símbolos permite comprobar el estado de las variables, y donde buscar su significado (gestión de variables globales, argumentos, puntos de retorno de las funciones, etc).
  • Generación de código: Si el código es correcto, se sustituyen las porciones por código ensamblador correspondiente, se sustituyen valores y se genera un fichero ensamblable. Existen compiladores que generan directamente código objeto y se saltan este paso.
  • Optimización: Mediante técnicas como el desenrollamiento de bucles, se pueden conseguir unos ciclos de ejecución más, además de posibles técnicas para múltiples procesadores.

De hecho, hacer un compilador no es demasiado difícil. Se requieren ciertos conocimientos de Ensamblador, teoría de lenguajes formales, y paciencia. El análisis morfológico, sintáctico y semántico se puede hacer con las herramientas flex y bison, y generar un fichero ensamblador usando la herramienta NASM, en un proceso que lleva aproximadamente… un cuatrimestre para un grupo de 5 personas.

El caso, es que para arquitecturas como .net el proceso será un poco más complicado.

Las novedades

Lo que hace a Roslyn una herramienta tan especial, es que cada una de las fases que se han comentado antes tendrá una API específica, con lo cual nos encontraremos con varias API diferentes para las siguientes fases:

  • Árbol sintáctico
  • Tabla de símbolos
  • Enlace y análisis de flujo (semántico)
  • Generación de código.

Estas API proporcionan nuevos servicios para los lenguajes de programación, como resaltado de sintaxis, explorador de objetos, capacidad de refactoring, que podremos extender para nuestros proyectos.

Esto nos permite tener la capacidad de compilar código de manera dinámica (en tiempo de ejecución) desde un programa, o definir funciones que son creadas sobre la marcha, es decir, hacer programas que creen programas o metaprogramación, algo bastante común a lenguajes funcionales como LISP.

Esta capacidad permite tener una consola REPL (Read-Eval-Print-Loop) para poder usar C# o Visual Basic, o ejecutar directamente un código seleccionado. Esta consola se incluye con la CTP de Roslyn, y tiene IntelliSense, completado de código, opciones de refactor, ejecución de LINQ, generar interfaces de forma dinámica… para un código que estamos escribiendo en una consola, no esta nada mal.

En resumen, una utilidad muy interesante que seguramente hará las delicias de algunos, y que ahora está disponible para jugar con ello, y descubrir nuevas maneras de generar y usar el código (como por ejemplo hacer una utilidad que convierta de C# a VB).

Más información:

Hands-on Labs de desarrollo de aplicaciones Metro

Microsoft ha agregado, como parte del Training Kit de Visual Studio 11 Developer Preview, varios Hands-on Labs para aprender a usar las características de Metro. Estos tutoriales, de aproximadamente una hora de duración, cubren una buena cantidad de novedades de Metro, algunas de las que se han descrito en este blog.

Hay en total casi 20 labs usando C#, Visual Basic, Javascript y C++, entre los que se incluyen los anteriormente comentados, ejemplos de creación de juegos con C++, diseño de interfaz con Blend, pruebas o interacción de Javascript y C#, entre otros.

Sin duda una manera muy práctica de aprender a desarrollar aplicaciones Metro.

Más información:

Proporcionar ficheros en aplicaciones Metro

En el artículo anterior se ha visto cómo se consumían ficheros desde una aplicación Metro, en este se verá cómo convertir una aplicación existente en un origen de datos para otras aplicaciones

Proporcionando ficheros

La otra cara de trabajar con ficheros permite a nuestras aplicaciones proporcionar archivos directamente de los servicios a los que estén conectados.

¿Qué aplicaciones deberían implementarlo?

En general, cualquier aplicación que trabaje con ficheros, entre las que se puede mencionar, como ejemplo:

  • Redes sociales, para obtener fotos o vídeo directamente.
  • Programas que reciban RSS de vídeo, música o imágenes.
  • Gestores de tareas que almacenen, para cada proyecto, ficheros.
  • Blocs de notas, etc…

Implementación

Para que la aplicación desarrollada que nuestra aplicación tenga esta funcionalidad, debe incluir el contrato Picker, que se agrega en la ventana Project > Add New Item… :
Una vez agregado, es necesario configurar, como se ha visto en el artículo dedicado al contrato Share, la opción Supported File Types en el fichero .appxmanifest. Esta opción permitirá limitar a qué tipo de ficheros accederán las otras aplicaciones.


Una vez hecho esto, se habrá creado una plantilla similar a la de compartir. La diferencia es que todo el manejo de ficheros y la interfaz tendrá que ir por nuestra cuenta, mientras respetemos los elementos comunes de la interfaz.

El objeto más importante para poder proporcionar ficheros es el objeto FilePickerBasket, que servirá como enlace común.al resto de las aplicaciones.

Para poder agregar ficheros al Basket se usará un código similar en el caso de que la ruta al fichero sea local:

StorageFile pickedFile = await Package.Current.InstalledLocation.GetFileAsync(@&quot;ruta\al\fichero&quot;);
this.AddFileToBasket(&quot;Fichero local&quot;, pickedFile);

En el caso de que el fichero se encuentre en un servidor remoto, será necesario que el servicio asociado proporcione una URL para poder acceder a él, y el propio sistema se encargará de descargarlo y asociarlo a la aplicación que lo requiera.

StorageFile pickedUriFile = await StorageFile.GetFileFromUriAsync(uri, filename, StreamReference.CreateFromUri(&quot;http://ruta/al/fichero&quot;));
this.AddFileToBasket(&quot;Fichero remoto&quot;, pickedUriFile);

La última línea cargará el siguiente código auxiliar, válido tanto para ficheros locales como remotos.

        void AddFileToBasket(string id, StorageFile file)
        {
            bool inBasket;
            switch (this.basket.AddFile(id, file))
            {
                case AddFileToBasketResult.AddedToBasket:
                case AddFileToBasketResult.AlreadyInBasket:
                    inBasket = true;
                    break;

                default:
                    inBasket = false;
                    break;
            }
            this.UpdateSelectionState(id, inBasket);
        }

Para eliminar un fichero del Basket el código sería este, válido tanto para un fichero local como para un fichero remoto:

id = &quot;Nombre del fichero&quot;;
if (this.basket.ContainsFile(id))
{
    this.basket.RemoveFile(id);
}

Conclusiones

Las nuevas maneras de consumir y proporcionar ficheros de las aplicaciones Metro permite, al igual que como se veía en los artículos dedicados a las opciones de compartir, llegar a un nuevo nivel de interacción entre diferentes aplicaciones y con el propio sistema.

Serán los propios usuarios, quienes descubran nuevas maneras de combinar las aplicaciones existentes usando estos nuevos servicios, creando una nueva experiencia en el uso de sus ordenadores personales.

Más información

Consumir ficheros en aplicaciones Metro

En artículos anteriores se ha visto cómo compartir contenido desde nuestras aplicaciones así como consumir contenido de otras. En este artículo y en el siguiente se hablará de cómo consumir ficheros del sistema de archivos, y como proporcionar opciones para que otras aplicaciones puedan hacerlo usando el contrato File Picker.

Consumiendo ficheros

Para poder consumir ficheros solamente es necesario cargar un menú, de la misma manera que lo haríamos con una aplicación Windows Forms.

Lo primero necesario es una referencia a Windows.Storage.Pickers así como a Windows.Storage

Tras agregar la referencia, el siguiente paso es cargar el filePicker, para ello, se puede asignar a un botón, enlazandolo con el evento Click, o también se podría cargar automáticamente (por ejemplo, si estuviese vacía una base de datos, para una importación inicial). Estos métodos, como se ha visto en otros artículos relacionados con Metro, deberán ser asíncronos.

Finalmente se podrán establecer filtros para seleccionar una extensión concreta, la manera de mostrar el menú de selección, o si lo que se carga es una selección simple o una múltiple.

De esta manera para seleccionar un único fichero txt situado en la biblioteca Documents, y que se muestre como una lista de ficheros, el código a usar será este:

async void Button_Click(object sender, RoutedEventArgs e)
{
    FileOpenPicker openPicker = new FileOpenPicker();
    openPicker.ViewMode = PickerViewMode.List;
    openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
    openPicker.FileTypeFilter.Add(".txt");
    StorageFile file = await openPicker.PickSingleFileAsync();
}

Como alternativas a este código, si el objetivo es cargar múltiples ficheros, se ha de cambiar la última llamada del código por pickMultipleFilesAsync(). En caso de que el contenido sean imágenes, lo más recomendable sería cambiar la cuarta línea del código para que se mostraran como miniaturas, para lo que se usaría PickerViewMode.Thumbnail.

En el próximo artículo se mostrará cómo se pueden proporcionar ficheros a otras aplicaciones y al sistema como si de otro origen de datos se tratara.

Más información