20
Vicente G. Guzmán Lucio Desarrollador .NET Desarrollando mi primera App para Windows 8 con C# “Medir el progreso del desarrollo de software por líneas de código es como medir el progreso de la construcción de un avión por su peso" -- Bill Gates El siguiente material se creó con la finalidad de enseñar a desarrollar una aplicación desde 0 para el nuevo sistema operativo de Microsoft: Windows 8. Antes de empezar se debe dejar bien claro que NO se pueden crear Apps para Windows 8 si no se cuenta con este SO instalado en la máquina, además se debe de contar previamente con: Visual Studio 2012 Una vez teniendo todo instalado, procedemos a generar un nuevo Proyecto, tal y como se muestra en la siguiente imagen:

Desarrollando mi primera App para Windows 8 con C#

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

Desarrollando mi primera App para

Windows 8 con C#

“Medir el progreso del desarrollo de software por líneas de código es como medir el progreso de

la construcción de un avión por su peso"

-- Bill Gates

El siguiente material se creó con la finalidad de enseñar a desarrollar una aplicación desde 0 para

el nuevo sistema operativo de Microsoft: Windows 8.

Antes de empezar se debe dejar bien claro que NO se pueden crear Apps para Windows 8 si no se

cuenta con este SO instalado en la máquina, además se debe de contar previamente con:

Visual Studio 2012

Una vez teniendo todo instalado, procedemos a generar un nuevo Proyecto, tal y como se muestra

en la siguiente imagen:

Page 2: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

Nos desplegara la siguiente imagen, en donde nos mostrara un listado de

tipos de plantillas que tenemos para seleccionar, para este Demo elegiremos la que se llama

“Aplicación de cuadricula (XAML)”, le proporcionaremos un nombre y proporcionaremos la ruta

en donde se guardara.

Aplicación de Cuadricula (XAML)

Proyecto de tres páginas de la Tienda Windows que navega entre elementos agrupaos organizados

en una cuadricula. Las páginas dedicadas muestran detalles del grupo y de los elementos.

Si quieres conocer los distintos tipos de plantillas entra al siguiente enlace:

Plantillas de proyecto C#, VB y C++ para aplicaciones de la Tienda Windows

Page 3: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

Una vez que le demos al botón de Aceptar tendremos una pantalla similar a

esta:

Antes de comenzar a aventar código, identifiquemos las partes más importantes de nuestro

ambiente de trabajo para familiarizarnos.

Page 4: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

Compilación

Para poder ejecutar nuestro proyecto tenemos primero que compilarlo, esto se puede de realizar

de distintas formas.

En nuestra barra de controles accedemos a “Compilar” y enseguida aparecerá la opción de

“Compilar Solución”, de igual forma nos muestra la forma de hacerlo presionando al mismo

tiempo la combinación de teclas: Ctrl + Mayus + B, aunque en algunas máquinas no puede

funcionar esta combinación, les sugiero intenten Ctrl + Shift + B.

Cabe destacar que conforme vayamos creando o editando algunas partes, estas no se “empatan”

con la solución, para esto también contamos con la opción de “Limpiar Solución”.

En mi experiencia siempre limpio y compilo antes de ejecutar la aplicación.

Después de haber realizado lo anterior, en la parte superior un botón de “play” el cual nos marca

por default “Equipo Local”, esto significa que la aplicación se ejecutara en nuestra máquina.

Nota// Se necesita tener Windows 8, en caso contrario, teniendo esta opción activa no funcionara.

Además de poder ejecutar la App de manera local, el SDK de Visual Studio

nos brinda la opción de compilar en un Simulador o en un Equipo remoto.

Estas dos últimas opciones las conoceremos en el siguiente tutorial.

Page 5: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

También debemos de conocer la diferencia entre las modalidades de

compilación, las cuales son solo dos: Debug & Release

Debug: esta versión del programa se compila sin optimizar y con toda la información de

depuración simbólica. La optimización complica la depuración, ya que la relación entre el código

fuente y las instrucciones generadas es más compleja.

Release: esta versión del programa no contiene información de depuración simbólica y está

totalmente optimizada. La información de depuración se puede generar en Archivos PDB (C++),

según las opciones del compilador utilizadas. Crear archivos PDB puede ser muy útil si luego

necesita depurar la versión de lanzamiento.

En otras palabras la versión de depuración se genera para la depuración y la versión de

lanzamiento para la distribución final de lanzamiento.

