Este es el primer artículo de una serie dedicada al desarrollo de aplicaciones para Windows Phone 7 en Silverlight. Como primer ejemplo vamos a crear una aplicación sencilla de representación de datos y la iremos refinando en sucesivos episodios:
- Aplicación base: representación de datos y visionado de vídeos.
- Mejoras visuales y navegación
- Guardar el estado (tombstoning)
- Mejoras de rendimiento
- Interacción con otros servicios
- Preparación para el Marketplace
Veremos lo fácil que nos va a resultar realizar la primera versión mientras que el aspecto de la aplicación va a resultar profesional desde el primer momento. Una característica común de las aplicaciones WP7.
Plantillas de proyecto para WP7
Cuando creamos una aplicación en Silverlight para Windows Phone 7 tenemos varias proyectos base donde elegir:
- Aplicación Windows Phone: nos da una pantalla con un título donde podemos empezar a crear nuestra aplicación desde cero. Aunque sea la primera opción que tenemos es la más cruda de todas, yo recomiendo no empezar por aquí.
- Una aplicación conectada a datos: en este caso nos proporcionan dos pantallas, una principal y otra de detalle. Es conectada a datos al modo de WP7, es decir, no esperéis un sql compact o algo parecido, WP7 está pensado para consumir datos de la nube, así que los datos se obtendrán inicialmente a través de la conexión de red.
- Un Panorama: que nos permite crear una aplicación que ocupa una región más grande que la pantalla con una imagen de fondo común. Es el proyecto más vistoso de todos y el que se suele usar de base para casi todas las aplicaciones básicas del WP7: contactos, imágenes, marketplace, etc….
- Un Pivot: la versión WP7 de lo que sería una página con tabs, se usa por ejemplo para el cliente de correo o para las pantallas de configuración.
La aplicación
La idea es crear una aplicación que nos de una vista de noticias, artículos y vídeos recientes, tal como sería para un canal de noticias cualquiera. Para el ejemplo voy a usar las fuentes RSS que hay en MSDN España y así estaremos al día en últimas tecnologías.
Para ello vamos a crear una aplicación tipo Panorama, pues es la más adecuada ya que nos da un patrón de diferentes vistas conectadas a una fuente de datos. Vamos a empezar creando un nuevo proyecto del tipo "Windows Phone Panorama Application"
La plantilla nos creará un proyecto con datos de ejemplo para que veamos en la lista de diseño cómo quedará la aplicación. El esquema de los datos está definido como la clase ItemViewModel dentro de la carpeta ViewModels y también tenemos el MainViewModel donde tenemos la colección de datos que vamos a mostrar.
Dentro del proyecto que nos crea la plantilla Panorama tenemos ejemplos de cómo representar los datos, la manera más sencilla: una listbox que enlazaremos a la colección de datos que tenemos en el ViewModel.
Para nuestro caso vamos a borrar ItemViewModel generado, pues vamos a crear nuestras propias clases para representar las fuentes RSS y borraremos el contenido de MainViewModel, donde luego escribiremos el código para recuperar los datos. Las fuentes de datos que vamos a utilizar son fuentes disponibles públicamente. Son las mismas que podemos usar desde cualquier lector de feeds o como fuente de datos para nuestros mashups. Para el ejemplo, como ya he dicho antes, usaremos las fuentes de MSDN España, una de vídeos y otras dos de texto:
- El canal de vídeos de MSDN España en Channel 9: http://channel9.msdn.com/Blogs/channel9spain/RSS
- El canal de noticias: http://www.microsoft.com/spain/msdn/rss/noticias.xml
- El canal de artículos: http://www.microsoft.com/spain/msdn/rss/articulos.xml
Para poder utilizar el contenido de las fuentes necesitaremos abrir una conexión web, leer el contenido xml del feed y rellenar una lista que nos sirva de fuente para la Listbox. Vamos allá: Primero crearemos las clases que necesitamos para representar los elementos de la lista:
Código :
public class ElementoEntradaVideo { /// <summary> /// Namespace usado para encontrar el namespace "media:" /// </summary> public static XNamespace Media="http://search.yahoo.com/mrss/"; public string Title { get; set; } public string Video { get; set; } public string Description { get; set; } public string Thumbnail { get; set; } public static List<ElementoEntradaVideo> GetElements(string response) { List<ElementoEntradaVideo> elementos=new List<ElementoEntradaVideo>(); var rssFeed= XElement.Parse(response); var channel=rssFeed.Descendants("channel"); elementos=(from item in channel.Elements("item") select new ElementoEntradaVideo { Title=item.Element("title").Value, Description=item.Element("description").Value, Video=item.Element("enclosure") == null ? null : item.Element("enclosure").Attribute("url").Value, Thumbnail = (from thumb in item.Descendants(Media + "thumbnail") orderby int.Parse(thumb.Attribute("width").Value) select thumb.Attribute("url").Value).FirstOrDefault() }).ToList(); return elementos; } }
El método GetElements interpreta el xml y crea una lista de elementos que usaremos parar rellenar las listas que mantendremos en el MainViewModel.
En el MainViewModel vamos a crear tres coleciones, del tipo ObservableCollection, que contendrán los datos a mostrar:
Código :
public class MainViewModel : ViewModelBase { public const string _spain="http://channel9.msdn.com/Blogs/channel9spain/RSS"; public const string _noticiasLink="http://www.microsoft.com/spain/msdn/rss/noticias.xml"; public const string _articulosLink="http://www.microsoft.com/spain/msdn/rss/articulos.xml"; public MainViewModel() { Videos=new ObservableCollection<ElementoEntradaVideo>(); Noticias=new ObservableCollection<ElementoEntradaRss>(); Articulos=new ObservableCollection<ElementoEntradaRss>(); } public ObservableCollection<ElementoEntradaVideo> Videos { get; private set; } public ObservableCollection<ElementoEntradaRss> Noticias { get; private set; } public ObservableCollection<ElementoEntradaRss> Articulos { get; private set; }
Dentro del MainViewModel abriremos un WebClient para solicitar el contenido de la fuente rss y cuando lo recibamos usaremos el método GetElements para obtener la colección:
Código :
private void fillVideos(string rssUrl) { WebClient client=new WebClient(); client.DownloadStringCompleted += (x, e) => { if (e.Error == null) { List<ElementoEntradaVideo> elements=ElementoEntradaVideo.GetElements(e.Result); elements.ForEach((element) => this.Videos.Add(element)); } }; client.DownloadStringAsync( new Uri(rssUrl)); }
El método DownloadStringAsync ejecuta una llamada asíncrona al servidor de la fuente rss que se vuelve a sincronizar con el UI en el método DownloadStringCompleted. Sobre esta llamada y sobre cómo mejorar el rendimiento cuando hacemos llamadas remotas hablaremos en el capítulo 4 de esta serie.
Para que todo esto funcione debemos cargar los datos desde la vista XAML, así en el codebehind tendremos que llamar al método de carga del MainViewModel:
Código :
// Constructor public MainPage() { InitializeComponent(); // Set the data context of the listbox control to the sample data DataContext=App.ViewModel; this.Loaded += new RoutedEventHandler(MainPage_Loaded); } // Load data for the ViewModel Items private void MainPage_Loaded(object sender, RoutedEventArgs e) { App.ViewModel.LoadData(); }
Diseño del UI
Ahora nos toca ya diseñar el aspecto del interfaz gráfico, lo primero que vamos a hacer es rellenar el fichero de datos de ejemplo para poder ver en el diseñador cómo nos queda.
Código :
<local:MainViewModel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:CanalDeNoticiasMSDN.ViewModels"> <local:MainViewModel.Videos> <local:ElementoEntradaVideo Title="Título 1"/> <local:ElementoEntradaVideo Title="Título 2"/> <local:ElementoEntradaVideo Title="Título 3"/> <local:ElementoEntradaVideo Title="Título 4"/> <local:ElementoEntradaVideo Title="Título 5"/> <local:ElementoEntradaVideo Title="Título 6"/> </local:MainViewModel.Videos> <local:MainViewModel.Noticias> <local:ElementoEntradaRss Guid="1" Title="Título 1" Description="Descripción del título 1" PubDate ="1/1/2010 14:04:05"/> <local:ElementoEntradaRss Guid="2" Title="Título 2" Description="Descripción del título 1" PubDate ="1/1/2010 14:04:05"/> <local:ElementoEntradaRss Guid="3" Title="Título 3" Description="Descripción del título 1" PubDate ="1/1/2010 14:04:05"/> </local:MainViewModel.Noticias> <local:MainViewModel.Articulos> <local:ElementoEntradaRss Guid="1" Title="Título 1" Description="Descripción del título 1" PubDate ="1/1/2010 14:04:05"/> <local:ElementoEntradaRss Guid="2" Title="Título 2" Description="Descripción del título 2" PubDate ="1/1/2010 14:04:05"/> <local:ElementoEntradaRss Guid="3" Title="Título 3" Description="Descripción del título 3" PubDate ="1/1/2010 14:04:05"/> </local:MainViewModel.Articulos> </local:MainViewModel>
Una vez rellenados los datos abrimos MainPage.xaml y creamos el primer PanoramaItem para representar los vídeos:
Código :
<!--Panorama item one--> <controls:PanoramaItem Header="Vídeos"> <ListBox Margin="0,0,-12,0" ItemsSource="{Binding Videos}" SelectionChanged="ListBox_SelectionChanged"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal" Margin="0,0,0,17"> <Image Height="100" Width="100" Source="{Binding Thumbnail}" Margin="12,0,9,0"/> <StackPanel Width="311"> <TextBlock Text="{Binding Title}" TextWrapping="Wrap" Style="{StaticResource PhoneTextTitle3Style}"/> </StackPanel> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </controls:PanoramaItem>
Dentro del PanoramaItem tenemos una ListBox, enlazamos la propiedad ItemSource a la lista llamada Videos que hemos creado antes. Dentro de la listbox modificamos el DataTemplate para poner la imagen y el título y ya tenemos una bonita lista que incluye un fotograma y un título por cada entrada. El control ListBox se encargará de repetir el patrón, hacer scroll de los elementos y de la interacción con el usuario.
Para los artículos y las noticias es bastante parecido.
Código :
<!--Panorama item two--> <controls:PanoramaItem Header="Artículos"> <ListBox Margin="0,0,-12,0" ItemsSource="{Binding Articulos}" SelectionChanged="ListBox_SelectionChanged_1"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Margin="0,0,0,17"> <TextBlock Text="{Binding Title}" TextWrapping="Wrap" Style="{StaticResource PhoneTextTitle2Style}"/> <TextBlock Text="{Binding PubDate}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </controls:PanoramaItem>
Al ejecutar la aplicación ya podremos ver el resultado:
Visualización de los datos
Ahora que la aplicación ya muestra el título de las entradas e incluso las imágenes ¿Cómo vemos el contenido al que apuntan? La respuesta está en las tareas de WP7, que nos permiten lanzar aplicaciones tales como el navegador o el reproductor de vídeo. Para ello añadimos primero un manejador de evento al SelectionChanged de la listbox:
Código :
<ListBox Margin="0,0,-12,0" ItemsSource="{Binding Videos}" SelectionChanged="ListBox_SelectionChanged">
Y ahora en el manejador lanzamos la tarea de vídeo con los datos que tenemos del elemento seleccionado:
Código :
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (e.AddedItems.Count > 0) { ElementoEntradaVideo element=e.AddedItems[0] as ElementoEntradaVideo; if (element != null) { new MediaPlayerLauncher { Media=new Uri(element.Video), Controls=MediaPlaybackControls.All }.Show(); } } }
Así al pulsar sobre un elemento ya podremos ver el vídeo. Para el caso de los artículos y noticias vamos a lanzar el navegador con una dirección url:
Código :
private void ListBox_SelectionChanged_1(object sender, SelectionChangedEventArgs e) { if (e.AddedItems.Count > 0) { ElementoEntradaRss element=e.AddedItems[0] as ElementoEntradaRss; if (element != null) { new WebBrowserTask { URL=element.Link }.Show(); } } }
En unas pocas líneas hemos creado una aplicación completamente funcional.
Descarga el código de ejemplo
Conclusiones
En este primer tutorial hemos aprendido cómo empezar una aplicación para WP7 usando el control Panorama, nos hemos introducido en el patrón MVVM que suelen usar las aplicaciones de datos en Silverlight, hemos consumido datos de fuentes rss y hemos abierto vídeos y enlaces usando las tareas de Windows Phone. En el próximo capítulo vamos a empezar a refinar la aplicación: cambiaremos el aspecto visual de la aplicación y añadiremos alguna vista más aparte de la principal para mejorar la experiencia de usuario.
¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.
Por jmservera el 14 de Enero de 2011
Por HernanDroid el 15 de Enero de 2011
Aunque bueno, yo apenas empecé a profundizar la web hace 45 días y si se manejar algo de HTML básico y la plataforma WordPress
De todas maneras ya quisiera empezar a estudiar lo que quiero
Por jmservera el 16 de Enero de 2011
La programación para Windows Phone 7 sobre la que trata el artículo poco tiene que ver con HTML, se usan Silverlight y C# como lenguajes y Visual Studio como entorno de programación. Si necesitas algún tip sobre el tema te puedo pasar unos cuantos enlaces para empezar.
Por lucasmoyano el 17 de Enero de 2011
Por jonathan el 18 de Enero de 2011
Por jonathan el 18 de Enero de 2011
Por jmservera el 18 de Enero de 2011
Si no os funciona podéis descargar el código de codeplex en: http://ejemploswp7silver.codeplex.com/SourceControl/list/changesets
Por Pablo el 29 de Enero de 2011
Por jmservera el 02 de Febrero de 2011
Pablo-blog :
Um! Buena pregunta Pablo.
Pues siento decirte que ni iso-8859-1 ni su equivalente windows-1252 estan soportados en windows phone, puedes mirar en msdn los códigos soportados, que básicamente son las distintas versiones de unicode.
Por Pau el 10 de Febrero de 2011
Por Eduardo el 20 de Marzo de 2011
Me gustaría desarrolar una aplicación para windows phone 7 que capture voz o audio desde el teléfono para luego enviarlo por la red a un servicio web.
¿Me puedes orientar?
Por jmservera el 21 de Marzo de 2011
Si queréis un tutorial más claro y en castellano puedo escribir algo sobre uso de las clases de XNA desde silverlight.
Por martip07 el 13 de Mayo de 2011
estoy cambiando los urls por los de mi blog (http://www.tgameblog.tk) y en lo que va en noticias y articulos va todo genial.
pero enla parte de videos quisera cambiar eso apra poner poner mi canal de youtube:
http://www.youtube.com/user/martip07?feature=mhee
como podria ahcer eso ya que eso tendria que ser un mediaRSS y ya no un RSS normal.
Resumen:
cambiar la seccionde videos por mi canal de youtube.
gracias...!!!!
Por jmservera el 16 de Mayo de 2011
Para poder ver vídeos de youtube hay que hacerlo de otra manera:
1. Usar el api gdata de youtube para listar los vídeos de tu canal
2. Los vídeos no se abren con el MediaPlayerLauncher sino con el WebBrowser con una url del estilo
vnd.youtube:xCnV4B70xJ4
donde lo que va detrás de los dos puntos es el ID del vídeo.
3. Hay que tener instalada la app de youtube, si no la tienes el webbrowser te redirige.
Si hay más gente interesada puedo hacer un tutorial
Un saludo,
Juanma
Por juan santana el 21 de Mayo de 2011
Pero como puedo lanzar los videos si los tengo residentes en un stackpanel de la propia aplicacion , porque son media element y tengo que instalar reproductor y quisiera saber como puedo lanzarlos desde el stackpanel.
Por gisela el 15 de Julio de 2011
Por Jean el 24 de Agosto de 2011
Me podrias recomendar algun tutorial en español sobre estos 2 lenguajes? ... Ahora que estoy de vacaciones quiero aprender, como cuanto crees que podria tardar en manejar lo basico de estos lenguajes, de manera que pueda desarrollar alguna aplicacion parecida a esta?
Gracias!
Por Wooper el 25 de Agosto de 2011
Por jmservera el 25 de Agosto de 2011
También te recomiendo en castellano el blog de Josué Yeray: (http://geeks.ms/blogs/jyeray)
Por jmservera el 25 de Agosto de 2011
También tiene uno de Windows Phone, donde explica los conceptos básicos de Silverlight.
Un saludo,
-Juanma
Por gold_lider1 el 23 de Noviembre de 2011
Tenes algun ejemplo en donde algun dato desde la aplicación Windows phone me lo vuelque sobre una base datos en squl server 2008?
Por Jesus Flores el 16 de Diciembre de 2011
Por qjuanp el 21 de Enero de 2012
Por qjuanp el 21 de Enero de 2012
Si los datos los vas a manejar desde diferentes dispositivos puedes exponerlos desde un servicio web.
Por JuanZ el 11 de Mayo de 2012
Por Orlando Gutierrez el 31 de Octubre de 2012
Por ivan el 09 de Marzo de 2013
mi correo es [email protected]
Por williams el 01 de Abril de 2013
Por Sebastián el 07 de Septiembre de 2013