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(@"ruta\al\fichero");
this.AddFileToBasket("Fichero local", 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("http://ruta/al/fichero"));
this.AddFileToBasket("Fichero remoto", 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 = "Nombre del fichero";
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

Conectándonos desde Metro a un servicio web con WCF

El enfoque de las aplicaciones Metro está centrado en el contenido más que en el continente, aunque en esta serie de artículos se han visto varias características que hacen únicas las aplicaciones de Windows 8. En este artículo se verá cómo crear un servicio WCF muy simple, y acceder a él desde una aplicación Metro.

Para este artículo se necesita la versión completa de Visual Studio 11, que se puede desde aquí ya que la versión que se incluye está limitada a creación de aplicaciones Metro únicamente.

Creando el servicio

Un servicio web es un conjunto de funciones que expone un servidor, y a las que puede acceder un cliente. Para crear un servicio WCF basta con agregar un nuevo proyecto a la solución, de tipo WCF Service Application:

De los elementos creados, los más interesantes son los siguientes:

  • IService.cs: Contiene la interfaz pública que expondrá el servicio.
  • Service.svc: Contiene la implementación de lo expuesto en la interfaz.

Además de estos elementos, se agrega una clase Project que servirá como ejemplo para recibir un dato compuesto del servidor.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TareasService
{
    public class Project
    {
        public int ProjectId { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
    }
}

Finalmente, se crea un método para poder obtener una lista de proyectos del servidor:

...
public IEnumerable<Project> getProjects()
{
    return new List<Project>{
        new Project{Name="Proyecto1"},
        new Project{Name="Proyecto2"}};
}
...

En el fichero de interfaz, se agrega la cabecera de la función:

...
[OperationContract]
IEnumerable<Project> getProjects();
...

Al compilar y ejecutar el proyecto se mostrará una ventana del navegador con instrucciones para consumir este servicio de manera manual.

Consumiendo el servicio

Para consumir el servicio se ha de agregar una referencia al proyecto, haciendo click derecho en el proyecto y seleccionando la opción «Agregar referencia de servicio«. En la ventana que surgirá, al hacer en el botón «Discover» se mostrará una referencia a todos los proyectos de tipo servicio web que se hayan creado recientemente como se muestra en la imagen:


Una vez pultado OK se habrá importado la referencia en el proyecto y se podrán usar las funciones definidas anteriormente.

En el caso de aplicaciones Metro, la técnica obliga a usar los métodos asíncronos, siendo la manera de tratar las funciones diferente, como se muestra en el código.

...
    TaskServiceClient client = new TaskServiceClient();
    Task<List<Project>> results = client.getProjectsAsync();
    List<Project> result = results.Result;
    this.Items = result;
    client.CloseAsync();
...

Para poder visualizar la información se emplea el enlace a datos o databinding, una característica de los controles XAML que permite definir directamente la correspondencia entre los distintos elementos de una clase y los campos a visualizar de un documento XAML.

...
<DataTemplate x:Key="GroupedItemTemplate">
    <Grid HorizontalAlignment="Left" Width="252" Height="252">
        <StackPanel Grid.Column="1" Style="{StaticResource OverlayStackPanelStyle}">
            <TextBlock TextWrapping="Wrap" Text="{Binding Name}"" HorizontalAlignment="Stretch" Height="60"/>
            <TextBlock TextWrapping="Wrap" Text="{Binding Description}" HorizontalAlignment="Stretch" Height="20"/>
        </StackPanel>
    </Grid>
</DataTemplate>
...

Importante: En Windows 8 será necesario abrir el puerto TCP del firewall para que la aplicación tenga acceso al servicio, de otra manera el sistema devolverá un error.

Con esto sería suficiente para que la aplicación tenga la capacidad de acceder a un servicio web. Con algo de práctica no será dificil tener un servicio un poco más complejo

Más información:

Interacción en Metro: Application Bar

En el artículo anterior se ha visto cómo agregar un menú contextual a una aplicación Metro. La otra interacción disponible es la Application Bar, que sustituye la barra de menús y las diferentes barras de herramientas. En este artículo se verán las caracteristicas que hacen diferente la Application Bar y cómo implementar una.

Características

La Application Bar se puede situar encima o debajo de la pantalla, ya que los laterales están reservados para el cambio de aplicaciones y las diferentes charms, de las que se ha hablado en este artículo.

Otra característica, es que es deseable, y así se muestra en las aplicaciones de ejemplo, que los controles se sitúen a los lados de la pantalla, ya que, al estar enfocado a tablets, los laterales hacen el acceso táctil más fácil al sostener el ordenador con ambas manos.

Además, usando este control se podrán mostrar notificaciones, como la que aparece al terminar de descargar un fichero en Internet Explorer.

Implementación

Para poder implementar esta funcionalidad se agrega un control de tipo ApplicationBar a la página, dentro del contenedor principal (Un grid o un StackPanel). En este control se especifican las propiedades como la alineación, el color de fondo, su persistencia y el estado que tendrá al cargar la página.

<ApplicationBar x:Name="AppBar" Grid.ColumnSpan="2" Grid.Row="2" VerticalAlignment="Bottom" IsPersistent="False" IsOpen="True"
                Height="Auto" DismissMode="EdgeSwipe" HorizontalAlignment="Stretch" Background="#548D8D8D">

El resto del comportamiento es similar a cualquier otro contenedor de XAML como se aprecia en el código completo:

     <ApplicationBar x:Name="AppBar" Grid.ColumnSpan="2" Grid.Row="2" VerticalAlignment="Bottom" IsPersistent="False" IsOpen="True"
                Height="Auto" DismissMode="EdgeSwipe" HorizontalAlignment="Stretch" Background="#548D8D8D">
            <ApplicationBar.Resources>
                <Style TargetType="TextBlock">
                    <Setter Property="FontFamily" Value="SegoeUI" />
                    <Setter Property="FontSize" Value="12" />
                    <Setter Property="Foreground" Value="White" />
                    <Setter Property="HorizontalAlignment" Value="Center" />
                </Style>
            </ApplicationBar.Resources>
            <Grid Margin="15,0,15,0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="90" />
                    <ColumnDefinition Width="70" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="70" />
                    <ColumnDefinition Width="90" />
                </Grid.ColumnDefinitions>
                <StackPanel Orientation="Vertical" Margin="0,14,0,5" Grid.Column="0">
                    <Button Margin="0,0,0,10"/>
                    <TextBlock Text="Back" />
                </StackPanel>
                <StackPanel Orientation="Vertical" Margin="0,14,0,5" Grid.Column="4">
                    <Button Margin="0,0,0,10"/>
                    <TextBlock Text="View Full" />
                </StackPanel>
            </Grid>
        </ApplicationBar>

El resultado será una barra como la que se muestra en la siguiente pantalla:

Mas información en MSDN:

Interacción en Metro: Menú contextual

En cualquier aplicación de escritorio existen varias maneras de interactuar, podemos usar botones dentro de una aplicación, como es el caso de un instalador o un asistente de cualquier tipo, podemos hacer click derecho sobre una palabra o un elemento y obtener un menú contextual, o podemos recurrir al menú, situado habitualmente en la esquina superior izquierda con múltiples opciones a nuestra disposición.

Esta idea también ha cambiado, o mejor dicho, evolucionado en Windows 8, ya que ahora veremos aplicaciones donde es más importante el contenido que las propias opciones de la aplicación, quedando la interacción de menús en un discreto segundo plano. Para ello, en este, y en el siguiente artículo vamos a comentar dos opciones de interacción que han cambiado razonablemente en Windows 8, el menú contextual y la barra de menús, denominada a partir de ahora Application Bar.

Menú contextual

Acostumbrado a aparecer cuando pulsamos click derecho, nos ofrece una serie de opciones sobre el elemento sobre el que estamos en este momento, como copiar, comprimir o borrar, entre las mas habituales del explorador de Windows.

En metro la idea es similar, accederemos mediante click derecho con teclado y ratón. sin embargo, con metro tenemos una limitación que es que no podemos tener mas de 5 elementos presentes en el menú, y como se aprecia la interfaz está preparada para interacción táctil, con más espacio y una apariencia más ligera.

Para implementar este click derecho, nos dirigimos al objeto al que querramos aplicarlo (en mi caso fue un ContentControl que contenía un texto) y agregamos una función handler que responda al evento RightTapped, que viene a significar click derecho.

ItemDetail.RightTapped += new Windows.UI.Xaml.Input.RightTappedEventHandler(ItemDetail_RightTapped);

En el cuerpo de la función definimos nuestro menú contextual y las diferentes opciones que tendremos. Tenemos dos opciones para recibir la información del menú:

  • En el segundo parámetro del constructor de UICommand especificamos un callback (una función que se llame en caso de seleccionarlo.)
  • Recoger el resultado de la función ShowForSelectionAsync y a partir de ahí seleccionar en base al indice obtenido.
        async void ItemDetail_RightTapped(object sender, Windows.UI.Xaml.Input.RightTappedEventArgs e)
        {
            PopupMenu menu = new PopupMenu();
            menu.Commands.Add(new UICommand("Enviar por e-mail", null));
            menu.Commands.Add(new UICommand("Borrar", null));
            await menu.ShowForSelectionAsync(GetElementRect((FrameworkElement)sender));
        }

El otro parámetro que será necesario definir será la posición, para lo cual hemos recurrido a algo de ayuda de los ejemplos de la API, y es una función que genera el rectángulo del elemento que está efectuando la llamada.

        Rect GetElementRect(FrameworkElement element)
        {
            GeneralTransform buttonTransform = element.TransformToVisual(null);
            Point point = buttonTransform.TransformPoint(new Point());
            return new Rect(point, new Size(element.ActualWidth, element.ActualHeight));
        }

Conclusión

Pese a que ahora parece distinto, el menú contextual sigue teniendo especial importancia en el desarrollo de interfaces, y no deberíamos por tanto descuidarlo o ignorarlo. Al final del artículo está una referencia a la documentación de interfaz de usuario de Metro.

En el siguiente artículo veremos cómo usar la Application Bar como sustituto de la barra de menús en nuestra aplicación.

Mas información en MSDN

Capacidad de compartir para nuestra aplicación Metro

Una de las opciones que incorpora Windows 8, es el chime o pestaña Share, que permite que nuestras aplicaciones puedan enviar contenidos a otras de una manera sencilla. Para ello, tanto la aplicación origen como la destino tiene que tener la capacidad de aceptar elementos (ShareTarget) o de enviarlos (SendTarget).

Continuar leyendo «Capacidad de compartir para nuestra aplicación Metro»

Instalando Windows 8 Developer Preview + Visual Studio 11 en un Macbook Pro

Instalar un sistema operativo que está en fase pre-beta puede tener sus complicaciones. Si lo instalas en un Mac, la cosa se puede complicar aún más. El sistema que tengo (Un MacBook Pro 13′ de mediados de 2010) con una única partición de OSX. No quiero instalarlo en nativo 100%, así que instalaré vía Bootcamp una copia de Windows 7 Profesional x64 y encima de ella, Windows 8 versión x64.

1. Particionar

El primer paso será reducir el tamaño de nuestra partición para poder hacer hueco para Windows.

Para ello, usamos el Asistente Boot Camp que nos permite reducir el tamaño de nuestra partición de OSX, aunque podemos encontrarnos con un error de este tipo:

El disco no puede dividirse en particiones porque algunos archivos no pueden moverse. Guarde una copia de seguridad del disco y utilice la Utilidad de Discos para formatearlo como un único volumen Mac OS Plus (con registro). Restituya la información en el disco y vuelva a usar el Asistente Boot Camp

Evidentemente no queremos formatear el ordenador, ya que sería cuanto menos, un contratiempo. Podemos omitir este error usando los pasos siguientes:

  1. Abrir Utilidad de discos.
  2. Seleccionar el disco que queremos reparticionar.
  3. Reparar disco y Reparar permisos.
  4. En la pestaña Particiones reduciremos el tamaño al tamaño que querramos.
  5. Una vez que hayamos reducido la partición la volveremos a ampliar, y ya podremos usar Boot Camp.

En este proceso lo que hemos hecho ha sido mover los ficheros a otra parte del disco, un proceso que el asistente de BootCamp no soporta, pero Utilidad de Discos sí.

2. Instalar Windows 7

Tras usar el asistente de Boot Camp, instalamos Windows 7 (en mi caso versi’on  siguiendo los pasos del instalador. Puede pasar que en el transcurso de la instalación el instalador se quede colgado (En el apartado de «Completando Instalación»), si ese es tu caso, vuelve a grabar la iso de Windows 7 que tengas (si eres estudiante universitario puedes acceder mediante el programa Microsoft Academic Alliance) porque tendrás archivos corruptos.

3. Instalar Windows 8

En la web de Scott Hanselman recomienda instalarlo mediante un pen-drive USB, eso es genial porque ahorras en grabar discos, además es mucho más rápido. Desafortunadamente los mac no permiten arranque desde USB de nada que no sea un disco con una instalación de Mac OSX (http://support.apple.com/kb/HT1948) así que nos tocará grabar la ISO y luego instalarlo a la vieja usanza, la pega en este caso es que perdemos las herramientas de desarrollo, pero todo se puede arreglar.

Antes de reiniciar, crearemos el disco virtual siguiendo los siguientes pasos:

  1. Abrir Panel de Control / Herramientas Administrativas / Administración de Equipos
  2. Desplazarse al apartado Discos
  3. Crear un Nuevo VHD, asignamos una capacidad de 60 GB, con 40 deberían bastar, pero nos aseguramos.

Ahora podremos reiniciar el ordenador, cargar el disco de Windows 8, y comenzar el instalador. (Nota. Es recomendable, o bien tener un teclado externo para los próximos pasos, o bien poner la distribución del teclado en inglés y poner los caracteres especiales a ciegas, ya que en mi caso el instalador no reconocía la tecla correspondiente a \).

Al llegar al apartado de selección de discos pulsamos Shift + F10, lo que nos mostrará una ventana de comandos, y tendremos que montar el disco virtual que hemos creado antes, para poder instalarlo ahí. Los comandos son los siguientes (cuando lo instalas por 5ª vez te los aprendes de memoria, palabra).

  • select vdisk file=»C.\ruta\a\disco»
  • attach vdisk

Si volvemos al instalador, y pulsamos el botón de Actualizar (o click en F5, para el mismo efecto) y nos dejará seleccionar el disco que hemos creado hace un rato, y podremos instalar Windows ahí, y completar la instalación.

4. Instalar los drivers

En este caso es igual que anteriormente, solo que si no nos deja ejecutarlo tendremos que usar compatibilidad con Windows 7. Para ello, click derecho sobre el instalador, pestaña compatibilidad y seleccionamos Windows 7. Tras ejecutar el instalador, tendremos audio, resolución decente, e incluso compatibilidad con el Magic Mouse para el scroll.

5. Instalar Visual Studio 11

En mi caso el instalador web no funcionó, así que recurrí a la versión ISO (disponible aquí: http://www.microsoft.com/download/en/details.aspx?id=27538) para la instalación. Como Windows 8 incorpora gestión de imágenes ISO, podemos montarla directamente sin tener que recurrir a otros programas.

En mi caso la instalación se congeló (literalmente), en varias ocasiones, para lo cual reiniciaba el ordenador, tras lo que la instalación continuaba. Tras 5 o 6 reinicios y varios quebraderos de cabeza, se instaló toda la suite.

Aún faltaba un pequeño detalle, y es que Visual Studio 11, pese a incluir las herramientas para desarrollar aplicaciones Metro, no incluye elementos clave para ejecutarlas. Estos elementos sí que están disponibles en la ISO que incluye las herramientas de desarrollador (que ocupa unos 5 GB y no pude instalar al no contar con DVDs de doble capa).

Por suerte se han publicado los ficheros necesarios en esta web http://weblogs.asp.net/bsimser/archive/2011/09/17/fixing-the-makepri-exe-error-on-windows-8.aspx para que así podamos tener las herramientas para empezar a jugar con Windows 8.

Como última recomendación, si tenéis errores a la hora de ejecutar vuestras aplicaciones, probad a cambiar la resolución un par de veces, y se solucionará.

Fuentes: