Archivo de la etiqueta: vs11

Live Tiles en Metro, la herencia de Windows Phone

Si ha tenido la ocasión de ver un Windows Phone antes de Windows Developer Preview, habrá notado que las similitudes son mas que notables, en concreto en lo que se refiere a los iconos, unos elementos mucho mayores que lo habitual y que poseen información adicional. Para muestra un par de imágenes:

Windows Phone

Windows 8

En este articulo se verá una definición de estos iconos, los Live Tiles, sus características y como actualizarlos desde nuestra aplicación.

Los tiles: Definición y características

Un Tile (cuya traducción a castellano sería algo así como baldosa) es en su base un icono que identifica nuestra aplicación. Un Live Tile, es un icono vivo, que además de servir como primera imagen de nuestra aplicación permite que el usuario reciba información de esta aún estando cerrada. Se pueden actualizar los tiles de varias maneras:

  • En la aplicación principal, lo que se verá en este artículo
  • Usando un proceso en segundo plano, que servirá para actualizar la aplicación aunque ésta esté cerrada.
  • Mediante una notificación push desde un servidor remoto

Existen dos tipos de tiles:

  • Básico, de tamaño 150x150px y obligatorio para poder enviar la aplicación al marketplace.
  • Ancho (Wide), de tamaño 310x150px y opcional, permitirá mostrar un icono que ocupe dos espacios contiguos.
Además, existe como en Windows Phone la opción de crear Tiles secundarios con información adicional y que permitan un acceso directo a un apartado concreto de nuestra aplicación.

Implementación

Para este ejemplo, se parte de la aplicación MVCTask que estaba desarrollando, donde se actualizará el tile para que muestre el número total de proyectos. Este código se ejecutará tras recibir desde el servidor la información de proyectos.

        /// <summary>
        /// Actualiza el icono de la aplicación con un número
        /// </summary>
        /// <param name="numero"></param>
        void ActualizarIcono(int numero)
        {
            // Se obtiene desde la plantilla el documento XML que contendrá el XML del icono
            XmlDocument badgeXml = BadgeUpdateManager.GetTemplateContent(BadgeTemplateType.BadgeNumber);

            // Se edita el XML para agregar los datos deseados, en este caso un número
            XmlElement badgeElement = (XmlElement)badgeXml.SelectSingleNode("/badge");
            badgeElement.SetAttribute("value", "" + numero.ToString());
            badgeElement.SetAttribute("version", "1");

            // Se crea una notificación desde el XML editado
            BadgeNotification badge = new BadgeNotification(badgeXml);

            // Finalmente, se actualiza el contenido de la aplicación
            BadgeUpdateManager.CreateBadgeUpdaterForApplication().Update(badge);
        }

A diferencia de Windows Phone, en este caso las Tiles no se especifican de una manera explícita, sino que es necesario crear un texto en formato XML que contendrá esta información. Esto permite poder crear tiles más complejos que en el sistema móvil.

La función mostrada anteriormente obtiene el XML básico de un constructor, agrega el dato del número (en este caso value, que contendrá el número de proyectos obtenidos), se crea un nuevo elemento Badge a partir de este XML, y finalmente usando el BadgeUpdateManager, se actualiza el icono de la aplicación, quedando entonces de esta manera:

Icono sin indicador

Icono con indicador

 

 

 

 

 

 

Como se aprecia, el propio sistema se encarga de crear todo el estilo alrededor de la notificación, y se puede ver la diferencia entre los iconos.

Conclusiones

Los Live Tiles permiten conseguir una interacción con el usuario más allá de la de hacer de lanzador de la aplicación, lo que aumenta las posibilidades de que el usuario vuelva a ejecutarla respecto a aplicaciones que no posean estas características.

En el próximo artículo se verá cómo crear un tile de tamaño doble con más información, así como un tile secundario que acceda a un proyecto concreto.

Más información:

Anuncios

Panel de preferencias para nuestra aplicación Metro

El panel o Charm de preferencias, que se muestra al pulsar la combinación de teclas Windows + I o al seleccionar Settings en el menú de inicio, contiene la información de la aplicación, información genérica del sistema como wifi, brillo o estado de batería. Además de esta información, nuestra aplicación Metro puede colocar enlaces a secciones como las preferencias, acerca de, etc.

En este artículo se verá cómo agregar enlaces a este panel, y posteriormente cómo crear un panel de preferencias que se muestre u oculte usando estos enlaces. El código de este artículo está basado en la última versión de MetroTask, disponible en Codeplex, y en el estado en el que quedó en el anterior artículo.

Agregar los accesos

Para poder agregar los accesos al menú de preferencias primeramente se ha de obtener una referencia al panel de preferencias de la vista actual, siendo este dependiente de la página que se este mostrando.

Posteriormente se agregarán, a la colección ApplicationCommands, el comando deseado, para que se muestre en el panel. Además de agregar un campo que muestra el texto del comando o en este caso, un valor de la colección KnowSettingsCommand, Además, se agregará la llamada a una función que se ejecutará al pulsar sobre la opción:

public CollectionPage()
{
   ...
   SettingsPane pane = SettingsPane.GetForCurrentView();
   pane.ApplicationCommands.Add(new SettingsCommand(KnownSettingsCommand.About, About);
   ...
}

private void About(IUICommand command)
{
    //Aquí se situará la lógica de las preferencias
}

El resultado se aprecia a continuacíón. Este botón ejecuta el comando seleccionado, que sin duda podría cargar otra página con la configuración y las preferencias, pero los ejemplos mostrados nos dan la idea de que el panel de preferencias de nuestra aplicación debe tener un formato similar al Charm que se muestra, y eso es lo que vamos a hacer a continuación.

Crear el panel

Para crear un panel de preferencias el proceso consiste en crear una página XAML (que en este caso se llamará AppSettingsPane), cargarla dentro de la vista mostrada, y ocultarla, de tal manera que la acción que se ejecute sea solamente mostrarla.

Para poder cargar la página lo primero es agregar una sentencia using al documento xaml, para poder usar las referencias al proyecto, y posteriormente cargar la misma:

xmlns:local="using:Tareas"
...
<local:AppSettingsPane x:Name="Settings" HorizontalAlignment="Right" Margin="0,0,-346,0"/>
...

Con este proceso se incrusta el contenido del fichero AppSettingsPane en la página, desplazado 346px a la derecha (y oculto), según dicta la guía de diseño. Finalmente se modifica el código generado anteriormente para que desplace la capa:

private void About(IUICommand command)
{
    Settings.Margin = ThicknessHelper.FromUniformLength(0);
}

El problema de este código es que no hay manera de ocultar la ventana, para lo cual se agrega un método adicional llamado PointerPressed en el Grid principal, que estará pendiente de los cambios de posición del cursor, lo que permitirá que cuando el cursor haga click fuera del panel este se oculte.

<Grid x:Name="LayoutRoot" PointerPressed="LayoutRoot_PointerPressed" Style="{StaticResource LayoutRootGridStyle}">

 

        private void LayoutRoot_PointerPressed(object sender, Windows.UI.Xaml.Input.PointerEventArgs e)
        {
            if (Settings.Margin.Right == 0)
            {
                Settings.Margin = ThicknessHelper.FromLengths(0, 0, -346, 0);
            }
        }

Conclusiones

Las preferencias permiten al usuario personalizar su aplicación, habilitar o deshabilitar funciones, y está en nuestras manos proporcionar un panel que permita dicha personalización. En este artículo se ha visto cómo insertar un elemento en el panel de preferencias, y cómo cargar un menú de opciones desde éste.

Más información

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

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:

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