Explorador de Soluciones

En el explorador de soluciones es donde se

encuentra todo lo relacionado a nuestro proyecto,

desde las Referencias, Imágenes y clases.

Aquí podemos ver desde la vista diseño y el código

de cada página o elemento.

GroupedItemsPage.xaml (Design)

GroupedItemsPage.xaml.cs (Code)

Page 6: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

Abramos la página de GroupedItemsPage, la cual es la principal de nuestro proyecto.

Ahora compilemos nuestro proyecto para poder ver como se encuentra actualmente y comprobar

que no existe ningún error.

En este tutorial veremos cómo crear una App que consume un Feed, y para este demo

utilizaremos el de este portal:

http://geeks.ms/blogs/MainFeed.aspx

Nota//

Para que tu App sea una que se mantenga sola debes de ver que el sitio que quieras utilizar

muestre la siguiente información:

Está viendo una fuente cuyo contenido se actualiza con frecuencia. Las fuentes se agregan a la lista

de fuentes comunes cada vez que se suscribe a ellas. La información actualizada en la fuente se

descarga automáticamente en el equipo y se podrá consultar en Internet Explorer y en otros

programas.

Page 7: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

Lo primero que editaremos será el archivo de la página

“GroupedItemsPage.xaml.cs”, en el método LoadState.

Antes:

Lo que haremos será decirle al método de carga que añada y muestre todos los elementos que se puedan extraer del elemento que se encuentra en el “SampleDataSource”, en este caso será AllGroups. Despues:

protected override async void LoadState (Object navigationParameter, Dictionary<String, Object> pageState) { this.DefaultViewModel["Groups"] = SampleDataSource.AllGroups; await SampleDataSource.AddGroupForFeedAsync("http://geeks.ms/blogs/MainFeed.aspx"); }

SampleDataSource: Crea una colección de grupos y elementos con contenido codificado de forma rígida. SampleDataSource se inicializa con datos marcadores de posición en lugar de con datos de producción activos, por lo que se proporcionan datos de muestra tanto en el momento del diseño como en el de la ejecución.

Ahora abriremos el elemento “SampleDataSource.cs” que se encuentra en la carpeta DataModel.

Page 8: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

Referencias faltantes. Las referencias son muy importantes a la hora de la creación de algunos métodos y eventos, es por eso que se deben de agregar si se conocen, en caso contrario se pueden añadir después. Las que ya se encuentran importadas en nuestro archivo son las siguientes: using System; using System.Linq; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; using Windows.ApplicationModel.Resources.Core; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media.Imaging; using System.Collections.Specialized;

Y las que añadiremos serán las siguientes: using System.IO; using System.Text.RegularExpressions; Cuando nos haga falta alguna referencia, al momento de compilar el mismo Visual Studio nos indica cual es la que no se encuentra. Por ejemplo:

Solo es cuestión de dar doble click al error y este nos llevara a la línea exacta en el código. Para poder solucionarlo, solo es de posicionar el cursor en la palabra “Task” y cuando nos aparezca un cuadrito seleccionamos la primera opción: using.System.Threading.Tasks;

Page 9: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

Para resolver el segundo error, repetimos el mismo procedimiento, solo que aquí la referencia que nos hace falta es la de: using Windows.Web.Syndication;

Y así luce nuestro archivo con todas las referencias:

Page 10: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

Busquemos la clase sellada SampleDataSource, veremos que contiene una instancia de la misma. public sealed class SampleDataSource { private static SampleDataSource _sampleDataSource = new SampleDataSource();

Lo que haremos ahora será agregar una colección de objetos SampleDataGroup arriba de la instancia a la que llamaremos AllGroups, la cual ocuparemos más adelante. public static readonly ObservableCollection<SampleDataGroup> AllGroups = new ObservableCollection<SampleDataGroup>();

Las lineas siguientes: private ObservableCollection<SampleDataGroup> _allGroups = new ObservableCollection<SampleDataGroup>(); public ObservableCollection<SampleDataGroup> AllGroups { get { return this._allGroups; } } public static IEnumerable<SampleDataGroup> GetGroups(string uniqueId) { if (!uniqueId.Equals("AllGroups")) throw new ArgumentException("Only 'AllGroups' is supported as a collection of groups"); return _sampleDataSource.AllGroups; }

Las eliminamos, ya que no las utilizaremos. Y en las métodos de GetGroup y GetItem lo único que haremos será idenficar “_sampleDataSource” y lo borramos, para dejar la validación de AllGroups.

Page 11: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

Así nos debe de quedar hasta el momento:

Ahora si observamos la clase publica de SampleDataSource contiene 6 grupos de ítems ya definidos por la aplicación, lo que haremos ahora sería cargar los ítems propios de la página que vamos a leer, en este caso el del Feed, para ello vamos a limpiar el método “SampleDataSource”, en otras palabras eliminar todo su contenido. Antes:

Page 12: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

Después: public SampleDataSource() { }

Para llenar el SampleDataSource vamos a crear un método asíncrono que permita obtener los ítems de la URL, el cual se llamara “AddGroupForFeedAsync”, cuyo parámetro de entrada será la cadena de la URL a leer. Para los que no sepan que es un método asíncrono, este funciona de modo que se obtienen los datos en una consulta y se refrescan hasta que se genera una nueva. public static async Task<bool> AddGroupForFeedAsync(string feedUrl) { }

Dentro de este método evaluaremos si es posible obtener el grupo de ítems de nuestra URL, en caso correcto se crearan 2 variables: feed y feedGroup. if (SampleDataSource.GetGroup(feedUrl) != null) return false; var feed = var feedGroup =

La variable feed inicializara un objeto del tipo SyndicationClient para obtener los ítems de la URL. Y la variable feedGroup inicializara un SampleDataGroup que valida los campos de título, subtitulo e imagen. var feed = await new SyndicationClient().RetrieveFeedAsync(new Uri(feedUrl)); var feedGroup = new SampleDataGroup(uniqueId: feedUrl, title: feed.Title != null ? feed.Title.Text : null, subtitle: feed.Subtitle != null ? feed.Subtitle.Text : null, imagePath: feed.ImageUri != null ? feed.ImageUri.ToString(): "/Assets/Logito.jpg", description: null);

En el campo de imagePath realizamos una simple validación en donde si la nota creada no tiene imagen o no puede ser mostrada (esto puede ser afectado por su formato o resolución) mostraremos una local. Hecho esto recorreremos los ítems de nuestra variable feed para cargar los elementos. foreach (var i in feed.Items) { }

Para esto manipularemos la cadena denominada imagePath, la cual es igual al método GetImageFromPostContents que crearemos más adelante. string imagePath = GetImageFromPostContents(i);

Page 13: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

A continuación validaremos el valor de la cadena, en donde si es igual a nulo y el elemento de imagen del grupo también, mostremos una imagen definida por nosotros, esto para que no quede vacío a la hora de ejecución. if (imagePath == null && feedGroup.Image != null) imagePath = "/Assets/Logito.jpg";

Después los asignaremos a nuestro feedGroup. feedGroup.Items.Add(new SampleDataItem( uniqueId: i.Id, title: i.Title.Text, subtitle: null, imagePath: imagePath, description: null, content: Windows.Data.Html.HtmlUtilities.ConvertToText(i.Summary.Text), @group: feedGroup));

Ahora se procede a cargar el feedGroup creado en la vista de la aplicación, el cual es AllGroups. AllGroups.Add(feedGroup); return true; Ya para culminar crearemos un método en el cual obtendremos el formato de las imagenes que contiene el Feed, y también limpiaremos el contenido (caracteres Unicode) que nos arroje el texto del mismo.

private static string GetImageFromPostContents(SyndicationItem item) { return Regex.Matches(item.Summary.Text, "href\\s*=\\s*(?:\"(?<1>[^\"]*)\"|(?<1>\\S+))", RegexOptions.None) .Cast<Match>() .Where(m => { Uri url; if (Uri.TryCreate(m.Groups[1].Value, UriKind.Absolute, out url)) { string ext = Path.GetExtension(url.AbsolutePath).ToLower(); if (ext == ".png" || ext == ".jpg") return true; } return false; }) .Select(m => m.Groups[1].Value) .FirstOrDefault(); } }

}

Page 14: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

Añadiendo la imagen faltante. La ruta que indicamos anteriormente proviene de la carpeta Assets, dentro de esta se encontrara la imagen que definimos previamente. Para agregar susodicha imagen (Logito.jpg) solo hagamos click derecho sobre la carpeta Assets y seleccionemos la opción: Agregar: Elemento existente.

Seleccionamos la imagen y damos en Aceptar.

Nota//La imagen debe de contar con las siguientes medidas: Logito.jpg = 150x150 px.

Page 15: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

Limpiemos y compilemos para comprobar que no tengamos ningún otro error. Si no aparece ninguno, solo apretemos F5 y veamos el resultado.

Ya para que luzca un poco mejor cambiemos el nombre que aparece de “App1” por el de “Noticias Geeks”, vayamos al archivo App.xaml y localicemos la etiqueta que lo contiene.

Page 16: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

Ctrl + Shift + B y después F5 para poder ver reflejado el cambio.

Si se selecciona cualquier noticia, así es como se muestra la descripción de la misma.

Page 17: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

Ya con esto hemos terminado el desarrollo de nuestra primera aplicación para Windows 8, ahora lo que solo nos queda por realizar es darle un buen diseño, agregarle la barra de Charms en donde se exprese quien la desarrollo e información de contacto, la cual va dentro del “Acerca de” y estará listo para publicarse en la Store. Para poder realizar esto último y si son estudiantes favor de mandar un correo a: [email protected] Comentando que asistieron al taller realizado en Campus Party y que les gustaría poder publicar su aplicación, el equipo les asignara un código. Cabe destacar que la continuidad de este material se publicara en el blog:

www.luciomsp.wordpress.com Así que si gustan poder estar al tanto, solo suscríbanse y automáticamente les llegara a su correo la publicación del mismo.

Page 18: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

Bloque de Código Completo (/DataModel/SampleDataSource.cs) /// <summary> /// Crea una colección de grupos y elementos con contenido codificado de forma rígida. /// /// SampleDataSource se inicializa con datos de marcadores de posición en lugar de con datos de producción /// activos, por lo que se proporcionan datos de muestra tanto en el momento del diseño como en el de la ejecución. /// </summary> public sealed class SampleDataSource { public static readonly ObservableCollection<SampleDataGroup> AllGroups = new ObservableCollection<SampleDataGroup>(); private static SampleDataSource _sampleDataSource = new SampleDataSource(); public static SampleDataGroup GetGroup(string uniqueId) { // La búsqueda lineal sencilla es aceptable para conjuntos de datos reducidos var matches = AllGroups.Where((group) => group.UniqueId.Equals(uniqueId)); if (matches.Count() == 1) return matches.First(); return null; } public static SampleDataItem GetItem(string uniqueId) { // La búsqueda lineal sencilla es aceptable para conjuntos de datos reducidos

var matches = AllGroups.SelectMany(group => group.Items).Where((item) => item.UniqueId.Equals(uniqueId));

if (matches.Count() == 1) return matches.First(); return null; } public SampleDataSource() { } public static async Task<bool> AddGroupForFeedAsync(string feedUrl) { if (SampleDataSource.GetGroup(feedUrl) != null) return false;

var feed = await new SyndicationClient().RetrieveFeedAsync(new Uri(feedUrl)); var feedGroup = new SampleDataGroup( uniqueId: feedUrl, title: feed.Title != null ? feed.Title.Text : null, subtitle: feed.Subtitle != null ? feed.Subtitle.Text : null, imagePath: feed.ImageUri != null ? feed.ImageUri.ToString() : "/Assets/Logito.jpg", description: null);

Page 19: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

foreach (var i in feed.Items) { string imagePath = GetImageFromPostContents(i); if (imagePath == null && feedGroup.Image != null) imagePath = "/Assets/Logito.jpg"; feedGroup.Items.Add(new SampleDataItem( uniqueId: i.Id, title: i.Title.Text, subtitle: null, imagePath: imagePath, description: null, content: Windows.Data.Html.HtmlUtilities.ConvertToText(i.Summary.Text), @group: feedGroup)); } AllGroups.Add(feedGroup); return true; } private static string GetImageFromPostContents(SyndicationItem item) { return Regex.Matches(item.Summary.Text, "href\\s*=\\s*(?:\"(?<1>[^\"]*)\"|(?<1>\\S+))", RegexOptions.None) .Cast<Match>() .Where(m => { Uri url; if (Uri.TryCreate(m.Groups[1].Value, UriKind.Absolute, out url)) { string ext = Path.GetExtension(url.AbsolutePath).ToLower(); if (ext == ".png" || ext == ".jpg") return true; } return false; }) .Select(m => m.Groups[1].Value) .FirstOrDefault(); } } }

Page 20: Desarrollando mi primera App para Windows 8 con C#

Vicente G. Guzmán Lucio Desarrollador .NET

@LucioMSP

[email protected]

¿Preguntas?