<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>La Liga SilverlightTutoriales | La Liga Silverlight</title>
	<atom:link href="http://blogs.ligasilverlight.com/category/tutorial/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.ligasilverlight.com</link>
	<description>La primera Comunidad en Español acerca de Silverlight y tecnologías relacionadas</description>
	<lastBuildDate>Tue, 17 Jan 2012 16:43:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Desplegando un ChildWindow en objetos Window en Silverlight 5</title>
		<link>http://blogs.ligasilverlight.com/2012/01/desplegando-un-childwindow-en-objetos-window-en-silverlight-5/</link>
		<comments>http://blogs.ligasilverlight.com/2012/01/desplegando-un-childwindow-en-objetos-window-en-silverlight-5/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 16:33:41 +0000</pubDate>
		<dc:creator>Rodrigo Díaz Concha</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[silverlight 5]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/?p=3620</guid>
		<description><![CDATA[Silverlight 5 cuenta con muchas características enfocadas principalmente a la construcción de aplicaciones de negocio, una de ellas es la creación de Ventanas de Sistema. Sin embargo, si necesitas mostrar un ChildWindow dentro de una ventana creada dinámicamente, el comportamiento que obtendrás tal vez no es el esperado, y es que el ChildWindow se mostrará en la raíz de la aplicación (comunmente MainPage) y no en la ventana nueva en donde estás ejecutando el código. Por ejemplo, en la siguiente figura la aplicación crea la ventana de la izquierda… …pero al crear el objeto ChildWindow dentro de la ventana en donde esperas que se despliegue: Este comportamiento no es el esperado ¿cierto? En este artículo explicaré cómo puedes obligar que el ChildWindow se dibuje adecuadamente en la ventana que le corresponda. Puedes leer el artículo completo aquí]]></description>
			<content:encoded><![CDATA[<p><a href="http://silverlight.net" target="_blank">Silverlight 5</a> cuenta con <a href="http://rdiazconcha.com/2011/12/silverlight-5-ya-disponible/" target="_blank">muchas características</a> enfocadas principalmente a la construcción de aplicaciones de negocio, una de ellas es la creación de Ventanas de Sistema.</p>
<p>Sin embargo, si necesitas mostrar un ChildWindow dentro de una ventana creada dinámicamente, el comportamiento que obtendrás tal vez no es el esperado, y es que el ChildWindow se mostrará en la raíz de la aplicación (comunmente MainPage) y no en la ventana nueva en donde estás ejecutando el código.</p>
<p>Por ejemplo, en la siguiente figura la aplicación crea la ventana de la izquierda…</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2012/01/SNAGHTML33a0cdc.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="SNAGHTML33a0cdc" border="0" alt="SNAGHTML33a0cdc" src="http://blogs.ligasilverlight.com/wp-content/uploads/2012/01/SNAGHTML33a0cdc_thumb.png" width="500" height="284"/></a></p>
<p>…pero al crear el objeto ChildWindow dentro de la ventana en donde esperas que se despliegue:</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2012/01/SNAGHTML3416af3.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="SNAGHTML3416af3" border="0" alt="SNAGHTML3416af3" src="http://blogs.ligasilverlight.com/wp-content/uploads/2012/01/SNAGHTML3416af3_thumb.png" width="500" height="286"/></a></p>
<p>Este comportamiento no es el esperado ¿cierto?</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2012/01/image.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.ligasilverlight.com/wp-content/uploads/2012/01/image_thumb.png" width="240" height="173"/></a></p>
<p>En este artículo explicaré cómo puedes obligar que el ChildWindow se dibuje adecuadamente en la ventana que le corresponda.</p>
<h2><a href="http://rdiazconcha.com/2012/01/desplegando-un-childwindow-en-objetos-window-en-silverlight-5/" target="_blank">Puedes leer el artículo completo aquí</a></h2>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2012/01/desplegando-un-childwindow-en-objetos-window-en-silverlight-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 31: Promoviendo tu aplicaci&#243;n</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-31-promoviendo-tu-aplicacin/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-31-promoviendo-tu-aplicacin/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 18:05:16 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/?p=3539</guid>
		<description><![CDATA[Esta es una traducción de Day 31: Promoting Your App, puedes encontrar el artículo aquí en su versión original en inglés. Hacer que los usuarios encuentren tu aplicación puede parecer como algo que está fuera de tus manos, pero estás equivocado. Hay muchas cosas que puedes hacer para manejar la atención hacia tu aplicación. Esta sección se enfoca en algunas de las mejores prácticas que deberías utilizar para cada aplicación que crees. La primera semana es vital A menos de que tu aplicación se convierta en una gran sensación, es altamente posible que la primer semana de tu aplicación en el marketplace será en donde veas el más alto número de descargas diarias. Obtener exposición en la categoría “Nuevo” es una oportunidad muy buena y necesitas asegurarte de que estás manejando esto en una forma que hará a tu aplicación brillar por mucho mas que solo unos días. Al final, tu meta es catapultarla desde la categoría Nuevo a la categoría Top Apps. Los cuatro o cinco días que tienes que esperar para que tu aplicación sea aprobada podrían ser aprovechados para ejecutar una estrategia para hacer pública la expectativa de tu aplicación. Enlazar a tu aplicación Cuando ingresas tu [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/12/01/31-days-of-mango-day-31-promoting-your-app/">Esta es una traducción de Day 31: Promoting Your App, puedes encontrar el artículo aquí en su versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia31.png"><img style="padding-left: 0px; padding-right: 0px; padding-top: 0px; border: 0px;" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia31_thumb.png" alt="dia31" width="600" height="75" border="0" /></a></p>
<p>Hacer que los usuarios encuentren tu aplicación puede parecer como algo que está fuera de tus manos, pero estás equivocado. Hay muchas cosas que puedes hacer para manejar la atención hacia tu aplicación. Esta sección se enfoca en algunas de las mejores prácticas que deberías utilizar para cada aplicación que crees.</p>
<p><strong><span style="font-size: large;">La primera semana es vital</span></strong></p>
<p>A menos de que tu aplicación se convierta en una gran sensación, es altamente posible que la primer semana de tu aplicación en el marketplace será en donde veas el más alto número de descargas diarias. Obtener exposición en la categoría “Nuevo” es una oportunidad muy buena y necesitas asegurarte de que estás manejando esto en una forma que hará a tu aplicación brillar por mucho mas que solo unos días. Al final, tu meta es catapultarla desde la categoría Nuevo a la categoría Top Apps. Los cuatro o cinco días que tienes que esperar para que tu aplicación sea aprobada podrían ser aprovechados para ejecutar una estrategia para hacer pública la expectativa de tu aplicación.</p>
<p><strong><span style="font-size: large;">Enlazar a tu aplicación</span></strong></p>
<p>Cuando ingresas tu aplicación por primera vez en el Marketplace, incluso antes de que la aplicación sea aprobada, tienes ya asignado un “deep link” que puedes usar para dirigir a las personas hacia tu aplicación usando una dirección web ordinaria. Aquí está el ejemplo del enlace a una de mis aplicaciones, MathMaster:</p>
<p><a title="http://www.windowsphone.com/es-MX/apps/f08521cd-1cff-df11-9264-00237de2db9e" href="http://www.windowsphone.com/es-MX/apps/f08521cd-1cff-df11-9264-00237de2db9e">http://www.windowsphone.com/es-MX/apps/f08521cd-1cff-df11-9264-00237de2db9e</a></p>
<p>Este enlace te lleva a una página que intentará abrir Zune en la máquina del usuario, y después redireccionarlo a la página de tu aplicación en el Marketplace. Este enlace no funcionará a menos que tu aplicación haya sido aprobada. Recomendamos usar este link cada vez que puedas, especialmente en el sitio personalizado que creaste para tus aplicaciones. Estás planeando hacer eso ¿No es así?</p>
<p><strong><span style="font-size: large;">Crear un portal web para tus aplicaciones</span></strong></p>
<p>Una cosa importante que deberías haber aprendido al pasear por el Marketplace en el <a href="http://www.jeffblankenburg.com/2010/10/27/31-days-of-windows-phone-day-27-windows-phone-marketplace/">Día 27 de la serie original de Windows Phone</a> fue que tu habilidad para discutir acerca de tus aplicaciones en el Marketplace es muy limitada. Unos cuantos pantallazos y aproximadamente 2,000 caracteres es todo lo que tienes. Al crear un sitio web para tus aplicaciones, creas muchas nuevas oportunidades para ti mismo.</p>
<p>1. Puedes crear conexiones reales con tus usuarios. El Marketplace de Windows Phone no te da ninguna indicación de quienes son tus usuarios. Un sitio web te permite interactuar con tus fans.</p>
<p>2. Puedes dar un monto de información muy enriquecido acerca de tu aplicación, incluyendo videos y otro contenido promocional que pueda hacer a tu aplicación mas atractiva.</p>
<p>3. Puedes relacionar a tus aplicaciones. El Marketplace no siempre hace un gran trabajo al promocionar tus otras aplicaciones a clientes potenciales, así que has que tu sitio web permita que eso suceda.</p>
<p>4. Tu aplicación ahora es detectable por gente que ni siquiera esta buscando activamente en el Marketplace.</p>
<p>5. Este sitio web no tiene que ser exactamente un sitio web por completo. No hay nada malo con crear una página en Facebook o cualquier otra red social que puedas personalizar. La idea final de este proceso es proveer un destino para tus fans, así ellos pueden pasar la voz acerca de tu genial aplicación.</p>
<p>Si quieres ver una plantilla genial para crear una página personalizada para tu aplicación, <a href="http://wp7appsite.codeplex.com/">checa esta plantilla de Windows Phone en CodePlex</a>. Es una página personalizable que se ve genial, usa pantallazos de tu aplicación, permite a tus usuarios dar comentarios y les da muchas formas de aprender mucho mas de tu aplicación. Aquí hay un pantallazo de la plantilla.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image28.png"><img style="padding-left: 0px; padding-right: 0px; padding-top: 0px; border: 0px;" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image28_thumb.png" alt="image28" width="468" height="400" border="0" /></a></p>
<p><strong><span style="font-size: large;">Crear un video de guía para tu aplicación</span></strong></p>
<p>Uno de los elementos importantes de tu sitio web debe ser incluir un video guía de tu aplicación. Las capturas de pantalla en el Marketplace son buenas, pero permitirle al usuario ver la experiencia total en una forma controlada nos dará siempre mucha mas información. Nuestra recomendación es utilizar un programa de captura de pantallas como TechSmith’s Camtasia. Camtasia hace muy fácil no solo capturar video desde el emulador, sino editar los resultados, agregar música de fondo y colocar información de introducción antes y después del video. Hay probablemente bastantes herramientas que harán esto por ti, pero en nuestra experiencia, Camtasia es la herramienta perfecta para el trabajo. Puedes ver un ejemplo de mi aplicación de MathMaster en YouTube aquí.</p>
<p><a href="http://youtu.be/uMlyUn3sgJU">Puedes ver el video aquí.</a></p>
<p>Diviértete haciéndolo. En tu video puedes agregar un mayor nivel de interés a tu aplicación que las capturas de pantalla nunca podrán. Ahora que nos hemos enfocado en sitios web y videos, vamos a discutir cosas que puedes hacer dentro de tu aplicación para ayudar a promoverla.</p>
<p><strong><span style="font-size: large;">Generar opiniones de tu aplicación</span></strong></p>
<p>Las opiniones pueden ser un factor decisivo entre si tu aplicación tiene o no las descargas que estás buscando. Desafortunadamente, no hay un mecanismo para recordarle a los usuarios que comenten tu aplicación. Necesitas hacer esto por ti mismo. Recomendamos hacerlo como una adición agradable en tu aplicación en lugar de hacerlo una molestia para tu usuario.</p>
<p>Una idea que recomendamos es hacer un logro dentro de tu aplicación. Un poco de diversión sorprenderá y enganchará al usuario. Dale puntos por leer los créditos de la aplicación. Dale mas por usarla mas de 10 veces. Agregar logros a cualquier aplicación, encontrarás que tus usuarios estarán regresando mas y mas a ella. Quizá también desbloquees una pieza específica de funcionalidad que de otra manera no estaría disponible cuando opinen en tu aplicación.</p>
<p>Una segunda idea es contar el número de veces que tu usuario ha lanzado tu aplicación y pídele en la segunda, quinta y décima ocasión que opine tu aplicación. Pídelo gentilmente. No querrás molestarlo, pero si quieres su opinión. Puedes incluso usar la <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.marketplacereviewtask%28v=VS.92%29.aspx">MarketplaceReviewTask</a> para llevarlos directamente a la página de opiniones de tu aplicación.</p>
<p>Grandes opiniones generan mas tráfico. Comúnmente, una opinión de una estrella puede ser tan valiosa como una escrita. El promedio de evaluación (1-5) es desplegada donde quiera que este tu aplicación, así un alto rango comúnmente genera mas tráfico. Hacer que tus usuarios dejen una opinión tendrá un efecto positivo en los rangos de descarga de tu aplicación.</p>
<p><strong><span style="font-size: large;">Cruzar tus aplicaciones entre ellas</span></strong></p>
<p>Dentro de tu aplicación, puedes dar un lugar donde el usuario puede encontrar información acerca de tu compañía, contactos de soporte y otra información como el número de la versión. En este lugar, o ciertamente en una ubicación mas prominente, tienes una oportunidad para promover las otras aplicaciones que has creado. Usa tus íconos.  Usa los deep links o el lanzador MarketplaceDetailTask. Da una forma sencilla para tu usuario para encontrar y descargar las ofertas que tienes de tus otras aplicaciones.</p>
<p>Si realmente te quieres poner imaginativo, crea un archivo XML en tu servidor web que contenga toda la información acerca de tus aplicaciones y consúmelo en tus aplicaciones para crear la lista de todas tus aplicaciones. De esta forma, cuando agregues una nueva aplicación a tu catálogo, no tendrás que actualizar todas tus aplicaciones, solo hacer esta promoción “cruzada”.</p>
<p>En resumen</p>
<p>Hay muchísimas cosas que necesitas hacer para tener a tu aplicación lista, después de que has terminado tu aplicación. Asegúrate que has considerado tu estrategia de promoción antes de presionar el botón final de “Ingresar” en tu aplicación. Crear una comunidad alrededor de tu aplicación solo ayudará a hacer crecer a tu audiencia, porque los usuarios entusiastas son también evangelistas poderosos de tu esfuerzo.</p>
<p>Si te has tomado este tiempo para crear una nueva aplicación sorprendente para Windows Phone, necesitas estar seguro de que va a tener el impacto potencial que estas esperando. Enfocarte en monetizar, promocionar y opinar es tan importante como tu aplicación misma.</p>
<p>Este es el artículo final de esta serie. Espero que la hayas disfrutado tanto como nosotros lo hemos hecho al escribirla. Muchas gracias por leer todos los post.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-31-promoviendo-tu-aplicacin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 30: Base de datos local</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-30-base-de-datos-local/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-30-base-de-datos-local/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 16:39:13 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/?p=3533</guid>
		<description><![CDATA[Esta es una traducción de Day 30: Local Database, puedes encontrar el artículo aquí en su versión original en inglés. ¿Qué es una base de datos local? En la versión original de Windows Phone 7, podíamos salvar información pero tomaba cierto código especial o utilizar bases de datos de terceros como SterlingDB para tener un repositorio de información relaciona que algunas aplicaciones necesitan. Esto limitó algunos tipos de aplicaciones que algunos desarrolladores pudieron producir para los usuarios. En Windows Phone Mango, los desarrolladores aún cuentan con el almacenamiento aislado para mantener información e información almacenada para sus aplicaciones pero ahora tenemos SQL CE como un elemento de almacenamiento relacional para crear aplicaciones aún mejores para Windows Phone. Como otras soluciones de bases de datos para el Windows Phone original, la base de datos nativa de SQL CE creada en Mango tiene su información almacenada en el almacenamiento aislado del dispositivo. Puedes aprender mas acerca del almacenamiento aislado aquí. Microsof tampoco creó nuevas formas de trabajar con la información en el teléfono y en su lugar implementó LINQ a SQL para todas las operaciones de las bases de datos. LINQ a SQL es usado para hacer todas la funciones para la [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/30/31-days-of-mango-day-30-local-database/">Esta es una traducción de Day 30: Local Database, puedes encontrar el artículo aquí en su versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia30.png"><img style="padding-left: 0px; padding-right: 0px; padding-top: 0px; border-width: 0px;" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia30_thumb.png" alt="dia30" width="600" height="75" border="0" /></a></p>
<p><strong><span style="font-size: large;">¿Qué es una base de datos local?</span></strong></p>
<p>En la versión original de Windows Phone 7, podíamos salvar información pero tomaba cierto código especial o utilizar bases de datos de terceros como SterlingDB para tener un repositorio de información relaciona que algunas aplicaciones necesitan. Esto limitó algunos tipos de aplicaciones que algunos desarrolladores pudieron producir para los usuarios.</p>
<p>En Windows Phone Mango, los desarrolladores aún cuentan con el almacenamiento aislado para mantener información e información almacenada para sus aplicaciones pero ahora tenemos SQL CE como un elemento de almacenamiento relacional para crear aplicaciones aún mejores para Windows Phone.</p>
<p>Como otras soluciones de bases de datos para el Windows Phone original, la base de datos nativa de SQL CE creada en Mango tiene su información almacenada en el almacenamiento aislado del dispositivo. Puedes aprender mas acerca del almacenamiento aislado <a href="http://msdn.microsoft.com/en-us/library/ff402541(v=VS.92).aspx">aquí</a>. Microsof tampoco creó nuevas formas de trabajar con la información en el teléfono y en su lugar implementó LINQ a SQL para todas las operaciones de las bases de datos. LINQ a SQL es usado para hacer todas la funciones para la aplicación cuando se trate de manejar la información incluyendo crear la información, llenar la base de datos, obtener información u finalmente guardar y borrarla.</p>
<p>Un buen tutorial de LINQ para SQL esta <a href="http://msdn.microsoft.com/en-us/library/bb425822.aspx">aquí</a> en MSDN.</p>
<p><strong><span style="font-size: large;">Ajustar una base de datos local para tu aplicación de mango</span></strong></p>
<p>Como todos los puntos de inicio para Windows Phone 7, empezaremos creando un proyecto de Windows Phone Databound Application dentro de Visual Studio 2010.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image002_thumb4.jpg"><img style="padding-left: 0px; padding-right: 0px; padding-top: 0px; border-width: 0px;" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image002_thumb4_thumb.jpg" alt="clip_image002_thumb4" width="522" height="361" border="0" /></a></p>
<p>Pudimos haber comenzado con una aplicación sencilla de Windows Phone, pero me gustan los elementos adicionales que te dan para permitir que tu aplicación tenga mejores patrones de diseño como Model-View-ViewModel (MVVM).</p>
<p>A continuación actualizaremos el MainPage del proyecto para permitir que la información sea agregada a la sabes de datos. Nuestra información de ejemplo estará coleccionando ideas que todos tenemos y necesitamos  recordar. No iremos a gran detalle acerca del diseño del MainPage pero aquí está el XAML para obtener la apariencia para nuestro colector de ideas.</p>
<p>&lt;phone:PhoneApplicationPage<br />
x:Class=&#8221;Dia_30_BaseDatosLocal.MainPage&#8221;<br />
xmlns=&#8221;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;<br />
xmlns:x=&#8221;http://schemas.microsoft.com/winfx/2006/xaml&#8221;<br />
xmlns:phone=&#8221;clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone&#8221;<br />
xmlns:shell=&#8221;clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone&#8221;<br />
xmlns:d=&#8221;http://schemas.microsoft.com/expression/blend/2008&#8243;<br />
xmlns:mc=&#8221;http://schemas.openxmlformats.org/markup-compatibility/2006&#8243;<br />
mc:Ignorable=&#8221;d&#8221; d:DesignWidth=&#8221;480&#8243; d:DesignHeight=&#8221;768&#8243;<br />
d:DataContext=&#8221;{d:DesignData SampleData/MainViewModelSampleData.xaml}&#8221;<br />
FontFamily=&#8221;{StaticResource PhoneFontFamilyNormal}&#8221;<br />
FontSize=&#8221;{StaticResource PhoneFontSizeNormal}&#8221;<br />
Foreground=&#8221;{StaticResource PhoneForegroundBrush}&#8221;<br />
SupportedOrientations=&#8221;Portrait&#8221;  Orientation=&#8221;Portrait&#8221;<br />
shell:SystemTray.IsVisible=&#8221;True&#8221;&gt;</p>
<p>&lt;Grid x:Name=&#8221;LayoutRoot&#8221; Background=&#8221;Transparent&#8221;&gt;<br />
&lt;Grid.RowDefinitions&gt;<br />
&lt;RowDefinition Height=&#8221;Auto&#8221;/&gt;<br />
&lt;RowDefinition Height=&#8221;*&#8221;/&gt;<br />
&lt;/Grid.RowDefinitions&gt;</p>
<p>&lt;StackPanel x:Name=&#8221;TitlePanel&#8221; Grid.Row=&#8221;0&#8243; Margin=&#8221;12,17,0,28&#8243;&gt;<br />
&lt;TextBlock x:Name=&#8221;ApplicationTitle&#8221; Text=&#8221;LA LIGA SILVERLIGHT&#8221; Style=&#8221;{StaticResource PhoneTextNormalStyle}&#8221;/&gt;<br />
&lt;TextBlock x:Name=&#8221;PageTitle&#8221; Text=&#8221;base datos&#8221; Margin=&#8221;9,-7,0,0&#8243; Style=&#8221;{StaticResource PhoneTextTitle1Style}&#8221;/&gt;<br />
&lt;/StackPanel&gt;</p>
<p>&lt;Grid x:Name=&#8221;ContentPanel&#8221; Grid.Row=&#8221;1&#8243; Margin=&#8221;12,0,12,0&#8243;&gt;<br />
&lt;Grid.RowDefinitions&gt;<br />
&lt;RowDefinition Height=&#8221;Auto&#8221; /&gt;<br />
&lt;RowDefinition Height=&#8221;Auto&#8221; /&gt;<br />
&lt;/Grid.RowDefinitions&gt;</p>
<p>&lt;ListBox x:Name=&#8221;lstIdeas&#8221; ItemsSource=&#8221;{Binding IdeaItems}&#8221;<br />
Grid.Row=&#8221;0&#8243; Margin=&#8221;12, 0, 12, 0&#8243; Width=&#8221;440&#8243;&gt;<br />
&lt;ListBox.ItemTemplate&gt;<br />
&lt;DataTemplate&gt;<br />
&lt;Grid HorizontalAlignment=&#8221;Stretch&#8221; Width=&#8221;440&#8243;&gt;<br />
&lt;Grid.ColumnDefinitions&gt;<br />
&lt;ColumnDefinition Width=&#8221;50&#8243; /&gt;<br />
&lt;ColumnDefinition Width=&#8221;*&#8221; /&gt;<br />
&lt;ColumnDefinition Width=&#8221;100&#8243; /&gt;<br />
&lt;/Grid.ColumnDefinitions&gt;<br />
&lt;CheckBox IsChecked=&#8221;{Binding IsComplete, Mode=TwoWay}&#8221; Grid.Column=&#8221;0&#8243; VerticalAlignment=&#8221;Center&#8221;/&gt;<br />
&lt;TextBlock Text=&#8221;{Binding ItemName}&#8221; FontSize=&#8221;{StaticResource PhoneFontSizeLarge}&#8221; Grid.Column=&#8221;1&#8243; VerticalAlignment=&#8221;Center&#8221;/&gt;<br />
&lt;Button Grid.Column=&#8221;2&#8243; x:Name=&#8221;btnBorrarIdea&#8221; BorderThickness=&#8221;0&#8243; Margin=&#8221;0&#8243; Click=&#8221;btnBorrar_Click&#8221;&gt;<br />
&lt;Image Source=&#8221;appbar.delete.rest.png&#8221;/&gt;<br />
&lt;/Button&gt;<br />
&lt;/Grid&gt;<br />
&lt;/DataTemplate&gt;<br />
&lt;/ListBox.ItemTemplate&gt;<br />
&lt;/ListBox&gt;</p>
<p>&lt;Grid Grid.Row=&#8221;1&#8243;&gt;<br />
&lt;Grid.ColumnDefinitions&gt;<br />
&lt;ColumnDefinition Width=&#8221;*&#8221; /&gt;<br />
&lt;ColumnDefinition Width=&#8221;Auto&#8221; /&gt;<br />
&lt;/Grid.ColumnDefinitions&gt;<br />
&lt;TextBox x:Name=&#8221;txtNuevaIdea&#8221; Grid.Column=&#8221;0&#8243; Text=&#8221;agregar nueva idea&#8221;<br />
FontFamily=&#8221;{StaticResource PhoneFontFamilyLight}&#8221; GotFocus=&#8221;txtNuevaIdea_GotFocus&#8221;/&gt;<br />
&lt;Button Content=&#8221;+&#8221; Grid.Column=&#8221;1&#8243; x:Name=&#8221;btnAgregar&#8221; Click=&#8221;btnAgregar_Click&#8221; FontSize=&#8221;29.333&#8243;/&gt;<br />
&lt;/Grid&gt;<br />
&lt;/Grid&gt;<br />
&lt;/Grid&gt;</p>
<p>&lt;/phone:PhoneApplicationPage&gt;</p>
<p>También para dejar que nuestra aplicación se compile y corra sin hacer nada el código de abajo será agregado en el archivo MainPage.xaml.cs dentro de la clase MainPage y después del constructor.</p>
<p>private void txtNuevaIdea_GotFocus(object sender, RoutedEventArgs e)<br />
{<br />
txtNuevaIdea.Text = String.Empty;<br />
}</p>
<p>private void btnAgregar_Click(object sender, RoutedEventArgs e)<br />
{</p>
<p>}</p>
<p>protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)<br />
{<br />
base.OnNavigatedFrom(e);<br />
}</p>
<p><strong><span style="font-size: large;">Trabajar con el Data Context</span></strong></p>
<p>El Data Context es el punto que nos permite trabajar con la base de datos y también con las clases proxy que representan las tablas de nuestra base de datos. El Data Context es también una clase y trabaja contra un número de  clases de tipo“Objeto CLR viejo y plano” (POCO) que fueron creadas para este proyecto. Los objetos de tipo tabla que representan las tablas de nuestra base de datos contendrán una colección de entidades para cada registro de la tabla almacenado en la base de datos, Otros detalles acerca de nuestra base de datos están también dados por medio del Data Context tales como llaves primarias y mapas de asociación entre tablas.</p>
<p>Solo un recordatorio de que esta base de datos no tiene conexión con el SQL Server 2008 R2 que esta corriendo localmente en tu PC o un servidor en tu proveedor de hosting o compañia y solo mantiene la información en tu dispositivo.</p>
<p>No hay mucho de la clase de tipo DataContext ademas de la cadena de conexión con la que estamos familiarizados en desarrollo y propiedades de cada tabla que existen en nuestra base de datos. Piensa en el DataContext como el “eje” para la información de tu aplicación. El código para el Data Context de nuestra aplicación de ejemplo es el siguiente:</p>
<p>public class IdeaDataContext : DataContext<br />
{<br />
public static string cadenaConexion = &#8220;Data Source=isostore:/Ideas.sdf&#8221;;<br />
public IdeaDataContext(string cadenaConex): base(cadenaConex)<br />
{ }</p>
<p>public Table&lt;IdeaItem&gt; ElementoIdea;<br />
}</p>
<p>Nota que el tipo ElementoIdea estará detallado en la siguiente sección que cubre la creación de la base de datos.</p>
<p><strong><span style="font-size: large;">Crear la base de datos</span></strong></p>
<p>A diferencia de las aplicaciones que corren desde tu PC o en IIS 7, las bases de datos de Windows Phone deben ser creadas e inicializadas en la primera instancia de tu aplicación. Primero veremos como crear las clases que representarán las tablas de nuestra base de datos y después mirar la inicialización de la base de datos,</p>
<p>Por cada tabla que necesitamos que sea creada y expuesta a través de nuestra base de datos en nuestro teléfono para la aplicación, necesitamos crear un nuevo POCO. Dado que etas clases representan las entidades que estarán almacenadas en la base de datos, vamos a llamarlas clases de entidad. Para iniciar la clase de entidad debemos adherir dos interfaces.</p>
<p>* INotifyPropertyChanged – La interfaz INotifyPropertyChanged es usada para notificar a los clientes, típicamente enlazando que una propiedad ha cambiado.</p>
<p>* InotifyPropertyChanged – La interfaz INotifyPropertyChanging es usada para notificar a los clientes, típicamente enlazando que una propiedad esta cambiando.</p>
<p>Estas dos interfaces permitirán a cada entidad notificar al Data Context que esta en proceso de cambiar o esta cambiando. Esto después será reflejado en las vistas XAML de nuestra aplicación por medio del enlazado que hemos hecho.</p>
<p>Esta clase de entidad debe ser anotada como una tabla para permitir al DataContext saber como trabajar con ella. Una clase de entidad debe tener también propiedades públicas y privadas para cada propiedad de la Entidad también como tener la propiedad privada anotada para dar metadatos valiosos acera de la propiedad de la entidad (a.k.a. la columna de la base de datos). Recuerda tener las propiedades de la llave primaria para cada una de tus clases de entidad.</p>
<p>Debajo esta la clase de entidad ElementoIdea que estará localizada en la tabla ElementoIdea referenciada en el DataContext que creamos antes.</p>
<p>[Table]<br />
public class IdeaItem : INotifyPropertyChanged, INotifyPropertyChanging<br />
{<br />
private int idElementoIdea;<br />
private string nombreElemento;<br />
private bool estaAcompletada;</p>
<p>public event PropertyChangedEventHandler PropertyChanged;<br />
public event PropertyChangingEventHandler PropertyChanging;</p>
<p>[Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]<br />
public int IdElementoIdea<br />
{<br />
get<br />
{<br />
return idElementoIdea;<br />
}<br />
set<br />
{<br />
if (idElementoIdea != value)<br />
{<br />
NotifyPropertyChanging(&#8220;IdElementoIdea&#8221;);<br />
idElementoIdea = value;<br />
NotifyPropertyChanged(&#8220;IdElementoIdea&#8221;);<br />
}<br />
}<br />
}</p>
<p>[Column]<br />
public string NombreElemento<br />
{<br />
get<br />
{<br />
return nombreElemento;<br />
}<br />
set<br />
{<br />
if (nombreElemento != value)<br />
{<br />
NotifyPropertyChanging(&#8220;NombreElemento&#8221;);<br />
nombreElemento = value;<br />
NotifyPropertyChanged(&#8220;NombreElemento&#8221;);<br />
}<br />
}<br />
}</p>
<p>[Column]<br />
public bool EstaAcompletada<br />
{<br />
get<br />
{<br />
return estaAcompletada;<br />
}<br />
set<br />
{<br />
if (estaAcompletada != value)<br />
{<br />
NotifyPropertyChanging(&#8220;EstaAcompletada&#8221;);<br />
estaAcompletada = value;<br />
NotifyPropertyChanged(&#8220;EstaAcompletada&#8221;);<br />
}<br />
}<br />
}</p>
<p>[Column(IsVersion = true)]<br />
private Binary version;</p>
<p>private void NotifyPropertyChanged(string nombrePropiedad)<br />
{<br />
if (PropertyChanged != null)<br />
{<br />
PropertyChanged(this, new PropertyChangedEventArgs(nombrePropiedad));<br />
}<br />
}</p>
<p>private void NotifyPropertyChanging(string nombrePropiedad)<br />
{<br />
if (PropertyChanging != null)<br />
{<br />
PropertyChanging(this, new PropertyChangingEventArgs(nombrePropiedad));<br />
}<br />
}<br />
}</p>
<p>Finalmente debemos crear la base de datos si esta no existe. Esto lo haremos en el constructor de la aplicación. Encontrarás esto en el archivo App.xaml.cs. El código que será agregado al final del método constructor es como el que sigue.</p>
<p>using (IdeaDataContext baseDatos = new IdeaDataContext(IdeaDataContext.cadenaConexion))<br />
{<br />
if (baseDatos.DatabaseExists() == false)<br />
{<br />
baseDatos.CreateDatabase();<br />
}<br />
}</p>
<p>Ahora tenemos una base de datos que ha sido creada e inicializada en el almacenamiento aislado. Una cosa mas para recordar es que las bases de datos locales en Windows Phone 7 no pueden ser directamente compartidas entre aplicaciones en el teléfono dada la seguridad otorgada por el “sandbox” en el sistema operativo Windows Phone.</p>
<p><strong><span style="font-size: large;">Soporte de LINQ to SQL para Windows Phone Mango</span></strong></p>
<p>El SDK de Windows Phone 7.1 permite algunos, no todos los elementos de LINQ to SQL dentro de Windows Phone. Los siguientes son solo algunos elementos para recordar al trabajar con información y LINQ to SQL en Windows Phone Mango.</p>
<p>* Execute Command no es soportado.</p>
<p>* Los objetos ADO.NET (tales como DataReader) no están soportados.</p>
<p>* Solo son soportados los tipos de datos de Microsoft SQL Server Compact Edition (SQL CE)</p>
<p>Para obtener mas limitantes y elementos de usar LINQ to SQL en Mango, por favor lee la página de MSDN <a href="http://msdn.microsoft.com/en-us/library/hh202872(v=VS.92).aspx">aquí</a>.</p>
<p><strong><span style="font-size: large;">Obtener Información desde una base de datos local</span></strong></p>
<p>Para obtener información o cualquier trabajo relacionado con la base de datos local, primero debemos crear el DataContext y conectarlo a la base de datos. Esto sucederá en el MainPage por medio de una variable privada para el DataContext, una propiedad de tipo Observable Collection para las ideas en la base de datos y en el constructor del MainPage como se muestra aquí.</p>
<p>private IdeaDataContext ideaDB;</p>
<p>private ObservableCollection&lt;IdeaItem&gt; listaIdeas;<br />
public ObservableCollection&lt;IdeaItem&gt; ListaIdeas<br />
{<br />
get<br />
{<br />
return listaIdeas;<br />
}<br />
set<br />
{<br />
if (listaIdeas != value)<br />
{<br />
listaIdeas = value;<br />
NotifyPropertyChanged(&#8220;IdeaItems&#8221;);<br />
}<br />
}<br />
}</p>
<p>public MainPage()<br />
{<br />
InitializeComponent();<br />
ideaDB = new IdeaDataContext(IdeaDataContext.cadenaConexion);</p>
<p>this.DataContext = this;<br />
}</p>
<p>Para obtener nuestras ideas localizadas en la base de datos local usaremos LINQ to SQL para consultar y obtener la colección de la base de datos vía el DataContext.</p>
<p>protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)<br />
{<br />
var ideaEnBaseDatos = from IdeaItem idea in ideaDB.ElementoIdea<br />
select idea;</p>
<p>ListaIdeas = new ObservableCollection&lt;IdeaItem&gt;(ideaEnBaseDatos);<br />
base.OnNavigatedTo(e);<br />
}</p>
<p>Las ideas ahora están enlazadas y reflejadas en el MainPage.xaml .</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0033.png"><img style="padding-left: 0px; padding-right: 0px; padding-top: 0px; border: 0px none;" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0033_thumb.png" alt="clip_image0033" width="241" height="401" border="0" /></a></p>
<p><strong><span style="font-size: large;">Almacenar información a la base de datos local</span></strong></p>
<p>Finalmente crearemos la forma de guardar nuestra información de ideas a la base de datos local. No enviaremos las ideas a la base de datos a menos de que necesitemos incrementar el rendimiento. Mantendremos todas las ideas en la colección local que creamos como una propiedad del MainPage (ListaIdeas). La adición de nuevas ideas a la base de datos local se efectuará cuando el botón de agregar idea cuando esta sea agregadas a la colección ListaIdeas.</p>
<p>private void btnAgregar_Click(object sender, RoutedEventArgs e)<br />
{<br />
IdeaItem nuevaIdea = new IdeaItem { NombreElemento = txtNuevaIdea.Text };<br />
ListaIdeas.Add(nuevaIdea);<br />
ideaDB.ElementoIdea.InsertOnSubmit(nuevaIdea);<br />
}</p>
<p>Como lo mencioné antes, las ideas coleccionadas desde el usuario no estarán almacenadas en la base de datos hasta que la aplicación se haya salido del MainPage ya sea que salga de la aplicación o que la aplicación se mueva a una nueva página. El código para el evento es el siguiente.</p>
<p>protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)<br />
{<br />
base.OnNavigatedFrom(e);<br />
ideaDB.SubmitChanges();<br />
}</p>
<p><strong><span style="font-size: large;">En resumen</span></strong></p>
<p>¡Eso es todo! Ahora tienes una forma simple de crear, almacenar y obtener información relacional en tus aplicaciones Windows Phone. ¿Cómo la piensas usar?</p>
<p>Para descargar este ejemplo entero de la aplicación de Windows Phone usando los conceptos aquí mostrados, puedes hacerlo en el enlace siguiente.</p>
<p><a href="http://aminespinoza.com/materialBlog/31dias/Dia_30_BaseDatosLocal.zip">Puedes descargar el código aquí.</a></p>
<p>Mañana el último artículo de la serie. cubriremos las mejores prácticas para promocionar tus aplicaciones de Windows Phone. Nos vemos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-30-base-de-datos-local/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 29: Globalizaci&#243;n</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-29-globalizacin/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-29-globalizacin/#comments</comments>
		<pubDate>Thu, 29 Dec 2011 19:52:11 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/?p=3513</guid>
		<description><![CDATA[Esta es una traducción de Day 29: Globalization, puedes encontrar el artículo aquí en su versión original en inglés. Globalización contra Localización Las personas comúnmente se confunden cuando se discute acerca de globalización y localización. Ambas tratan de lidiar con presentar contenido de una manera amigable por todo el mundo, pero la distinción es que la globalización trabaja con el formato de los elementos, tales como el tiempo, fechas, tipos de moneda y números en la forma en la que el usuario este familiarizado considerando, mientras que la localización involucra desplegar el idioma nativo del usuario en la interfaz. Este artículo cubrirá el uso de ambas técnicas para crear aplicaciones que puedan alcanzar una gran audiencia con la interfaz de usuario mas amigable posible. Estaremos creando una aplicación simple durante el curso de este artículo que soporte a ambas, globalización y localización. Esta aplicación rápidamente genera un mensaje de correo electrónico que permite saber al contacto que estas retrasado para una reunión. Configurar soporte para la localización Después de crear un nuevo Windows Phone con C#, necesitaremos hacer algunas cosas para configurar la aplicación para que soporte la localización. Definir un lenguaje neutral para el ensamblado Dado que estamos localizando [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/29/31-days-of-mango-day-29-globalization/">Esta es una traducción de Day 29: Globalization, puedes encontrar el artículo aquí en su versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia29.png"><img style="padding-left: 0px; padding-right: 0px; padding-top: 0px; border-width: 0px;" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia29_thumb.png" alt="dia29" width="600" height="75" border="0" /></a></p>
<p><strong><span style="font-size: large;">Globalización contra Localización</span></strong></p>
<p>Las personas comúnmente se confunden cuando se discute acerca de globalización y localización. Ambas tratan de lidiar con presentar contenido de una manera amigable por todo el mundo, pero la distinción es que la globalización trabaja con el formato de los elementos, tales como el tiempo, fechas, tipos de moneda y números en la forma en la que el usuario este familiarizado considerando, mientras que la localización involucra desplegar el idioma nativo del usuario en la interfaz. Este artículo cubrirá el uso de ambas técnicas para crear aplicaciones que puedan alcanzar una gran audiencia con la interfaz de usuario mas amigable posible.</p>
<p>Estaremos creando una aplicación simple durante el curso de este artículo que soporte a ambas, globalización y localización. Esta aplicación rápidamente genera un mensaje de correo electrónico que permite saber al contacto que estas retrasado para una reunión.</p>
<p><strong><span style="font-size: large;">Configurar soporte para la localización</span></strong></p>
<p>Después de crear un nuevo Windows Phone con C#, necesitaremos hacer algunas cosas para configurar la aplicación para que soporte la localización.</p>
<p><strong>Definir un lenguaje neutral para el ensamblado</strong></p>
<p>Dado que estamos localizando nuestra aplicación, necesitamos decirle al proyecto cual es la localización preestablecida. Para hacer esto, vamos a  ir cuadro de diálogo de las propiedades del proyecto y clic en “Assembly Information” y después especificar el idioma neutral para nuestra aplicación – eso es, el lenguaje que será utilizado si no hay recursos locales definidos que coincidan con los del usuario. Para este ejemplo, ajustaremos el lenguaje neutral en “English (United States)”.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0024.jpg"><img style="padding-left: 0px; padding-right: 0px; padding-top: 0px; border-width: 0px;" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0024_thumb.jpg" alt="clip_image0024" width="262" height="250" border="0" /></a></p>
<p>Indicando la cultura soportada</p>
<p>A continuación necesitamos decirle al proyecto que lenguajes están soportados. Visual Studio no expone esta parte de información del proyecto, pero podemos editarla fácilmente. Asegúrate de guardar todos los cambios de modo que todos los cambios al .csproj estén guardados antes de editar el archivo. Después ve a la carpeta del proyecto en el disco  dando clic derecho en el proyecto y selecciona “Open Folder in Windows Explorer”. Selecciona el .csproj para tu aplicación (se cuidadoso de no seleccionar el archivo .csproj.user) y ábrelo con el bloc de notas o tu editor de textos favorito (N. del T. una amplia recomendación es <a href="http://notepad-plus-plus.org/">Notepad++</a>).</p>
<p>Busca el elemento &lt;SupportedCultures&gt;&lt;/SupportedCultures&gt; y agrega el código de las culturas que deseas soportar separando cada cultura por un punto y coma. Esta lista no deberá incluit el lenguaje neutral del ensamblado. Visita <a href="http://msdn.microsoft.com/en-us/library/hh202918%28v=VS.92%29.aspx">http://msdn.microsoft.com/en-us/library/hh202918(v=VS.92).aspx</a> para una lista de culturas soportadas por varias versiones de Windows Phone. Para los propósitos de este ejemplo, estaremos soportando Español, Chino simplificado y Francés, además del el preestablecido que fue el Inglés, así que nuestro nodo de SupportedCultures se verá así.</p>
<p>&lt;SupportedCultures&gt;es-ES;zh-CN;fr-FR&lt;/SupportedCultures&gt;</p>
<p>Después de hacer tus cambios, guarda el archivo .csproj y ve de regreso a Visual Studio. Presiona “recargar” cuando Visual Studio te diga que el proyecto ha cambiado para que estos cambios puedan tener efecto.</p>
<p><strong><span style="font-size: large;">Crear un archivo de recursos base</span></strong></p>
<p>Ahora que tenemos una cultura preestablecida y una lista de otras mas soportadas, podemos empezar a definir los recursos específicos para cada cultura. Empezaremos agregando un archivo para los recursos preestablecidos y movernos para agregar recursos para culturas específicas. Como una buena práctica de localización, cualquier cadena que el usuario vea deberá ser incluida en estos archivos en lugar de hacerlas de modo estático en XAML o en un archivo de código.</p>
<p>Necesitamos agregar un archivo de recursos al proyecto que defina las cadenas de lenguaje para la aplicación. Para hacer esto, daremos clic derecho en nuestro proyecto en el explorador de soluciones y elegimos “Add –&gt; New Item”. Desde aquí, agregaremos un archivo de recursos. Puedes llamarlo como gustes, para este ejemplo lo llamaremos Cadenas.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image004_thumb5.jpg"><img style="padding-left: 0px; padding-right: 0px; padding-top: 0px; border-width: 0px;" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image004_thumb5_thumb.jpg" alt="clip_image004_thumb5" width="518" height="359" border="0" /></a></p>
<p>Agregar el archivo nos lleva al editor de recursos para este reecurso. El editor contiene una tabla con tres columnas, Name, Value y Comment. Nombre es el nombre auto generado por code-behind para el recurso y sirve como clave única para identificar un recurso. Value es el valor específico de la cultura para este recurso y es lo que usaremos para almacenar el texto que el usuario vea. Comment no es usado por la aplicación, pero es útil para señalar para que usamos tal recurso y donde lo usamos, además puede ayudar demasiado durante la traducción a otros lenguajes. También verás un modificador de acceso en la cima del editor de recursos. Este es interno de forma preestablecida pero necesitamos cambiarlo a público de modo que podamos enlazar estos valores mas adelante.</p>
<p>Aquí esta nuestro ejemplo después de agregar las cadenas apropiadas y cambiar el modificador de acceso a público:</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image006_thumb3.jpg"><img style="padding-left: 0px; padding-right: 0px; padding-top: 0px; border-width: 0px;" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image006_thumb3_thumb.jpg" alt="clip_image006_thumb3" width="518" height="324" border="0" /></a></p>
<p>Crear archivos de recursos específicos para cada cultura</p>
<p>Ahora que tenemos nuestros recursos preestablecidos definidos, podemos iniciar a crear recursos personalizados para el proyecto. Empezaremos definiendo los recursos en español para esta aplicación. Presiona y arrastra el archivo cadenas.resx en el explorador de soluciones para crear una copia del archivo y después renómbralo como “CopiaDeCadenas.resx” a “Cadenas.es-ES.resx” (es-ES es el código de cultura para el español). Es importante que este nuevo archivo inicie con el mismo nombre como este nuevo archivo inicie con el mismo nombre que el previo  pero teniendo la localización adecuada al final de este o el archivo no podrá ser utilizado de manera adecuada para mapear la localización adecuada. Una vez que has renombrado tal archivo, abre el archivo Cadenas.es-ES.resx y modifica la columna Value para cada recurso. Una buena fuente para traducciones es Bing Translator, además de que debes verificar las traducciones con alguien que entienda el lenguaje antes de desplegar. Es importante que la columna Name coincida entre los archivos de recursos para que los recursos puedan ser mapeados apropiadamente.</p>
<p>Una vez  que has terminado con esto, sigue el mismo procedimiento para cualquier localidad adicional que desees soportar siendo cuidadoso de que todos los recursos tienen un modificador de acceso público, mantén el mismo nombre y contén el código de cultura apropiado. Es también importante notar que el editor de recursos puede no desplegar ciertos conjuntos de caracteres extranjeros correctamente cuando copies y pegues desde el traductor de Bing al editor de recursos, pero estos caracteres se verán bien en el dispositivo o emulador.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image008_thumb3.jpg"><img style="padding-left: 0px; padding-right: 0px; padding-top: 0px; border-width: 0px;" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image008_thumb3_thumb.jpg" alt="clip_image008_thumb3" width="518" height="313" border="0" /></a></p>
<p><strong><span style="font-size: large;">Crear una interfaz de usuario no localizada</span></strong></p>
<p>Ahora que tenemos un conjunto de cadenas localizadas, mejor comenzamos a crear la interfaz en donde podamos usarlas. Nuestra aplicación de ejemplo tendrá algunos campos, una barra de aplicación y un encabezado estándar. Dado que queremos incluir datos en este ejemplo para demostrar la globalización, haremos referencia al Toolkit de Silverlight para Windows Phone y usar el control de TimePicker contenido en ese ensamblado. Este artículo no irá hasta el detalle de descargar, instalar y hacer referencia al Toolkit, pero este está disponible y nos será útil.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0102.jpg"><img style="padding-left: 0px; padding-right: 0px; padding-top: 0px; border: 0px;" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0102_thumb.jpg" alt="clip_image0102" width="214" height="389" border="0" /></a></p>
<p>Nuestro MainPage no localizado se verá así.</p>
<pre class="brush: xml">
&lt;phone:phoneapplicationpage x:Class=&quot;Dia_29_Globalizacion.MainPage&quot;
xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
xmlns:phone=&quot;clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone&quot;
xmlns:shell=&quot;clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone&quot;
xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
mc:Ignorable=&quot;d&quot; d:DesignWidth=&quot;480&quot; d:DesignHeight=&quot;696&quot;
FontFamily=&quot;{StaticResource PhoneFontFamilyNormal}&quot;
FontSize=&quot;{StaticResource PhoneFontSizeNormal}&quot;
xmlns:Controls=&quot;clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit&quot;
Foreground=&quot;{StaticResource PhoneForegroundBrush}&quot;
SupportedOrientations=&quot;Portrait&quot; Orientation=&quot;Portrait&quot;
shell:SystemTray.IsVisible=&quot;True&quot;&gt;

&lt;grid x:Name=&quot;LayoutRoot&quot; Background=&quot;Transparent&quot;&gt;
&lt;/grid&gt;&lt;grid .RowDefinitions&gt;
&lt;rowdefinition Height=&quot;Auto&quot;/&gt;
&lt;rowdefinition Height=&quot;*&quot;/&gt;
&lt;/grid&gt;

&lt;stackpanel x:Name=&quot;TitlePanel&quot; Grid.Row=&quot;0&quot; Margin=&quot;12,17,0,28&quot;&gt;
&lt;textblock x:Name=&quot;ApplicationTitle&quot; Text=&quot;{Binding Source={StaticResource Cadenas}, Path=Resources}&quot;
Style=&quot;{StaticResource PhoneTextNormalStyle}&quot; /&gt;
&lt;textblock x:Name=&quot;PageTitle&quot; Text=&quot;{Binding Resources.PageTitleSendMessage, Source={StaticResource Cadenas}}&quot;
Margin=&quot;9,-7,0,0&quot; Style=&quot;{StaticResource PhoneTextTitle1Style}&quot; TextWrapping=&quot;Wrap&quot; /&gt;
&lt;/stackpanel&gt;

&lt;scrollviewer Margin=&quot;12,0,12,0&quot; Grid.Row=&quot;1&quot;&gt;
&lt;stackpanel x:Name=&quot;ContentPanel&quot;&gt;
&lt;textblock TextWrapping=&quot;Wrap&quot; Text=&quot;{Binding Resources.FieldTo, Source={StaticResource Cadenas}}&quot; Style=&quot;{StaticResource PhoneTextSubtleStyle}&quot; /&gt;
&lt;textbox x:Name=&quot;txtPara&quot; TextWrapping=&quot;Wrap&quot; InputScope=&quot;EmailUserName&quot; /&gt;
&lt;hyperlinkbutton x:Name=&quot;btnElegirContacto&quot; Content=&quot;{Binding Resources.LinkChooseContact, Source={StaticResource Cadenas}}&quot;
HorizontalContentAlignment=&quot;Left&quot; Foreground=&quot;{StaticResource PhoneAccentBrush}&quot;
Click=&quot;btnElegirContacto_Click&quot; Margin=&quot;{StaticResource PhoneVerticalMargin}&quot; /&gt;
&lt;textblock TextWrapping=&quot;Wrap&quot; Text=&quot;{Binding Resources.FieldSubject, Source={StaticResource Cadenas}}&quot;
Style=&quot;{StaticResource PhoneTextSubtleStyle}&quot; /&gt;
&lt;textbox x:Name=&quot;txtTitulo&quot; TextWrapping=&quot;Wrap&quot; Text=&quot;{Binding Resources.AppTitle, Source={StaticResource Cadenas}}&quot;
InputScope=&quot;Text&quot; /&gt;
&lt;checkbox x:Name=&quot;chkInluirJustificacion&quot; Content=&quot;{Binding Resources.CheckIncludeAReason, Source={StaticResource Cadenas}}&quot; /&gt;
&lt;textbox x:Name=&quot;txtRazon&quot; TextWrapping=&quot;Wrap&quot; Text=&quot;{Binding Resources.DefaultReason, Source={StaticResource Cadenas}}&quot;
InputScope=&quot;Text&quot; IsEnabled=&quot;{Binding IsChecked, ElementName=chkInluirJustificacion}&quot; /&gt;
&lt;checkbox x:Name=&quot;chkIncluirETA&quot; Content=&quot;{Binding Resources.CheckShouldArriveBy, Source={StaticResource Cadenas}}&quot; /&gt;
&lt;controls:timepicker x:Name=&quot;timeLlegada&quot;
ValueStringFormat=&quot;{}{0:t}&quot;
IsEnabled=&quot;{Binding IsChecked, ElementName=chkIncluirETA}&quot;
Margin=&quot;0,-12,0,0&quot; /&gt;
&lt;checkbox x:Name=&quot;chkIncluirDiagnostico&quot;
Content=&quot;{Binding Resources.CheckIncludeDiagnostics, Source={StaticResource Cadenas}}&quot; /&gt;
&lt;/stackpanel&gt;
&lt;/scrollviewer&gt;

&lt;/phone:phoneapplicationpage&gt;&lt;phone:phoneapplicationpage .ApplicationBar&gt;
&lt;shell:applicationbar IsMenuEnabled=&quot;False&quot;&gt;
&lt;shell:applicationbariconbutton x:Name=&quot;btnEmail&quot; IconUri=&quot;/Imagenes/email.png&quot; IsEnabled=&quot;True&quot; Text=&quot;send&quot; Click=&quot;btnEmail_Click&quot; /&gt;
&lt;/shell:applicationbar&gt;
&lt;/phone:phoneapplicationpage&gt;
</pre>
<p>Obviamente este XAML contiene un número de cadenas estáticas las cuales no queremos para una aplicación localizable. Necesitamos que la interfaz de usuario tome ventaja de las cadenas de recursos.</p>
<p><strong><span style="font-size: large;">Obtener Cadenas de recursos en XAML</span></strong></p>
<p>Afortunadamente el diseñador de recursos con el que hemos estado trabajando tiene clases automáticamente generadas para acceder a estos recursos. Desafortunadamente, no podemos enlazar fácilmente estos en XAML por la clase de cadenas auto generadas que tiene un constructor interno y propiedades estáticas así que necesitaremos crear un “envoltorio” de recursos que exponga estos en una forma que podamos enlazar.</p>
<p>Agrega una nueva clase al proyecto llamada ProveedorCadenas.cs e incluye el siguiente código.</p>
<p><pre><code>namespace Dia_29_Globalizacion
{
public class ProveedorCadenas
{
private readonly Cadenas recursos = new Cadenas();

public Cadenas Resources
{
get { return recursos; }
}
}
}</code></pre></p>
<p>Ahora ve hacia el archivo de App.xaml y agrega un nuevo recurso a la aplicación con el calificador adecuado de espacio de nombres. Este recurso estará disponible a través de la aplicación entera y te dará un fácil acceso a la localización de cadenas. Cuando termines, tu App.xaml se deberá ver así.</p>
<p>&lt;Application<br />
x:Class=&#8221;Dia_29_Globalizacion.App&#8221;<br />
xmlns=&#8221;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;<br />
xmlns:x=&#8221;http://schemas.microsoft.com/winfx/2006/xaml&#8221; xmlns:local=&#8221;clr-namespace:Dia_29_Globalizacion&#8221;<br />
xmlns:phone=&#8221;clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone&#8221;<br />
xmlns:shell=&#8221;clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone&#8221;&gt;</p>
<p>&lt;Application.Resources&gt;<br />
&lt;local:ProveedorCadenas x:Key=&#8221;Cadenas&#8221; /&gt;<br />
&lt;/Application.Resources&gt;</p>
<p>&lt;Application.ApplicationLifetimeObjects&gt;<br />
&lt;shell:PhoneApplicationService<br />
Launching=&#8221;Application_Launching&#8221; Closing=&#8221;Application_Closing&#8221;<br />
Activated=&#8221;Application_Activated&#8221; Deactivated=&#8221;Application_Deactivated&#8221;/&gt;<br />
&lt;/Application.ApplicationLifetimeObjects&gt;</p>
<p>&lt;/Application&gt;</p>
<p>Ahora que hemos definido nuestro StringProvider como un recurso, podemos enlazarlo al MainPage. En este caso estamos enlazando a la sub propiedad de la propiedad de Reosurces representando el nombre del recurso como lo definimos antes en la colección de recursos y usando el objeto de  tipo ProveedorCadenas  como una fuente de enlazado. Por ejemplo, el título de nuestra aplicación se vuelve:</p>
<p>&lt;TextBlock x:Name=&#8221;ApplicationTitle&#8221; Text=&#8221;{Binding Source={StaticResource Cadenas}, Path=Resources}&#8221; Style=&#8221;{StaticResource PhoneTextNormalStyle}&#8221; /&gt;</p>
<p>Ambos, tanto Blend como Visual Studio deberán reconocar este enlazado y desplegar la cadena de lenguaje neutral (el valor en Cadenas.resx) en el diseñador si el proyecto ha sido compilado desde que los recursos fueron agregados.</p>
<p>Cuando creas aplicaciones globalizadas, ten cuidado de que muchas cadenas de lenguajes serán mayores de lo que es en el idioma preestablecido. Dado esto, es importante que ajustes la propiedad TextWrapping=&#8221;Wrap&#8221;  donde sea aplicable y usa un diseño flexible de estructuras de diseño como ScrollViewers y StackPanels que puedan adaptarse a contenido multi líneas cuando sea necesario. Dado el potencialmente largo recurso de las cadenas, es recomendable ajustar la propiedad SupportedOrientations=&#8221;PortraitOrLandscape&#8221; en la página cuando sea apropiado.</p>
<p>Es también importante estar al pendiente de que no todas las localidades soportan diferentes fuentes. Tu mejor apuesta en el caso de localización de aplicaciones es evitar las fuentes manualmente especificada o personalización de fuentes y en su lugar confiar en las fuentes ya creadas. Visita <a href="http://msdn.microsoft.com/en-us/library/hh202920%28v=VS.92%29.aspx">http://msdn.microsoft.com/en-us/library/hh202920(v=VS.92).aspx</a> para mas información.</p>
<p><strong><span style="font-size: large;">Referirse a cadenas localizadas en C#</span></strong></p>
<p>Este enfoque funcionará para la mayoría de las cadenas, pero las guías de diseño Metro requieren que el título de la aplicación en la cima de la página esté en mayúsculas y nuestra cadena en el archivo de recursos usa mayúsculas capitales. Podríamos definir un nuevo recurso solo para la etiqueta de título o escribir un convertidor de valores de tipo Uppercase para el enlazado, pero en su lugar solo vamos a ajustar el título en el code behind para poder demostrar el acceso a recursos localizados desde el código al agregar la siguiente línea en el constructor de tu MainPage:</p>
<p><pre><code>txtTituloApp.Text = Cadenas.AppTitle.ToUpper(CultureInfo.CurrentCulture);</code></pre></p>
<p><strong>Localizar la barra de aplicacón</strong></p>
<p>Los elementos de la barra de aplicación actualmente no soportan el enlazado de datos dado que ellos no son realmente controles de Silverlight personalizables. En su lugar, tendremos que ajustar manualmente el texto de nuestro ApplicationBarIconButton en el code behind al referirnos a la propiedad auto generada para nuestro nombre de recurso en el recurso de Cadenas como se muestra.</p>
<p><pre><code>public MainPage()
{
InitializeComponent();

txtTituloApp.Text = Cadenas.AppTitle.ToUpper(CultureInfo.CurrentCulture);

var button = (ApplicationBarIconButton)ApplicationBar.Buttons[0];
button.Text = Cadenas.ButtonSend;

timeLlegada.Value = DateTime.Now.AddMinutes(15);
}</code></pre></p>
<p>Ahora tenemos una aplicación localizada. Probar la aplicación en el emulador usando los ajustes para el lenguaje en francés resultará en lo siguiente.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0122.jpg"><img style="padding-left: 0px; padding-right: 0px; padding-top: 0px; border: 0px;" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0122_thumb.jpg" alt="clip_image0122" width="244" height="443" border="0" /></a></p>
<p><strong><span style="font-size: large;">Soportar globalización</span></strong></p>
<p>Ahora que tenemos una aplicación localizable, vámonos a la globalización. Dado que la globalización se encarga de los ajustes culturales del usuario respectivo, es importante dar el correcto IFormatProvider a varios métodos de formato de cadenas cuando sea apropiado. Afortunadamente .NET nos da CultureInfo.CurrentCulture el cual representa los ajustes culturales del usuario actual y pueden ser usados para formatear las cadenas para la interfaz del usuario. Cuando se hagan comparaciones estándar o al lidiar con la serialización u otras operaciones que el usuario no ve, es importante usar CultureInfo.InvariantCulture para asegurar que tu aplicación funcione adecuadamente en todos los ajustes de cultura.</p>
<p>A diferencia de la localización, no tienes que hacer nada para soportar una cultura particular e el framework .NET se preocupará de la mayoría de operaciones de formato de cultura por tí. Es también una buena práctica dar el formato apropiado de cadenas y especificar  el CultureInfo,CurrentCulture como un IFormarProvider cuando sea apropiado.</p>
<p>Por ejemplo, el código de nuestra aplicación esta hecho para generar un correo electrónico que haga explícito uso de CurrentCulture y formato de cadenas.</p>
<p><pre><code>private void btnEmail_Click(object sender, System.EventArgs e)
{
var cuerpo = new StringBuilder();
cuerpo.AppendLine(Cadenas.EmailHeader);

var cultura = CultureInfo.CurrentCulture;
if (chkInluirJustificacion.IsChecked == true)
{
cuerpo.AppendLine();
cuerpo.AppendLine(string.Format(cultura, &quot;{0}: {1}&quot;, Cadenas.EmailReason, txtRazon.Text));
}

if (chkIncluirETA.IsChecked == true)
{
cuerpo.AppendLine();
cuerpo.AppendLine(string.Format(cultura, &quot;{0}: {1}&quot;, Cadenas.CheckShouldArriveBy, timeLlegada.ValueString));
}

if (chkIncluirDiagnostico.IsChecked == true)
{
cuerpo.AppendLine();
cuerpo.AppendLine(cultura.Name);
cuerpo.AppendLine(string.Format(cultura, &quot;pi: {0}&quot;, Math.PI));
cuerpo.AppendLine(string.Format(cultura, &quot;number: {0}&quot;, -1));
cuerpo.AppendLine(string.Format(cultura, &quot;currency: {0:c}&quot;, 4200.00));
cuerpo.AppendLine(string.Format(cultura, &quot;date: {0:D}&quot;, DateTime.Today));
cuerpo.AppendLine(string.Format(cultura, &quot;time: {0:t}&quot;, DateTime.Now));
}

if (Microsoft.Devices.Environment.DeviceType == DeviceType.Emulator)
{
MessageBox.Show(cuerpo.ToString());
}
else
{
var tarea = new EmailComposeTask { Subject = txtTitulo.Text, To = txtPara.Text, Body = cuerpo.ToString() };
tarea.Show();
}
}</code></pre></p>
<p>Dado que la globalización esta separada de la localización, corre a aplicación en un lenguaje sin cadenas localizadas resultará en valores apropiadamente globalizados así como estos valores alemanes en la imagen de abajo:</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0142.jpg"><img style="padding-left: 0px; padding-right: 0px; padding-top: 0px; border: 0px;" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0142_thumb.jpg" alt="clip_image0142" width="235" height="427" border="0" /></a></p>
<p>Especificar el formato de cadenas en XAML</p>
<p>Ocasionalmente querrás ser capaz de especificar un formato de cadena en XAML  ya sea como un parámetro para un value converter o como una propiedad en un control previamente creado. En nuestro ejemplo ajustaremos explícitamente el formato de la cadena de nuestro TimePicker para acortar el formato de tiempo para la cultura actual (“t”). Para hacer esto, prefijamos el formato de la cadena con un par de llaves como se muestra aquí.</p>
<p>&lt;Controls:TimePicker x:Name=&#8221;timeLlegada&#8221;<br />
ValueStringFormat=&#8221;{}{0:t}&#8221;<br />
IsEnabled=&#8221;{Binding IsChecked, ElementName=chkIncluirETA}&#8221;<br />
Margin=&#8221;0,-12,0,0&#8243; /&gt;</p>
<p>Es también posible ajustar esto en C# de la siguiente manera.</p>
<p><pre><code>var info = CultureInfo.CurrentCulture.DateTimeFormat;
timeArrival.ValueStringFormat = &quot;{0:&quot; + info.ShortTimePattern + &quot;}&quot;;</code></pre></p>
<p>O mucho mas preciso.</p>
<p><pre><code>timeArrival.ValueStringFormat = &quot;{0:t}&quot;;</code></pre></p>
<p><strong><span style="font-size: large;">Probando diferentes culturas</span></strong></p>
<p>Hasta ahora, hemos creado una aplicación enteramente funcional que soporte la globalización y localización. Quizá te preguntes ahora como probarla en diferentes culturas. Los dispositivos Windows Phone quizá no te permitan cambiar el idioma de despliegue de tu pantalla, pero afortunadamente, Microsoft le dio esta capacidad al emulador.</p>
<p>Para acceder a estos ajustes, ve al menú de aplicaciones del emulador en la pantalla de inicio y escoge la aplicación de ajustes. Desde ahí da clic en el elemento del pivot que dice Region+Lenguaje</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0161.jpg"><img style="padding-left: 0px; padding-right: 0px; padding-top: 0px; border: 0px;" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0161_thumb.jpg" alt="clip_image0161" width="212" height="385" border="0" /></a></p>
<p>Esta pantalla te permite personalizar el lenguaje que se mostrará en el teléfono al ajustar en la lista de selección el lenguaje que quieres mostrar y después dando clic en el enlace de “Da tap aquí para aceptar los cambios”. Al hacerlo, se reiniciará la imagen del SO Windows Phone de tu emulador y aplicará los ajustes de lenguaje y globalización que has elegido. Puede ser confuso usar páginas de ajustes en un lenguaje que no conoces para cambiar los ajustes regionales, así que es una gran idea estudiar el diseño de la pantalla antes de aplicar nuestros cambios. Una vez que el emulador se haya reiniciado al lanzar nuestra aplicación en el emulador podrás verificar que la aplicación respeta el lenguaje del usuario y sus ajustes culturales.</p>
<p><strong><span style="font-size: large;">Consideraciones de publicación</span></strong></p>
<p>Cuando quieras desplegar una aplicación que soporte diferentes lenguajes y culturas, asegúrate de elegir la distribución que coincida con los lenguajes soportados ya sea seleccionando una distribución global al publicar tu aplicación y ajustando los precios o seleccionando lugares individuales que desees soportar.</p>
<p><strong><span style="font-size: large;">En Resumen</span></strong></p>
<p>Ahora sabes como crear una aplicación desde el inicio hasta el final que ofrecerá la mejor experiencia al dar una aplicación propiamente globalizada y localizada para la audiencia global que usa Windows Phone.</p>
<p>Para descargar este ejemplo entero de la aplicación de Windows Phone usando los conceptos aquí mostrados, puedes hacerlo en el enlace siguiente.</p>
<p><a href="http://aminespinoza.com/materialBlog/31dias/Dia_29_Globalizacion.zip">Puedes descargar el código aquí.</a></p>
<p>Mañana, vamos a regresar a la información, y vamos a cubrir como usar una base de datos local en tu aplicación. Nos vemos</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-29-globalizacin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 28: Biblioteca multimedia</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-28-biblioteca-multimedia/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-28-biblioteca-multimedia/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 17:25:34 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/?p=3481</guid>
		<description><![CDATA[Esta es una traducción de Day 28: Media Library, puedes encontrar el artículo aquí en su versión original en inglés. Hoy vamos a echar un vistazo a la clase MediaLibrary que es parte del espacio de nombres Microsoft.Xna.Framework.Media. Como el nombre sugiere, esta clase nos da acceso a la biblioteca de medios del usuario. Una biblioteca de medios en Windows Phone almacena imágenes y música. Al usar las biblioteca de medios, puedes integrar este contenido en tus propias aplicaciones. Hay muchas razones por las que un desarrollador querría hacer esto. Aquí hay algunas ideas: * Para mostrar al usuario una lista de canciones y dejarlos seleccionar la música de fondo mientras usa tu aplicación. *Permitir al usuario descargar sus imágenes desde un servicio. (por ejemplo Flickr) y agregarlas a la biblioteca. * Usar música de un artista o género desde la biblioteca de medios para hacer sugerencias de otros contenidos similares en los que el usuario podría interesarse. Para mostrar como usar la biblioteca de medios, he creado una aplicación de ejemplo. Esta aplicación enlistará todas las canciones que se encuentren en la biblioteca multimedia del usuario, reproducir una canción cuando el usuario la seleccione y permitirle seleccionar una imagen [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/28/31-days-of-mango-day-28-media-library/">Esta es una traducción de Day 28: Media Library, puedes encontrar el artículo aquí en su versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia28.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="dia28" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia28_thumb.png" width="600" height="75" /></a></p>
<p>Hoy vamos a echar un vistazo a la clase MediaLibrary que es parte del espacio de nombres Microsoft.Xna.Framework.Media. Como el nombre sugiere, esta clase nos da acceso a la biblioteca de medios del usuario. Una biblioteca de medios en Windows Phone almacena imágenes y música. Al usar las biblioteca de medios, puedes integrar este contenido en tus propias aplicaciones. Hay muchas razones por las que un desarrollador querría hacer esto. Aquí hay algunas ideas:</p>
<p>* Para mostrar al usuario una lista de canciones y dejarlos seleccionar la música de fondo mientras usa tu aplicación.</p>
<p>*Permitir al usuario descargar sus imágenes desde un servicio. (por ejemplo Flickr) y agregarlas a la biblioteca.</p>
<p>* Usar música de un artista o género desde la biblioteca de medios para hacer sugerencias de otros contenidos similares en los que el usuario podría interesarse.</p>
<p>Para mostrar como usar la biblioteca de medios, he creado una aplicación de ejemplo. Esta aplicación enlistará todas las canciones que se encuentren en la biblioteca multimedia del usuario, reproducir una canción cuando el usuario la seleccione y permitirle seleccionar una imagen de la biblioteca para usarla como fondo de pantalla. La aplicación usa la biblioteca multimedia para obtener una lista de las canciones y también guarda una imagen a la biblioteca para el usuario.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0027.jpg"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="clip_image0027" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0027_thumb.jpg" width="227" height="422" /></a></p>
<p><strong><font size="5">Guardar la imagen a la biblioteca multimedia</font></strong></p>
<p>En la aplicación de ejemplo he agregado una imagen como recurso. Es una imagen genial y estoy seguro de que todos los usuarios van a quererla así que vamos a guardarla en la biblioteca de medios. La aplicación de ejemplo guarda esta imagen en el método Application_Launching en el archivo App.xaml.cs, aquí está el código para ello.</p>
<p>public static void GuardarImagenBiblioteca(string nombreImagen)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var biblioteca = new MediaLibrary();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var imagen = biblioteca.Pictures.Where(p =&gt; p.Name == nombreImagen).SingleOrDefault();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (imagen == null)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var recurso = Application.GetResourceStream(new Uri(string.Format(&#8220;/31DaysMediaLibrary;component/Images/{0}&#8221;,nombreImagen), UriKind.Relative));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var bitmap = new BitmapImage();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bitmap.SetSource(recurso.Stream);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; biblioteca.SavePicture(nombreImagen, bitmap.ToStream());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>La mayoría de este código esta simplemente trabajando al cargar una imagen. Hay algunas líneas importantes aquí que están usando la Biblioteca de medios. Vamos a ver mas de cerca esas líneas.</p>
<p>var biblioteca = new MediaLibrary();<br /> 
<p>Esta línea crea una nueva clase de tipo MediaLibrary. Esto es lo que te dará acceso a las propiedades y métodos de la biblioteca de medios.</p>
<p>var imagen = biblioteca.Pictures.Where(p =&gt; p.Name == nombreImagen).SingleOrDefault();</p>
<p>Esta línea busca en la biblioteca por cualquier imagen que este ya salvada con el nombre de la imagen. Si esta existe, el código no la guardará de nuevo.</p>
<p>biblioteca.SavePicture(nombreImagen, bitmap.ToStream());</p>
<p>Esta línea guarda el BitmapImage a la biblioteca. Quizá notes que un BitmapImage no tiene normalmente el método ToStream. Pienso que lo tendría utilizando un método extendido para agregarselo. La clase de extensión no tiene nada que hacer con la biblioteca multimedia, pero aquí verás como es que funciona.</p>
<p>public static class ExtensionBitmap<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static Stream ToStream(this BitmapImage bitmap)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var writeableBitmap = new WriteableBitmap(bitmap);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var stream = new MemoryStream();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeableBitmap.SaveJpeg(stream, bitmap.PixelWidth, bitmap.PixelHeight, 0, 100);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stream.Position = 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return stream;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }</p>
<p>Después de que el código ha sido ejecutado, la imagen estará disponible en la biblioteca de medios. Para mostrar esto en nuestra aplicación de ejemplo, puedes dar clic en el ícono del engrane en la bandeja de la aplicación y la nueva imagen estará disponible para ser seleccionada usando un PhotoChooserTask.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0046.jpg"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="clip_image0046" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0046_thumb.jpg" width="193" height="362" /></a></p>
<p><strong><font size="5">Obtener una lista de canciones</font></strong></p>
<p>En la aplicación de ejemplo la pantalla muestra una lista de las canciones que el usuario tiene en la biblioteca de medios. La lista es un ListBox. Un Data Template es definido y es el que enlaza la propiedad Text de los dos TextBlock. Uno despliega el título de la canción y el otro despliega al artista. Aquí esta lo como queda el XAML para el ListBox.</p>
<p>&lt;ListBox <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x:Name=&#8221;lstCanciones&#8221; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SelectionChanged=&#8221;lstCanciones_SelectionChanged&#8221;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ListBox.ItemTemplate&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;DataTemplate&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel Margin=&#8221;0,0,0,17&#8243; Width=&#8221;432&#8243; Height=&#8221;78&#8243;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock Text=&#8221;{Binding Name}&#8221; TextWrapping=&#8221;Wrap&#8221; Style=&#8221;{StaticResource PhoneTextExtraLargeStyle}&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock Text=&#8221;{Binding Artist.Name}&#8221; TextWrapping=&#8221;Wrap&#8221; Margin=&#8221;12,-6,12,0&#8243; Style=&#8221;{StaticResource PhoneTextSubtleStyle}&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/StackPanel&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/DataTemplate&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/ListBox.ItemTemplate&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/ListBox&gt;</p>
<p>Ajusta el ItemSource a la lista de canciones es bastante simple:</p>
<p>var biblioteca = new MediaLibrary();<br />lstCanciones.ItemsSource = biblioteca.Songs;</p>
<p><strong><font size="5">¿Qué mas hay ahí?</font></strong></p>
<p>Hay algunas otras propiedades de la clase MediaLibrary para considerar:</p>
<p><strong>Álbumes</strong> – Es similar a la colección de canciones, pero enlista en su lugar los álbumes</p>
<p><strong>Artistas</strong> – Así como la colección de álbumes, esta colección enlista a los artistas de las canciones.</p>
<p><strong>Genres</strong> – Esta colección enlista los géneros de las canciones.</p>
<p><strong>Playlists</strong> – Esta colección enlista las listas de reproducción que el usuario ha agregado a su biblioteca.</p>
<p><strong><font size="5">En resumen</font></strong></p>
<p>Como puedes ver, usar la Biblioteca de medios es bastante sencillo. La mayoría del código en la aplicación de ejemplo esta escrito para usar el contenido, no para acceder a el desde la biblioteca. Hablé acerca de acceder a la colección de canciones y como guardar una imagen en la biblioteca. Discutí unas pocas maneras de usar la biblioteca en tus propias aplicaciones. Estoy seguro que hay&nbsp; muchas mas formas&nbsp; de usar este contenido. Diviértete y no puedo esperar a ver tus aplicaciones.</p>
<p>Para descargar este ejemplo entero de la aplicación de Windows Phone usando los conceptos aquí mostrados, puedes hacerlo en el enlace siguiente.</p>
<p><a href="http://aminespinoza.com/materialBlog/31dias/Dia_28_MediaLibrary.zip">Puedes descargar el código aquí.</a></p>
<p>Mañana, cubriremos la globalización/localización en el artículo y te mostraremos que tan sencillo es incluir esto en tu proyecto Windows Phone. Nos vemos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-28-biblioteca-multimedia/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 27: API del micr&#243;fono</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-27-api-del-micrfono/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-27-api-del-micrfono/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 06:19:10 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/?p=3473</guid>
		<description><![CDATA[Esta es una traducción de Day 27:Microphone API, puedes encontrarlo aquí en su versión original en inglés. Introducción El reconocimiento de voz o tomar notas es una práctica muy común dependiendo de tu profesión o uso, por ejemplo, es entendido que los dispositivos móviles de hoy ofrecen alguna clase de reconocimiento de palabras y control de la aplicación, ya sean direcciones o marcar un número o el otro uso común, al reproducir música. La tarea de notas es otro elemento que es útil para ser capaz de capturar audio en el campo para futuras referencias. El primer paso de todas estas aplicaciones es ser capaz de capturar audio vía el micrófono y procesarlo como sea necesario. Así que hoy miraremos al API del microfono proveída por Mango y haremos un ejemplo muy sencillo para que inicies. ¿Qué es lo que esta involucrado? Haremos lo mínimo, necesitaremos grabar audio y salvarlo para su reproducción. Los siguientes puntos clave deberán ser notados: 1. Clase Microphone: Esta es la clase proveída por el espacio de nombres Microsoft.Xna.Framework.Audio que nos permite el acceso a la API del micrófono. 2. Evento publico EventHandler&#60;EventArgs&#62; BufferReady: Este es un evento que se manifiesta cuando el micrófono esta [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/27/31-days-of-mango-day-27-microphone-api/" target="_blank">Esta es una traducción de Day 27:Microphone API, puedes encontrarlo aquí en su versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia27.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia27_thumb.png" alt="dia27" width="600" height="75" border="0" /></a></p>
<p>Introducción</p>
<p>El reconocimiento de voz o tomar notas es una práctica muy común dependiendo de tu profesión o uso, por ejemplo, es entendido que los dispositivos móviles de hoy ofrecen alguna clase de reconocimiento de palabras y control de la aplicación, ya sean direcciones o marcar un número o el otro uso común, al reproducir música.</p>
<p>La tarea de notas es otro elemento que es útil para ser capaz de capturar audio en el campo para futuras referencias.</p>
<p>El primer paso de todas estas aplicaciones es ser capaz de capturar audio vía el micrófono y procesarlo como sea necesario.</p>
<p>Así que hoy miraremos al API del microfono proveída por Mango y haremos un ejemplo muy sencillo para que inicies.</p>
<p>¿Qué es lo que esta involucrado?</p>
<p>Haremos lo mínimo, necesitaremos grabar audio y salvarlo para su reproducción.</p>
<p>Los siguientes puntos clave deberán ser notados:</p>
<p>1. Clase Microphone: Esta es la clase proveída por el espacio de nombres Microsoft.Xna.Framework.Audio que nos permite el acceso a la API del micrófono.</p>
<p>2. Evento publico EventHandler&lt;EventArgs&gt; BufferReady: Este es un evento que se manifiesta cuando el micrófono esta listo para librerar el audio almacenado. Necesitamos manejar esta evento y almacenar el audio para una reproducción posterior.</p>
<p>3. Microphone.Start: Como el nombre indica, lo llamamos para iniciar la grabación.</p>
<p>4. Microphone.Stop: Lo llamamos para detener la grabación. Un punto importante para considerar es que al llamar a Microphone.Stop inmediatamente limpiara el buffer.</p>
<p>Como verás en la aplicación, no llamamos al método Stop inmediatamente cuando el usuario abra el micrófono o de clic en el botón de reproducir. En lugar de eso, dejamos al micrófono levantar el evento de BufferReady con la duración del buffer seleccionada para capturar hasta el último bit de información de audio antes de detener la grabación.</p>
<p>using Microsoft.Xna.Framework –&gt; Como debiste haber adivinado desde el espacio de nombres, requerimos una referencia al framework de Xna. El API del micrófono es parte del framework de XNA y requiere la simulación de juego de Xna. Si no estás familiarizado con XNA, XNA es un framework muy enriquecido proveido por Microsoft para aplicaciones destinadas para juegos y gráficas.</p>
<p><strong><span style="font-size: large">Entendiendo el ejemplo</span></strong></p>
<p><strong>Prerequisitos</strong>: Instala las herramientas de Mango <a href="http://create.msdn.com">http://create.msdn.com</a> , esto te dará el Windows Phone SDK y Visual Studio Express 2010 que necesitas para desarrollar aplicaciones para Windows Phone.</p>
<p>1. Lanza Visual Studio, navega a la solución y ábrela. La aplicación esta creada usando Silverlight for Windows Phone. Corre el proyecto y despliega la aplicación en el emulador. Verás la siguiente pantalla cuando la aplicación termine de cargar.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0023.jpg"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0023_thumb.jpg" alt="clip_image0023" width="259" height="430" border="0" /></a></p>
<p>2. El elemento de la pantalla:</p>
<p>a. El botón de micrófono es una palanca la cual comienza y detiene al micrófono.</p>
<p>b. El botón de reproducir es usado para escuchar el sonido guardado.</p>
<p>c. Hay tres sliders para ajustar el volumen, extracción y tono del sonido al ser reproducido.</p>
<p>3. Como funciona:</p>
<p>a. Toca el micrófono para iniciar la grabación. Puedes detener la grabación al tocar el micrófono de nuevo o alternativamente al tocar el botón de reproducir.</p>
<p>b. Ajusta el volumen, prueba el sonido al cambiar los valores de los sliders al reproducir el sonido.</p>
<p><strong><span style="font-size: large">Entendiendo el código</span></strong></p>
<p><strong>Aquí están las declaraciones iniciales:</strong></p>
<p>private Microphone microfono = Microphone.Default;<br />
private MemoryStream stream = new MemoryStream();<br />
private SoundEffectInstance sonidoGrabado;<br />
private byte[] buffer;<br />
bool estaReproduciendoSonido = false;<br />
string rutaImagenMicrofonoDetenido = &#8220;Imagenes/stopped.png&#8221;;<br />
string rutaImagenMicrofonoIniciado = &#8220;Imagenes/114px-Yeti-USB-Microphone.png&#8221;;<br />
string rutaImagenBotonPlayPausadoLight = &#8220;Imagenes/light.appbar.transport.pause.rest.png&#8221;;<br />
string rutaImagenBotonPlayPausadoDark = &#8220;Imagenes/dark.appbar.transport.pause.rest.png&#8221;;<br />
string rutaImagenBotonPlayLight = &#8220;Imagenes/light.appbar.transport.play.rest.png&#8221;;<br />
string rutaImagenBotonPlayDark = &#8220;Imagenes/dark.appbar.transport.play.rest.png&#8221;;<br />
bool grabacionDetenida = false;<br />
bool reproducirSonido = false;<br />
bool streamDesechado = false;<br />
bool esTemaOscuro = ((Visibility)Application.Current.Resources["PhoneDarkThemeVisibility"] == Visibility.Visible);</p>
<p>Estaremos usando un objeto de la clase SoundEffectInstance para reproducir el sonido grabado. Podríamos también haber usado un SoundEffect, sin embargo al usar la clase SoundEffectInstance nos permitirá rastrear el estado (reproduciendo o detenido).</p>
<p>La otra declaración aquí es para un objeto MemoryStream. El buffer del micrófono es constantemente escrito en un memorystream a menos que la reproducción sea deseada. En este momento, ingresamos el contenido del memorystream al objeto SoundEffectInstance para reproducir.</p>
<p><strong>Inicialización:</strong></p>
<p>public MainPage()<br />
{<br />
InitializeComponent();<br />
DispatcherTimer temporizador = new DispatcherTimer();<br />
temporizador.Interval = TimeSpan.FromMilliseconds(33);<br />
temporizador.Tick += new EventHandler(temporizador_Tick);<br />
temporizador.Start();<br />
AjustarMicrofono();<br />
SoundEffect.MasterVolume = 1.0f;<br />
AjustarImagenBotonReproducirBasadoEnTema();<br />
}</p>
<p>El punto principal para ver aquí es el ciclo que hemos creado usando un DispatcherTimer. Este ciclo es esencial para capturar el audio desde el micrófono.</p>
<p>Ajustamos la imagen para el botón de reproducir basado en el tipo de tema que esté seleccionado.</p>
<p>Hasta ahora también ajustamos los valores del micrófono para nuestra aplicación, como sigue:</p>
<p>private void AjustarMicrofono()<br />
{<br />
if (Microphone.Default == null)<br />
{<br />
return;<br />
}</p>
<p>microfono.BufferDuration = TimeSpan.FromMilliseconds(500);<br />
buffer = new byte[microfono.GetSampleSizeInBytes(microfono.BufferDuration)];<br />
stream.SetLength(0);</p>
<p>microfono.BufferReady += microfono_BufferReady;</p>
<p>ImageBrush pincel = new ImageBrush();<br />
pincel.ImageSource = new BitmapImage(new Uri(rutaImagenMicrofonoDetenido, UriKind.Relative));<br />
pincel.Stretch = Stretch.Uniform;<br />
btnGrabar.Background = pincel;<br />
}</p>
<p>La duración del buffer es de medio segundo y después usamos un método llamado GetSampleSizeInBytes y pasamos la duración del buffer para obtener el tamaño real de este. Esto es importante para asegurar una captura de audio fluida-</p>
<p>Enlazamos el evento de Buffer Ready y ajustamos la imagen preestablecida del micrófono detenido.</p>
<p>¡Estamos listos para comenzar a grabar!</p>
<p><strong>Grabar audio:</strong></p>
<p>Cuando el usuario de clic sobre el botón del micrófono, el siguiente código es llamado:</p>
<p>private void btnGrabar_Click(object sender, System.Windows.RoutedEventArgs e)<br />
{<br />
if (estaReproduciendoSonido)<br />
{<br />
return;<br />
}<br />
streamDesechado = false;</p>
<p>if (microfono.State == MicrophoneState.Stopped)<br />
{<br />
ImageBrush pincel = new ImageBrush();<br />
pincel.ImageSource = new BitmapImage(new Uri(rutaImagenMicrofonoIniciado, UriKind.Relative));<br />
pincel.Stretch = Stretch.Uniform;<br />
btnGrabar.Background = pincel;<br />
if (sonidoGrabado != null) sonidoGrabado.Stop();<br />
stream.SetLength(0);<br />
grabacionDetenida = false;<br />
microfono.Start();</p>
<p>}<br />
else if (microfono.State == MicrophoneState.Started)<br />
{<br />
grabacionDetenida = true;<br />
ImageBrush pincel = new ImageBrush();<br />
pincel.ImageSource = new BitmapImage(new Uri(rutaImagenMicrofonoDetenido, UriKind.Relative));<br />
pincel.Stretch = Stretch.Uniform;<br />
btnGrabar.Background = pincel;<br />
btnReproducir.IsEnabled = true;<br />
}</p>
<p>reproducirSonido = false;<br />
AjustarImagenBotonReproducirBasadoEnTema();<br />
estaReproduciendoSonido = false;<br />
}</p>
<p>Aquí suceden unas cosas:</p>
<p>1- El micrófono es detenido: Si el micrófono es detenido necesitamos comenzar a hacerlo grabar. Ajustamos el fondo del botón del micrófono. Después reiniciamos el MemoryStream para limpiar nuestro audio grabado previamente. Checamos  y detenemos el audio a reproducir.</p>
<p>Pasos muy sencillos de seguir. Ahora necesitamos llamar al método Microfono.Start(). El resto de los pasos están basados en la UI y diseño de la aplicación.</p>
<p>2. El micrófono esta grabando: Primero necesitamos detener la grabación. Si reactivas la nota de arriba, no podemos llamar al método Microfono.Stop() inmediatamente mientras que toda la información grabada no haya sido desechada del MemoryStream. Así que usamos variables booleanas para mantener un registro y diferir la acción de detener en el evento DispatchTimer.</p>
<p>Dos cosas necesitan pasar aquí. Primero, necesitamos dejar el buffer del micrófono listo para lanzar al inicio de modo que podamos leer el último bit del audio y después necesitamos lanzar la reproducción. Manejamos esto como se muestra.</p>
<p>void microfono_BufferReady(object sender, EventArgs e)<br />
{<br />
microfono.GetData(buffer);<br />
stream.Write(buffer, 0, buffer.Length);</p>
<p>if (grabacionDetenida)<br />
{<br />
stream.Flush();<br />
streamDesechado = true;<br />
microfono.Stop();<br />
}<br />
}</p>
<p>En el evento anterior, verificamos si la grabación ha sido detenida usando nuestras variables booleanas y después llamamos al método Stream.Flush(). Esto desecha la información restante del MemoryStream. Después detenemos el micrófono.</p>
<p>Sin embargo, no podemos lanzar la reproducción de audio en este evento, Esto es manejado por el “tick” del temporizador como se muestra en seguida:</p>
<p>void temporizador_Tick(object sender, EventArgs e)<br />
{<br />
try { FrameworkDispatcher.Update(); }<br />
catch (Exception ex)<br />
{<br />
throw ex;<br />
}</p>
<p>if (true == estaReproduciendoSonido)<br />
{<br />
if (sonidoGrabado.State != SoundState.Playing)<br />
{<br />
ResetearAjustesReproduccion();<br />
}<br />
}<br />
else<br />
{<br />
if (reproducirSonido &amp;&amp; streamDesechado)<br />
{<br />
reproducirSonido = false;<br />
if (stream.Length &gt; 0)<br />
{<br />
AjustarImagenBotonPausaBasadoEnTema();<br />
Thread hiloSonido = new Thread(new ThreadStart(iniciarReproduccion));<br />
hiloSonido.Start();<br />
}<br />
}<br />
}<br />
}</p>
<p>El evento es llamado cada 33 milisegundos. Así que estará bastante ajustado para que el usuario reproduzca el sonido sin ningún problema. La ventaja, por supuesto es que podemos reproducir el audio entero antes de dejar que sea cortado.</p>
<p>Checamos si es momento de grabar y ver si el stream ha sido desechado. Si es así, iniciamos un nuevo hilo para la reproducción de audio. Este es un punto importante para notar.</p>
<p>Estamos lanzando la reproducción de la cinta en un hilo diferente para permitir a la UI actualizarse. Esto significa que cualquier código dentro de nuestra rutina de reproducción que escoja actualizar los elementos de la interfaz tiene que hacerlo al llamar al DispatchBeginInvoke como se muestra abajo.</p>
<p><strong>Reproducir el audio</strong></p>
<p>private void iniciarReproduccion()<br />
{<br />
SoundEffect sonido = new SoundEffect(stream.ToArray(), microfono.SampleRate, AudioChannels.Mono);<br />
sonidoGrabado = sonido.CreateInstance();</p>
<p>estaReproduciendoSonido = true;<br />
Dispatcher.BeginInvoke(() =&gt;<br />
{<br />
sonidoGrabado.Pitch = (float)sldPitch.Value;<br />
sonidoGrabado.Pan = (float)sldPan.Value;<br />
sonidoGrabado.Volume = (float)sldVolumen.Value;<br />
}<br />
);<br />
sonidoGrabado.Play();<br />
}</p>
<p>Creamos un objeto de la clase SoundEffectInstance  alimentándolo del stream de audio capturado, el rango de ejemplo del micrófono y el canal de audio.</p>
<p>Dado que deseamos usar los sliders para ajustar el volumen, pitch y pan, tenemos que usar de nuevo un Dispatcher.BeginInvoke dado que ellos están en un hilo diferente.</p>
<p>Finalmente llamamos al botón reproducir.</p>
<p><strong><span style="font-size: large">En resumen</span></strong></p>
<p>Es bastante simple crear una aplicación que registre audio. Podemos extender esta aplicación para guardar el audio grabado en el almacenamiento aislado y darle un título elegido por el usuario. Podemos agregar una vista de lista de las grabaciones del almacenamiento aislado y hacer una pequeña aplicación de notas de voz.</p>
<p>Los pasos básicos de la grabación de audio son:</p>
<p>a)Enlaza un evento al micrófono preestablecido para capturar el audio.</p>
<p>b)Escribe el audio en un stream</p>
<p>c)Cuando el usuario detenga la grabación, desecha el stream y almacénalo o reprodúcelo.</p>
<p>Podemos también extender esta aplicación tomando el audio grabado y mandándolo a un servicio de traducción y capturar comandos.</p>
<p>Para descargar este ejemplo entero de la aplicación de Windows Phone usando los conceptos aquí mostrados, puedes hacerlo en el enlace siguiente.</p>
<p><a href="http://aminespinoza.com/materialBlog/31dias/Dia_27_Microfono.zip">Puedes descargar el código aquí.</a></p>
<p>Mañana Jeff Fansler estará cubriendo la clase MediaLibrary y como podemos usarla para aprender mas acerca de la librería de música del usuario en su teléfono. Nos vemos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-27-api-del-micrfono/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 26: Transferencia de archivos en segundo plano</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-26-transferencia-de-archivos-en-segundo-plano/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-26-transferencia-de-archivos-en-segundo-plano/#comments</comments>
		<pubDate>Tue, 27 Dec 2011 05:29:30 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/?p=3467</guid>
		<description><![CDATA[Esta es una traducción de Day 26: Background File Transfer, puedes encontrarlo aquí en su versión original en inglés. Ayer creamos un proyecto usando un Background Agent, uno de los nuevos elementos multitarea nuevos en Windows Phone 7.5. Hoy usaremos el Background File Transfer para realizar la descarga de un archivo que continua incluso cuando nuestra aplicación no esté corriendo. Descargaremos un video desde Channel 9 y lo reproduciremos cuando esté completado. Comenzando Lanza Visual Studio y crea un nuevo proyecto. Debajo de Silverlight for Windows Phone, selecciona Windows Phone Application. Nombra la aplicación como gustes. Has creado la aplicación principal. Será responsable para: 1) Iniciar nuestra descarga del video 2) Desplegar el estado de la descarga 3) Reproducir el video una vez que se haya completado Crear la aplicación Ahora es tiempo de juntarlo todo. Abre MainPage.xaml y agrega dos botones para descargar y reproducir el video. Después, agrega dos TextBlocks para desplegar el progreso y estado. &#60;Grid x:Name=&#8221;ContentPanel&#8221; Grid.Row=&#8221;1&#8243; Margin=&#8221;12,0,12,0&#8243;&#62;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#60;Button x:Name=&#8221;btnIniciar&#8221; Click=&#8221;btnIniciar_Click&#8221; Content=&#8221;Iniciar descarga&#8221; Margin=&#8221;0,101,0,0&#8243; VerticalAlignment=&#8221;Top&#8221;/&#62;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#60;Button x:Name=&#8221;btnReproducir&#8221; Click=&#8221;btnReproducir_Click&#8221; IsEnabled=&#8221;False&#8221; Content=&#8221;Reproducir video&#8221; Margin=&#8221;0,225,0,0&#8243; VerticalAlignment=&#8221;Top&#8221;/&#62;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#60;TextBlock x:Name=&#8221;txtProgreso&#8221; Margin=&#8221;8,0,8,258&#8243; VerticalAlignment=&#8221;Bottom&#8221;/&#62;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#60;TextBlock x:Name=&#8221;txtEstado&#8221; Margin=&#8221;8,0,8,159&#8243; VerticalAlignment=&#8221;Bottom&#8221; Height=&#8221;0&#8243;/&#62;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#60;/Grid&#62; No incluiré el MainPage.xaml entero aquí, pero está disponible en la solución al [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/26/31-days-of-mango-day-26-background-file-transfer/">Esta es una traducción de Day 26: Background File Transfer, puedes encontrarlo aquí en su versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia26.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="dia26" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia26_thumb.png" width="600" height="75" /></a></p>
<p>Ayer creamos un proyecto usando un Background Agent, uno de los nuevos elementos multitarea nuevos en Windows Phone 7.5. Hoy usaremos el <strong>Background File Transfer</strong> para realizar la descarga de un archivo que continua incluso cuando nuestra aplicación no esté corriendo. Descargaremos un video desde <a href="http://channel9.msdn.com/">Channel 9</a> y lo reproduciremos cuando esté completado.</p>
<p>Comenzando</p>
<p>Lanza Visual Studio y crea un nuevo proyecto. Debajo de Silverlight for Windows Phone, selecciona Windows Phone Application. Nombra la aplicación como gustes.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image002_thumb3.jpg"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="clip_image002_thumb3" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image002_thumb3_thumb.jpg" width="508" height="309" /></a></p>
<p>Has creado la aplicación principal. Será responsable para:</p>
<p>1) Iniciar nuestra descarga del video</p>
<p>2) Desplegar el estado de la descarga</p>
<p>3) Reproducir el video una vez que se haya completado</p>
<p>Crear la aplicación</p>
<p>Ahora es tiempo de juntarlo todo. Abre MainPage.xaml y agrega dos botones para descargar y reproducir el video. Después, agrega dos TextBlocks para desplegar el progreso y estado.</p>
<p>&lt;Grid x:Name=&#8221;ContentPanel&#8221; Grid.Row=&#8221;1&#8243; Margin=&#8221;12,0,12,0&#8243;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Button x:Name=&#8221;btnIniciar&#8221; Click=&#8221;btnIniciar_Click&#8221; Content=&#8221;Iniciar descarga&#8221; Margin=&#8221;0,101,0,0&#8243; VerticalAlignment=&#8221;Top&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Button x:Name=&#8221;btnReproducir&#8221; Click=&#8221;btnReproducir_Click&#8221; IsEnabled=&#8221;False&#8221; Content=&#8221;Reproducir video&#8221; Margin=&#8221;0,225,0,0&#8243; VerticalAlignment=&#8221;Top&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock x:Name=&#8221;txtProgreso&#8221; Margin=&#8221;8,0,8,258&#8243; VerticalAlignment=&#8221;Bottom&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock x:Name=&#8221;txtEstado&#8221; Margin=&#8221;8,0,8,159&#8243; VerticalAlignment=&#8221;Bottom&#8221; Height=&#8221;0&#8243;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/Grid&gt;</p>
<p>No incluiré el MainPage.xaml entero aquí, pero está disponible en la solución al final. Primero, definimos algunas variables para mantener la ubicación de nuestro video a descargar, la ubicación donde guardaremos el video y la taza de transferencia actual.</p>
<p>private const String ubicacionArchivo = &#8220;shared/transfers/MiVideoDescargado.mp4&#8243;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Uri direccionVideoDescarga = new Uri(&#8220;http://video.ch9.ms/ch9/02df/0a2774a9-a010-4b9b-b654-9f88014102df/xboxCompanion_med_ch9.mp4&#8243;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Uri direccionGuardarArchivo = new Uri(ubicacionArchivo, UriKind.RelativeOrAbsolute);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private BackgroundTransferRequest solicitudActual = null;</p>
<p>Nota que cuando se descarga directamente al Almacenamiento Aislado, todas las descargas deben ir hacía shared/transfers/. Estaremos descargando un video desde Channel9 y guardarlo como “MiVideoDescargado.mp4”.</p>
<p>Cuando un usuario da clic en “Iniciar descarga”, crearemos un nuevo BackgroundTransferRequest y le diremos lo que queremos descargar y donde queremos guardar lo descargado. De forma preestablecida, una descarga puedes solo ser realizada cuando el dispositivo esta conectado y tiene una conexión Wi-Fi. Ajustamos esto con <b>BackgroundTransferRequest.TransferPreferences</b> a <strong>AllowCellularAndBattery. </strong>Finalmente, agregamos nuestra solicitud al <strong>BackgroundTransferService</strong>.</p>
<p>solicitudActual = new BackgroundTransferRequest(direccionVideoDescarga, direccionGuardarArchivo);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; solicitudActual.TransferPreferences = TransferPreferences.AllowCellularAndBattery;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BackgroundTransferService.Add(solicitudActual);</p>
<p>También necesitamos ser notificados del estado de la solicitud y el progreso para mostrarlo en nuestra UI. Podemos suscribirnos a los cambios manejando los eventos <strong>TransferProgressChanged</strong> y <strong>TransferStatusChanged.</strong></p>
<p>if (solicitudActual != null)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; solicitudActual.TransferProgressChanged += solicitudActual_TransferProgressChanged;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; solicitudActual.TransferStatusChanged += solicitudActual_TransferStatusChanged;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>Cuando somos notificados por ese eventos, podemos checar muchas propiedades en nuestro BackgroundTransferRequest para ver el estado actual de la descarga:</p>
<p>* <strong>BytesReceived / TotalBytesToReceive</strong> para el progreso de la descarga</p>
<p>* <strong>BytesSent / TotalBytesToSend</strong> para el progreso de una carga</p>
<p>* <strong>TransferStatus </strong>para el estado actual de la descarga (transferencia, completado, etc.)</p>
<p>* <strong>TransferError</strong> para información acerca de un archivo transferido</p>
<p>Nota que no importa si la transferencia fue exitosa, <strong>TransferStatus</strong> lo reportara a <strong>Completed</strong> cuando termine. Debido a esto, una vez que <strong>TransferStatus</strong> reporte su estado a <strong>Completed</strong>, deberías checar <strong>TransferError</strong> para ver si un error ocurrió.</p>
<p>Cuando la transferencia este completada, deberías removerlo del BackgroundTransferService:</p>
<p>BackgroundTransferService.Remove(solicitudActual);</p>
<p>Finalmente, uno de los aspectos mas truculentos de implementar un background file transfer, es lidiar con el cierre de tu aplicación. Cuando reingreses a la aplicación, necesitamos que nuestro estado siga cargando, incluso cuando solicitudActual vaya a ser nula y nuestros eventos no estén mas entrelazados. Para lidiar con esto, reseteamos nuestra solicitudActual y enlazamos los eventos en <strong>OnNavigatedTo</strong>:</p>
<p>protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; base.OnNavigatedTo(e);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (BackgroundTransferRequest solicitud in BackgroundTransferService.Requests)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; solicitudActual = solicitud;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IniciarSolicitudParaTransferencia();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IniciarManejadoresParaTransferencia();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RefrescarDireccionTransferencia();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>Ya funcional, este ejemplo es bastante simple. Es recomendado que también cheques <a href="http://msdn.microsoft.com/en-us/library/hh202955(v=VS.92).aspx">la vista general del Background File Transfer</a> en MSDN para una mas completa referencia. </p>
<p><strong><font size="5">Correr la aplicación</font></strong></p>
<p>Nota que nuestra aplicación esta lista para correr, despliégala en el emulado o en un dispositivo y ejecútala. Da clic en “Iniciar descarga” y deberás ver el progreso de la descarga reportado:</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0032.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="clip_image0032" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0032_thumb.png" width="335" height="190" /></a></p>
<p>Presiona el botón de “Iniciar” y deja a la aplicación. Espera un poco y después reingresa a la aplicación. Deberás ver que el progreso de la descarga ha continuado incluso cuando la aplicación no estaba corriendo. Una vez que el estado este completado, puedes dar clic en “Ver video” para ver el video que fue descargado.</p>
<p><strong><font size="5">En resumen</font></strong></p>
<p>Hoy creamos un BackgroundTransferRequest que descarga un video. Cuando se hace la solicitud de transferencia por tu cuenta, ten en cuenta que cubrimos.</p>
<p>* Iniciar un BackgroundTransferRequest y agregalo al BackgroundTransferService para iniciar una carga o descarga.</p>
<p>* Guarda las descargas en share/transfers al guardar en el Almacenamiento Aislado.</p>
<p>* Maneja la BackgroundTransferRequest. TransferProgressChanged y BackgroundTransferRequest. Los eventos TransferStatusChanged son notificados de cambios en el estado de transferencia.</p>
<p>* Cuando BackgroundTransferRequest y TransferStatus este completo, recuerda checar BackgroundTransferRequest y TransferError para ver si la transferencia fue exitosa.</p>
<p>* Manejar escenarios donde el usuario deje y regrese a la aplicación.</p>
<p>Para descargar este ejemplo entero de la aplicación de Windows Phone usando los conceptos aquí mostrados, puedes hacerlo en el enlace siguiente.</p>
<p><a href="http://aminespinoza.com/materialBlog/31dias/Dia_26_TransferenciaArchivos.zip">Puedes descargar el código aquí.</a></p>
<p>Mañana. Parag Joshi esta de vuelta para discutir la API del micrófono y como podemos usarla para capturar audio desde un dispositivo Windows Phone. Nos vemos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-26-transferencia-de-archivos-en-segundo-plano/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://video.ch9.ms/ch9/02df/0a2774a9-a010-4b9b-b654-9f88014102df/xboxCompanion_med_ch9.mp4" length="38056162" type="video/mp4" />
		</item>
		<item>
		<title>D&#237;a 25: Background agents</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-25-background-agents/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-25-background-agents/#comments</comments>
		<pubDate>Mon, 26 Dec 2011 03:42:57 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/?p=3459</guid>
		<description><![CDATA[Esta es una traducción de Day 25: Background Agents, puedes encontrarlo aquí en su versión original en inglés. Hoy, vamos a darle un vistazo a una de las capacidades multitarea nuevas en Windows Phone Mango. El entorno completo de multitarea abarca muchos nuevos elementos: * Background Agents * Background File Transfer * Background Audio Playback * Scheduled Notifications * Fast Application Switching Aquí nos enfocaremos en los Background Agents. Mientras que la transferencia de archivos y tarea de reproducción de audio cubren escenarios específicos, no permiten un código personalizado para ser ejecutados. Aquí es donde entran los agentes en segundo plano. Hay dos tipos de agentes de segundo plano: Periodic y Resource Intensive. Los agentes de recursos intensivos están hechos para tareas que consumirán un monto grande de recursos del sistema pero con muchas limitaciones para cuando ellos quieran correr. Los agentes periódicos corren mas frecuentemente y con menos restricciones, pero están hechos para tareas que sean ligeras en consumo de recursos. Para entender completamente las diferentes limitantes y beneficios de cada uno,visita la página de MSDN. Una tarea periódica puede hacer algo corto y simple, así como refrescar un RSS o actualizar tu live tile. Una tarea exigente de [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/25/31-days-of-mango-day-25-background-agents/">Esta es una traducción de Day 25: Background Agents, puedes encontrarlo aquí en su versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia25.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="dia25" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia25_thumb.png" width="600" height="75" /></a></p>
<p>Hoy, vamos a darle un vistazo a una de las capacidades multitarea nuevas en Windows Phone Mango. El entorno completo de multitarea abarca muchos nuevos elementos:</p>
<p>* Background Agents</p>
<p>* Background File Transfer</p>
<p>* Background Audio Playback</p>
<p>* Scheduled Notifications</p>
<p>* Fast Application Switching</p>
<p>Aquí nos enfocaremos en los Background Agents. Mientras que la transferencia de archivos y tarea de reproducción de audio cubren escenarios específicos, no permiten un código personalizado para ser ejecutados. Aquí es donde entran los agentes en segundo plano.</p>
<p>Hay dos tipos de agentes de segundo plano: <strong>Periodic</strong> y <strong>Resource Intensive</strong>. Los agentes de recursos intensivos están hechos para tareas que consumirán un monto grande de recursos del sistema pero con muchas limitaciones para cuando ellos quieran correr. Los agentes periódicos corren mas frecuentemente y con menos restricciones, pero están hechos para tareas que sean ligeras en consumo de recursos. Para entender completamente las diferentes limitantes y beneficios de cada uno,<a href="http://msdn.microsoft.com/en-us/library/hh202942(v=VS.92).aspx">visita la página de MSDN.</a></p>
<p>Una tarea periódica puede hacer algo corto y simple, así como refrescar un RSS o actualizar tu live tile. Una tarea exigente de recursos puede hacer algo que requiera mas tiempo y ancho de banda, como sincronizar o atrapar grandes montos de datos desde un servicio en la nube.</p>
<p>Vamos a hacer un agente periódico que actualizará el live tile de tu aplicación con el último momento en el que nuestra tarea personalizada se ejecutó.</p>
<p><strong><font size="5">Comenzando</font></strong></p>
<p>Lanza Visual Studio 2010 y crea un nuevo proyecto. Debajo de Silverlight for Windows Phone, selecciona Windows Phone Application.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0021.jpg"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="clip_image0021" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0021_thumb.jpg" width="452" height="245" /></a></p>
<p>Ya has creado la aplicación principal. Esta será responsable de dos cosas:</p>
<p>1) Tener un live tile que el agente de segundo plano puede actualizar con información</p>
<p>2) Iniciar y detener el agente de segundo plano</p>
<p>El agente de segundo plano por sí mismo, debe vivir en su proyectos propio especial. Agrega un nuevo proyecto a tu solución, seleccionando Windows Phone Scheduled Task Agent. Nómbralo MiAgente. Este proyecto contendrá el código personalizado que correrá en segundo plano y actualizará el live tile.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0042.jpg"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="clip_image0042" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0042_thumb.jpg" width="452" height="245" /></a></p>
<p>Finalmente, y esto es importante, ve a tu proyecto principal y agrega una referencia a MiAgente. Esto automáticamente te permitirá registrar tu agente desde dentro de la aplicación. También nota esta entrada automáticamente creada en el WMAppManifest.xml:</p>
<p>&lt;Tasks&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;DefaultTask Name=&#8221;_default&#8221; NavigationPage=&#8221;MainPage.xaml&#8221; /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ExtendedTask Name=&#8221;BackgroundTask&#8221;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;BackgroundServiceAgent Specifier=&#8221;ScheduledTaskAgent&#8221; Name=&#8221;MiAgente&#8221; Source=&#8221;MiAgente&#8221; Type=&#8221;MiAgente.ScheduledAgent&#8221; /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/ExtendedTask&gt;<br />&lt;/Tasks&gt;</p>
<p><strong><font size="5">Crear la aplicación</font></strong></p>
<p>Ahora es tiempo de juntarlo todo. Abre el MainPage.xaml y agrega dos botones, uno para iniciar el agente y el otro para detenerlo.</p>
<p>&lt;Grid x:Name=&#8221;ContentPanel&#8221; Grid.Row=&#8221;1&#8243; Margin=&#8221;12,0,12,0&#8243;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Button x:Name=&#8221;btnIniciar&#8221; Content=&#8221;Iniciar agente&#8221; Height=&#8221;90&#8243; Margin=&#8221;8,53,8,0&#8243; VerticalAlignment=&#8221;Top&#8221; Click=&#8221;btnIniciar_Click&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Button x:Name=&#8221;btnDetener&#8221; Content=&#8221;Detener agente&#8221; Height=&#8221;90&#8243; Margin=&#8221;8,147,8,0&#8243; VerticalAlignment=&#8221;Top&#8221; Click=&#8221;btnDetener_Click&#8221;/&gt;<br />&lt;/Grid&gt;</p>
<p>En el archivo MainPage.xaml.cs enlaza los botones para iniciar y detener al agente</p>
<p>using Microsoft.Phone.Controls;<br />using Microsoft.Phone.Scheduler;<br />using System;</p>
<p>namespace Dia_25_Agentes<br />{<br />&nbsp;&nbsp;&nbsp; public partial class MainPage : PhoneApplicationPage<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private const string nombreTarea = &#8220;MiAgente&#8221;;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public MainPage()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitializeComponent();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void btnIniciar_Click(object sender, System.Windows.RoutedEventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IniciarAgente();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void btnDetener_Click(object sender, System.Windows.RoutedEventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DetenerAgenteSiIniciado();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void IniciarAgente()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DetenerAgenteSiIniciado();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PeriodicTask tarea = new PeriodicTask(nombreTarea);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tarea.Description = &#8220;Este es un agente personalizado para el ejemplo&#8221;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ScheduledActionService.Add(tarea);<br />#if DEBUG<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Si estamos depurando, intentar iniciar la tarea inmediatamente<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ScheduledActionService.LaunchForTest(nombreTarea, new TimeSpan(0, 0, 1));<br />#endif<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void DetenerAgenteSiIniciado()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ScheduledActionService.Find(nombreTarea) != null)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ScheduledActionService.Remove(nombreTarea);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />}</p>
<p>Nota que al crear nuestro agente personalizado, estamos creando una nueva <strong>PeriodicTask</strong>. Usamos entonces el nombre como identificador al encontrar y detener al agente. Nota también que especificamos <strong>PeriodicTask.Description</strong> (es un campo requerido y aparecerá en <strong>Settings | Background Tasks</strong> debajo del nombre de nuestra aplicación).</p>
<p>Crear el agente de segundo plano</p>
<p>En el proyecto MiAgente, abre ScheduledAgent.cs y agrega el siguiente código:</p>
<p>protected override void OnInvoke(ScheduledTask task)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ActualizarTileAplicacion(ObtenerUltimoMensajeDeActualizacion());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private string ObtenerUltimoMensajeDeActualizacion()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return string.Format(&#8220;Ultima: {0}&#8221;, DateTime.Now);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void ActualizarTileAplicacion(string message)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ShellTile appTile = ShellTile.ActiveTiles.First();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (appTile != null)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StandardTileData tileData = new StandardTileData<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BackContent = message<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; appTile.Update(tileData);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />La clase ScheduledAgent tiene un método sobrecargado importante <strong>OnInvoke</strong>. Aquí es donde tu agente ejecutará su tarea en segundo plano. Si tu tarea esta completada y no necesitas mas a tu agente para ejecutarse, puedes llamar al método <strong>NotifyComplete()</strong> para verificar que la tarea ha sido satisfactoriamente completada o <strong>Abort()</strong> para verificar que estás cancelando la tarea. Para mantener la tarea corriendo a un intervalo, simplemente no llames a ninguno, que es lo que estamos haciendo aquí.</p>
<p><strong><font size="5">Correr la aplicación</font></strong></p>
<p>Ahora que nuestra aplicación esta lista para ejecutarse, despliégala en el emulador o en un dispositivo. Da un clic para iniciar el agente de segundo plano. Deja a la aplicación y regresa a la lista de aplicaciones. Presiona y mantente sobre la aplicación, escoge “anclar a inicio”. Cuando veas el tile en tu página de inicio deberías eventualmente ver a la aplicación girar, revelando la última vez que fue actualizada.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image005.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="clip_image005" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image005_thumb.png" width="337" height="173" /></a></p>
<p><strong><font size="5">En resumen</font></strong></p>
<p>Así que hoy creamos nuestro propio Background Agent personalizado que actualiza un live tile. Cuando hagas los tuyos por tu cuenta mantén en cuenta que cubrimos:</p>
<p>* Los agentes de segundo plano te permiten ejecutar código personalizado mientras tu aplicación no está corriendo.</p>
<p>* Hay dos tipos de agentes de segundo plano – periódico y de recursos intensivos.</p>
<p>* Las tareas periódicas son para tareas que tienen bajo consumo de recursos, y como resultado tienen menos restricciones que las tareas de recursos intensivos.</p>
<p>* Los agentes de segundo plano necesitan su propio proyecto, el cual debería ser agregado como una referencia de proyecto a la aplicación que iniciará el agente.</p>
<p>* En tu agente necesitas el método sobrecargado OnInvoke()</p>
<p>* Cuando tu tarea esté completa necesitas llamar a NotifyComplete() o Abort()</p>
<p>Para descargar este ejemplo entero de la aplicación de Windows Phone usando los conceptos aquí mostrados, puedes hacerlo en el enlace siguiente.</p>
<p><a href="http://aminespinoza.com/materialBlog/31dias/Dia_25_Agentes.zip">Puedes descargar el código aquí.</a></p>
<p>Mañana vamos a mirar a otro elemento multitarea llamado <strong>Background File Transfer</strong> que nos permitirá descargar o subir archivos mientras que nuestra aplicación no esté corriendo. Nos vemos</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-25-background-agents/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 24: Herramienta de rendimiento</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-24-herramienta-de-rendimiento/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-24-herramienta-de-rendimiento/#comments</comments>
		<pubDate>Sat, 24 Dec 2011 22:08:48 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/?p=3449</guid>
		<description><![CDATA[Esta es una traducción de Day 24: Performance Tools, puedes encontrarlo aquí en su versión original en inglés. El rendimiento es un aspecto importante para todas la aplicaciones, especialmente aplicaciones que corren con necesidad de recursos abundantes, los dispositivos confían en la red. Como un usuario, es relativamente fácil decir cuando una aplicación en ejecución es “lenta”; lo que no es fácil es identificar la causa de los problemas de rendimiento. Hacer cambios al código fuente sin entender el efecto en rendimiento puede llevarte a una reconstrucción innecesaria y hacer los problemas potenciales incluso peores. ¿Qué hacer? Con el lanzamiento de Windows Phone Mango, podemos ahora fácilmente identificar el origen de los problemas de rendimiento de nuestra aplicación (todo el camino hacia las funciones que están causando los problemas). Ingresa a la herramienta de perfil. Puedes usar la nueva herramienta para ayudar a identificar detalles con el rendimiento en tu aplicación, incluyendo consumo de memoria, complejidad en los árboles visuales, tiempo de lanzamiento de la aplicación e identificación de funciones de larga duración. Para correr la sesión de análisis de rendimiento, abre tu proyecto Windows Phone en Visual Studio y selecciona “Stat Windows Phone Performance Analysis” desde el menú de [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/24/31-days-of-mango-day-24-performance-analysis/">Esta es una traducción de Day 24: Performance Tools, puedes encontrarlo aquí en su versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia24.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="dia24" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia24_thumb.png" width="600" height="75" /></a></p>
<p>El rendimiento es un aspecto importante para todas la aplicaciones, especialmente aplicaciones que corren con necesidad de recursos abundantes, los dispositivos confían en la red. Como un usuario, es relativamente fácil decir cuando una aplicación en ejecución es “lenta”; lo que no es fácil es identificar la causa de los problemas de rendimiento. Hacer cambios al código fuente sin entender el efecto en rendimiento puede llevarte a una reconstrucción innecesaria y hacer los problemas potenciales incluso peores.</p>
<p>¿Qué hacer? Con el lanzamiento de Windows Phone Mango, podemos ahora fácilmente identificar el origen de los problemas de rendimiento de nuestra aplicación (todo el camino hacia las funciones que están causando los problemas). Ingresa a la herramienta de perfil. Puedes usar la nueva herramienta para ayudar a identificar detalles con el rendimiento en tu aplicación, incluyendo consumo de memoria, complejidad en los árboles visuales, tiempo de lanzamiento de la aplicación e identificación de funciones de larga duración. </p>
<p>Para correr la sesión de análisis de rendimiento, abre tu proyecto Windows Phone en Visual Studio y selecciona “Stat Windows Phone Performance Analysis” desde el menú de depuración o presiona el atajo de teclas ALT-F1.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb2.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="image_thumb2" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb2_thumb.png" width="273" height="232" /></a></p>
<p>Asegúrate de que estás lanzando el perfilador de Windows Phone y no el perfilador de .NET, el cual también esta encontrado en el menú “Debug”, listado como “Start performance analysis (ALT-F2)”.</p>
<p>Esta primera cosa que verás es una página preguntándote que selecciones el tipo de análisis que quieras hacer. A menos que sepas específicamente que hay un problema de consumo de memoria, deberás comenzar con el análisis de Ejecución:</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb1111.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="image_thumb111" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb111_thumb.png" width="306" height="171" /></a></p>
<p>Al dar clic en el enlace de “Launch Application” comenzará inmediatamente tu aplicación ya sea en el emulador o en el dispositivo con todo el monitoreo de código agregado a tu sesión. Una vez que la aplicación haya comenzado, navega por toda ella ejercitando esos elementos en tu aplicación que son las mas críticas de rendimiento o los que van a ser frecuentemente usados por tus usuarios. Así como pongas tu aplicación por sus fases, el monitoreo de información será automáticamente coleccionado y registrado por Visual Studio para una revisión posterior.</p>
<p>Una vea que tu sesión de pruebas este completa, regresa a Visual Studio y selecciona el enlace de “Stop Profiling”.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb12.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="image_thumb12" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb12_thumb.png" width="164" height="240" /></a></p>
<p>Hasta ahora, Visual Studio guardará toda la información de rendimiento en un archivo .SAP y agregará ese archivo a tu proyecto. Este archivo será anclado a tu proyecto, así como la fecha y hora de la prueba de ejecución (por ejemplo, DatabaseForMango_2011_11_14_17_59_27.sap”. Este registro puede ser revisado ahora, o guardado para una revisión posterior. La vista principal de los resultados esta ajustada a las gráficas que son elaboradas. Estas gráficas representan un número de medidas diferentes que están apiladas en la cima de cada una para dar una vista de tipo “timeline” del rendimiento de tus aplicaciones.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb51.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="image_thumb51" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb51_thumb.png" width="304" height="151" /></a></p>
<p>Empezando desde la cima, estas gráficas muestran</p>
<p>* <strong>Frame Rate</strong>: Esto muestra el rango de cuadros registrados para cada uno registrado en la UI. Los números aquí son potenciales focos de problemas que advierten para mayor investigación.</p>
<p>* <strong>CPU Usage</strong>: Muestra el consumo del CPU durante diferentes partes de la aplicación.</p>
<p>-<em> Las barras verdes representan el hilo de la UI</em> – Uno al cual vigilar mucho dado que el alto uso del hilo de la UI causa a esta que de vuelva poco responsiva al ingreso de datos del usuario. Cualquier valor superior a 50% es un problema potencial en el área.</p>
<p>- <em>Las barras azules representan los hilos de la aplicación</em> – Esto incluye a los hilos de segundo plano creados por el usuario y el hilo de composición (mas alto es mejor, comparado con el hilo de la UI)</p>
<p>-<em> Las barras grises representan los hilos del sistema</em> – Estos son hilos que&nbsp; NO son parte de tu aplicación, pero representan cosas como tareas de segundo plano, etc.</p>
<p>- <em>Las barras blancas representan los hilos desocupados</em> – Como el “proceso inactivo del sistema” mostrado en el administrador de tareas de Windows, esto representa el porcentaje del CPU disponible. Un número mayor significará una UI mas responsiva.</p>
<p>* <strong>Uso de memoria en MB</strong>: Vigila esto si tienes mas de 90 MB en cualquiera y corre la prueba siguiente – 90 MB es el límite para pasar la certificación para pasar al Marketplace.</p>
<p>* Animaciones: Una S es desplegada en cada cuadro donde una animación es lanzada.</p>
<p>- Rojo representa una animación enlazada a CPU (estas son malas dado que corren en el hilo del CPU e impactan directamente el rendimiento de la UI)</p>
<p>- Morado representa una animación enlazada a GPU (estas son buenas dado que corren en el hilo del Compositor y no afectan el rendimiento de la UI).</p>
<p>* Image Loads: Una “I” se mostrará para mostrar el cuadro para indicar cuando es cargada una imagen en la memoria.</p>
<p>* Eventos de colección de basura: Una “G” se mostrará para indicar un punto en el cual el colector de basura este corriendo.</p>
<p>Para ver los detalles de la información que esta alimentando la gráfica simplemente usa el puntero para seleccionar la región de la gráfica conteniendo estos cuadros que después quieres filtrar. La sección mas baja, referida como sección de Detailed Performance Analysis, poblará con mensajes de Advertencia e Información que resalte áreas de interés para los cuadros seleccionados.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb3.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="image_thumb3" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb3_thumb.png" width="322" height="203" /></a></p>
<p>Desde esta imagen, puedes ver que dos advertencias específicas son llamadas relacionadas al rango de problemas. Por ejemplo – la primer advertencia en la imagen superior contiene la siguiente información:</p>
<p>Advertencia: Una velocidad muy baja potencialmente causado por un costo de diseño alto.</p>
<p>El tiempo de diseño total (0.35 segundos) es alto. El elemento System.Windows.Controls.ScrollViewer : ScrollViewer tomó la mayoría de tiempo en diseño y esta contribuyendo a una baja velocidad de marcos. Esto puede ser porque las animaciones enlazadas al CPU estan causando actualizaciones de diseño. Ve al menú de Advertencias de Rendimiento en la barra de navegación y selecciona la vista de marcos. Navega entre los cuadros al dando clic en el encabezado de la columna de tiempo del CPU y selecciona los marcos con el mayor tiempo de CPU. Desde la vista de marcos, selecciona la opción Visual Tree e identifica System.Windows.Controls.ScrollViewer : ScrollViewer en el arbol.</p>
<p>La advertencia llama a un bajo nivel de marcos basados en como está construido el diseño relativo al ScrollViewer. La acción sugiere que deberíamos ir al menú de advertencia de rendimiento y seleccionar la vista de cuadros. Si miras mas de cerca a la sección de Rendimiento Detallado, verás que el texto derecho a las advertencias de rendimiento es un botón que controla un menú desplegable conteniendo muchas opciones debajo de ella en la cual podemos ir hacía abajo para mas información. Si escoges la opción “Frames”, verás algo como esto.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb41.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="image_thumb41" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb41_thumb.png" width="379" height="158" /></a></p>
<p>Esta lista de marcos seleccionados muestra que muchos de ellos tienen un uso de CPU cercano al 50% (¡en este caso es incluso cercano al 80%!). Al seleccionar ese marco y yendo de regreso al menú de navegación a un lado del elemento de marcos desde antes, muestra que aún hay mas niveles de detalle al cual podemos ir para un marco en particular. Selecciona cada uno de los elementos para obtener mas información acerca de que es lo que esta pasando con un elemento en particular. Mirar a los elementos así como a la opción “Functions” te permitirá ver que métodos están llamados en tu aplicación y proveerá los enlaces de vuelta a tu código fuente de esos métodos desde la aplicación que están siendo ejecutados. Puedes igualmente el Árbol visual, tipos de elementos y actualizaciones de cache. Estos mensajes de error, combinados con la guía correcta dada en donde mirar por problemas y la habilidad de la herramienta para que puedas ir hacia la raíz te da una gran vista en tu aplicación para descubrir problemas potenciales problemas y arreglarlos antes de enviar tu aplicación al Marketplace para su certificación.</p>
<p>Ahora que hemos visto como trabaja la herramienta, aquí hay un par de tips para usar lo que te ayudará al hacer tu aplicación mas veloz.</p>
<p>* Inicia con las pruebas de Ejecución de rendimiento para ver si hay algunos detalles con la memoria, como se indicó en la gráfica de consumo de memoria. Si descubres lugares donde tu aplicación está consumiendo cerca de 90 MB de memoria, corre una segunda prueba enfocándote específicamente en los ajustes de memoria. Normalmente encontrarás que los detalles de rendimiento pueden ser diagnosticados con esta primera prueba, así que solo usa la segunda prueba cuando los problemas de memoria se hayan superado.</p>
<p>* No olvides probar el FAS, Tombstoning y los correspondientes procesos de activación – todos estos sin partes importantes de tu aplicación-. Para forzar el Tombstoning en tu aplicación cuando presionas el botón de inicio, ve a las propiedades de tu proyecto debajo de la tabla Debug y selecciona “Tombstone upon deactivation while debugging”. De otra forma, tu aplicación se irá de manera pre establecida a FAS.</p>
<p>* Siempre prueba el rendimiento en un dispositivo – el rendimiento de tu laptop no se comparará con el rendimiento de tu dispositivo. Esto nos hace recordar la frase de “no vamos a instalar esta aplicación en tu laptop”. El dispositivo Windows Phone es mucho mas reducido de recursos que la típica estación de trabajo para desarrollo, así que la memoria y rendimiento estarán mas adaptados en el dispositivo que en el emulador. Correr estas pruebas en el dispositivo funciona de la misma forma que la depuración tradicional en el dispositivo (solo cambia el objeto de pruebas de “Windows Phone Emulator” a “Windows Phone Device” en la barra de herramientas estándar de Visual Studio).</p>
<p>En resumen</p>
<p>Aquí hay algunos enlaces para recursos adicionales en el análisis de rendimiento de Windwos Phone:</p>
<p>* <a href="http://msdn.microsoft.com/en-us/library/hh202934%28v=VS.92%29.aspx">Windows Phone Performance Analysis</a></p>
<p>* <a href="http://msdn.microsoft.com/en-us/library/hh202935%28v=VS.92%29.aspx">How to: Capture and Analyze Performance Data Using Windows Phone Performance Analysis</a></p>
<p>* <a href="http://msdn.microsoft.com/en-us/library/hh202932%28v=VS.92%29.aspx">How to: Identify and Fix Common Performance Issues Using Windows Phone Performance Analysis</a></p>
<p>Mañana, Gary Johnson estará escribiendo acerca de los agentes de segundo plano, y como podemos utilizar este nuevo elemento de Windows Phone 7.5 para ejecutar código cuando nuestra aplicación no esta corriendo. Nos vemos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-24-herramienta-de-rendimiento/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 23: Modelo de ejecuci&#243;n</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-23-modelo-de-ejecucin/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-23-modelo-de-ejecucin/#comments</comments>
		<pubDate>Sat, 24 Dec 2011 00:55:22 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/?p=3433</guid>
		<description><![CDATA[Esta es una traducción de Day 23: Execution Model, puedes encontrarlo aquí en su versión original en inglés. Vamos poniéndonos de acuerdo, nuestros smartphones son bastante inteligentes estos días. Pero los correos electrónicos, integración social, juegos y aplicaciones toman un buen tajo comparativamente del pequeño sistema de procesamiento y memoria, pero aún mas importante, la vida de la batería. Es además crucial para cualquier sistema operativo móvil y sus aplicaciones de terceros ser muy responsable al optimizar el uso de recursos en un smartphone, así como proveer la experiencia de usuario mas fluida y responsable posible. Aquí es donde el Execution Model viene en la jugada y se vuelve importante para entender en los varios eventos/estados durante el ciclo de vida de una aplicación. En este artículo hablaremos de como se ve el modelo de ejecución para Windows Phone y que ha cambiado con el lanzamiento de Mango para los consumidores y desarrolladores. La manera de Windows Phone Mientras hablamos de las varias partes de Windows Phone y sus aplicaciones de terceros todo el día, el teléfono toma un muy bien definido enfoque para administrar el ciclo de vida de una aplicación desde su lanzamiento hasta su finalización. El modelo [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/23/31-days-of-mango-day-23-execution-model/">Esta es una traducción de Day 23: Execution Model, puedes encontrarlo aquí en su versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia23.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="dia23" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia23_thumb.png" width="600" height="75" /></a></p>
<p>Vamos poniéndonos de acuerdo, nuestros smartphones son bastante inteligentes estos días. Pero los correos electrónicos, integración social, juegos y aplicaciones toman un buen tajo comparativamente del pequeño sistema de procesamiento y memoria, pero aún mas importante, la vida de la batería. Es además crucial para cualquier sistema operativo móvil y sus aplicaciones de terceros ser muy responsable al optimizar el uso de recursos en un smartphone, así como proveer la experiencia de usuario mas fluida y responsable posible. Aquí es donde el Execution Model viene en la jugada y se vuelve importante para entender en los varios eventos/estados durante el ciclo de vida de una aplicación. En este artículo hablaremos de como se ve el modelo de ejecución para Windows Phone y que ha cambiado con el lanzamiento de Mango para los consumidores y desarrolladores.</p>
<p>La manera de Windows Phone</p>
<p>Mientras hablamos de las varias partes de Windows Phone y sus aplicaciones de terceros todo el día, el teléfono toma un muy bien definido enfoque para administrar el ciclo de vida de una aplicación desde su lanzamiento hasta su finalización. El modelo de ejecución simplemente permite solo una aplicación para correr en primer plano a la vez. Dado que debemos ver como es benéfico esto para la experiencia de usuario, déjame jugar al abogado del diablo y discutir lo contrario. Sin embargo, incluso si esto fuera posible ¿Puedes realmente poder ver varias aplicaciones correr lado a lado en primer plano en un Windows Phone? ¿No puede ser el tamaño de la pantalla demasiado limitado para tratar de hacer esto? El enfocarse en una aplicación en primer plano simplemente tiene sentido para el factor del teléfono y compromete al usuario en una experiencia envolvente. Aquí es donde llega el estado real con el cual jugar, de forma similar los sistemas operativos Metro permiten a múltiples aplicaciones ancladas trabajando lado a lado en el primer plano, como en las vistas de Windows 8. Pero no estoy de acuerdo.</p>
<p>Así, esta decisión de una aplicación en el primer plano tiene implicaciones en el ciclo de vida de una aplicación. La mayoría de los usuarios de Windows Phone están acostumbrados a moverse entre aplicaciones de terceros y el SO por si mismo por medio del uso de los botones Inicio/Volver, mensajes o tiles. Cada aplicación Windows Phone para por varias fases, cada una exponiendo eventos, mientras pasamos por el tiempo de la aplicación en primer plano. Los detalles a continuación.</p>
<p>Los estados de la aplicación</p>
<p>En esencia, cada aplicación de Windows Phone para por los siguientes estados:</p>
<p>* <strong>Running</strong> &#8211; Este es el tiempo principal en primer plano para cualquier aplicación. El SO y el usuario le dan toda la atención a lo que hace.</p>
<p>* <strong>Dormant</strong> – Es el momento en el que una aplicación se retira del primer plano e inmediatamente se va a un estado “dormido”. Esta es una nueva mejora en Windows Phone Mango, donde toda la aplicación con su estado e historia son mantenidos intactos en la memoria. El objetivo aquí satisfacer las supremas responsabilidades de las aplicaciones en resumen, el cual es haber salido del primer plano, en caso de que el usuario quiera regresar a la aplicación. Esto es a lo que llamamos <em>Fast Application Switching</em> (FAS) en Windows Phone Mango.</p>
<p>¿Quieres intentarlo? Bien, sin mas que decir, necesitas un Windows Phone corriendo Mango o el emulador mas actual. Salta entre diferentes partes&nbsp; del SO o aplicaciones de terceros y luego presiona el botón de Regreso y ¡voila! Verás algo como esto ¿Lo ves?</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/FAS.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="FAS" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/FAS_thumb.png" width="193" height="351" /></a></p>
<p>Lo que estás viendo es el conjunto de aplicaciones en segundo plano, como una especie de pantallazo de las están en el estado Dormant, listas para regresar al primer plano en cuanto las selecciones. Para el consumidor, esto es multi tarea. Para ti como desarrollador, esto es FAS, una reactivación de la aplicación rápida sin que tengas que hacer nada. Bueno excepto por recompilar tus aplicaciones pre Mango usando el último SDK (7.1) de Windows Phone. Esto inmediatamente tiene dos efectos, tu aplicación no muestra el viejo mensaje de “Cargando..” si regresa al primer plano desde el estado en espera y también verás una captura de pantalla de la aplicación. Deberíamos ver un poco de código de prisa.</p>
<p>* <strong>Tombstoned</strong> &#8211; Ahora, como vimos, el runtime de Windows Phone mantiene en la memoria las aplicaciones en hibernación que han estado recientemente en primer plano. Mientras el resumen instantáneo es genial, pero cualquier smartphone tiene disponibilidad de memoria y el SO puede necesitar soporte para realizar alguna operación grande. Adivina que es lo que pasa. Si, las aplicaciones pasan de segundo plano&nbsp; a un modo de “Último en entrar, primero en salir”. En otras palabras, son desechadas y considerada para no estar consumiendo ningún recurso del sistema mas allá de ese punto. El último estado es no es técnicamente verdad, como lo veremos en un minuto.</p>
<p>Así que ¿cómo afecta el Tombstoning al ciclo de vida de una aplicación? Bueno, si el usuario ha estado usando tu aplicación, y después se va a algún juego que sea exigente de recursos, hay una oportunidad de que eventualmente tu aplicación sea desechada para liberar un poco de memoria para consumo del sistema. Sin embargo, el usuario debería decidir atravesar para llegar de nuevo a tu aplicación después de un tiempo. ¿Cómo se debería comportar tu aplicación? ¿Podemos recordar las cosas que el usuario tenía cuando dejó nuestra aplicación?</p>
<p>La respuesta es SI. Podemos darle absolutamente al usuario la experiencia que pudo venir de regresar como si nunca hubiera dejado tu aplicación y comenzar desde donde se quedó. Para lograr este efecto, sin embargo, necesita que nosotros, lo desarrolladores compartamos alguna responsabilidad para administrar el estado de nuestra aplicación a través de todo su ciclo de vida. En el código que sigue, veremos como podemos “hidratar” el estado de nuestra aplicación fuera del Tombstone, para darle al usuario final la impresión de que la aplicación nunca fue desechada. La verdad es que incluso cuando una aplicación es desechada algo de su información (como un diccionario) acerca del estado de la aplicación&nbsp; es preservado en memoria por el Sistema Operativo.</p>
<p>* <strong>Terminated</strong> – Una aplicación en este estado no tiene&nbsp; ninguna huella en la memoria del SO. Nada, incluyendo diccionarios de estado, de lo cual hablaremos mas tarde, no es preservado y ningún uso subsecuente de la aplicación resultará en una instancia fresca. Una aplicación alcanza este estado después de que ha sido desechada, el usuario navegó de regreso desde la primera página o una excepción no manejada ha matado a la aplicación.</p>
<p>Páginas y Eventos</p>
<p>Antes de movernos en el ciclo de vida de los eventos de la aplicación, vamos a dar un pequeño paso atrás para asegurarnos que nuestros fundamentos están correctos. Todas las aplicaciones Silverlight para Windows Phone corren en una colección de páginas XAML que son cargadas dentro del marco de Windows Phone. Mientras que la aplicación este en primer plan, el usuario es libre de navegar entre páginas dentro de la aplicación. Al presionar el botón de volver, hará que se regrese a la página anterior dentro de la aplicación, hasta que la primera página de la aplicación sea alcanzada y presionarlo ahí hará salir de la aplicación. Nosotros como desarrolladores, no necesitamos hacer nada para hacer que esto pase, mientras que el SO se preocupe de esto automáticamente durante el tiempo principal de la aplicación en primer plano.</p>
<p>Pero considera esto, un usuario esta escribiendo algo de contenido en un control de texto en una página XAML, se distrae y mueve de nuestra aplicación para realizar alguna operación. Cuando vuelve, dos cosas podrán haber pasado. Una, la aplicación pudo haber solo dormido y regresar justo con lo que el usuario estaba escribiendo, aquí no hay nada que tu aplicación necesite hacer para soportar esto, excepto por checar por una API para asegurarse de que tu aplicación estaba “dormida”. En segundo lugar, tu aplicación quizá haya sido desechada y ahora tienes un pequeño problema. Necesitas traer de vuelta a tu aplicación e hidratar el estado del XAML exactamente como el usuario la dejó. Esto es lo que veremos en el código.</p>
<p>Ahora que estamos hablando de los estados de las páginas, es un buen momento para hablar acerca de dos eventos durante el lapso de vida de una página</p>
<p>*<strong>OnNavigatedTo</strong> – Este evento se dispara cuando la página esta siendo llamada al primer plano para ser desplegada. Esto nos da a los desarrolladores una oportunidad para leer cadenas de consulta pasadas a la página para alimentar a los controles apropiadamente si viene desde Tombstoning.</p>
<p>*<strong>OnNavigatedFrom </strong>– Este evento se dispara cuando el usuario esta abandonando la página presente para ir hacia otra página dentro de la aplicación o dejando la aplicación completa. En cualquier caso, esto sirve como un buen punto para guardar cualquier información del estado para la página actual, en caso de la restauración quizá sea necesario en el futuro. Veremos estos ejemplos en código.</p>
<p><strong><font size="5">Diccionarios de datos y estados</font></strong></p>
<p>Ahora, demos un vistazo a que tipo de información estamos tratando de preservar y alimentar durante nuestro modelo de ejecución de la aplicación. En mi opinión, la información de Windows Phone es de dos tipos.</p>
<p>* <strong>Settings and Permanent Data</strong>&nbsp; &#8211; Este tipo de información es la cruz de tu aplicación y necesita ser mantenida mientras la aplicación este corriendo. No debemos gastar tiempo en guardar tal información en el almacenamiento aislado, así como archivos/carpetas, o en SQL CE si la información es relacional.</p>
<p>* <strong>Page and Transient Data</strong> – Esta es prescindible, pero conveniente para guardar información y es la que mejor puede lidiar con la memoria. Este tipo de información podría ser de cualquier tipo abarcando desde información si guardar por el usuario en una página, cualquier VistaModelo o algo de información temporal para el ciclo de vida de nuestra aplicación obtenida desde fuera. Esta es la información que necesitamos manejar cuidadosamente para dar a los usuarios finales la impresión de que nuestra aplicación esta viva y lista par continuar con su ciclo de vida. Ahora tenemos un poco de ayuda. Windows Phone expone un diccionario para cada aplicación y cada página de la aplicación puede ser usada para almacenar un par de información de tipo Key-Value. Este diccionario de estado esta fuera del PhoneApplicationService y debería ser solo usado para almacenar información de estado transitoria. No deberías usar esta propiedad para almacenamiento excesivo porque existe un límite de 2 MB para cada página y 4 MB para la aplicación entera; pero como veremos en el código, es muy útil al mantener el estado durante el modelo de ejecución de la aplicación. Y en esos diccionarios que son mantenidos por el SO incluso después de que la aplicación ha sido desechada. Si la aplicación es reactivada desde Tombstoning, este diccionario de estado será poblado con la información que guardamos en el durante la desactivación de la aplicación, Dado que esta información está presente en memoria, podemos utilizarla para recuperar el estado sin operaciones de archivos que demanden muchos recursos.</p>
<p><strong><font size="5">Eventos de la aplicación</font></strong> </p>
<p>Ahora que conocemos todos los detalles y la forma de trabajar desde dentro, vamos a ver lo que necesitamos hacer durante el ciclo de vida de una aplicación. El PhoneApplicactionService se enfoca en cuatro eventos primarios durante el modelo de ejecución de la aplicación que nos ayuda a administrar el estado:</p>
<p>*<strong>Launching</strong> – Este evento es alcanzado cuando una nueva instancia de la aplicación es creada por alguna acción del usuario como seleccionarla de la lista, seleccionar el Tile o cualquier otro medio, En este caso, comenzamos con un nuevo inicio y no con la continuación de cualquier aplicación pasada.</p>
<p>*<strong>Deactivated</strong> – Este evento es alcanzado cuando el usuario navega fuera de nuestra aplicación o un Chooser es lanzado. Esta es la mejor oportunidad para nosotros de guardar el estado de la aplicación en el diccionario de estado para su uso futuro al regresar a la aplicación. Si se regresa del estado dormido, esto no sería necesario, pero lo es absolutamente si se regresa desde Tombstoning y el evento es el único chance que tendremos de guardar el estado de la aplicación.</p>
<p>*<strong>Activated</strong> – Este evento es lanzado cuando la aplicación está regresando del segundo plano, de cualquier modo. Y adivina, una simple llamada a la API por medio de <strong><em>IsApplicationInstancePreserved</em></strong>&nbsp; y sus argumentos nos dirán desde que modo nuestra aplicación ha regresado. Si la bandera es verdadera, nuestra aplicación viene desde el estado Dormant, y fue mantenida en la memoria. Así que no es necesaria ninguna acción y FAS lo hace todo. Si la bandera es falsa, estamos regresando desde el Tombstone y usaríamos el diccionario de estado para recuperar el estado de la aplicación.</p>
<p>* <strong>Closing</strong> – Este evento es lanzado cuando el usuario atraviesa por medio de las páginas, llega a la página principal y sale de ella. En este punto, la aplicación debió haber salido del primer plano y se habrá terminado a sí misma después de alcanzar un evento. No se preserva ningún estado de información al terminar y cualquier lanzamiento subsecuente de la aplicación resultará en una nueva instancia.</p>
<p>Como un tema común, las tareas intensivas con altos recursos deberían ser evitadas durante cualquiera de los eventos anteriores, dado que tenemos un lapso de tiempo limitado (diez segundos para ser exacto) para que el SO espere por nuestros métodos para finalizar. Para una mejor experiencia de usuario, algunas de las operaciones de mantenimiento deberán ser realizadas en hilos de segundo plano mientras la aplicación esté corriendo.</p>
<p>Si quieres que tenga sentido toda esta información. Solo dale un vistazo al diagrama general del modelo de ejecución para Windows Phone, mejor descrito en el artículo de MSDN:</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/Execution-Model.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="Execution-Model" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/Execution-Model_thumb.png" width="383" height="487" /></a></p>
<p>[Cortesía MSDN]</p>
<p><strong><font size="5">Aplicación de prueba</font></strong></p>
<p>Hemos estado con mucha plática hasta ahora, ¿no es así? Vamos a ver algo de código. Vamos a crear una aplicación Windows Phone simple que resalte la administración de estados a través de todo el ciclo de vida de la aplicación. La aplicación entera y construida esta disponible para su descarga al final del artículo, solo asegúrate de que tienes el SDK de Windows Phone 7.1, y ¡Presiona F5!</p>
<p>Así que comencemos, Archivo &gt; Nuevo y aceptamos la plantilla mas básica para una aplicación con una sola página XAML únicamente, siendo esta MainPage.xaml.cs. Vamos a abrir la página XAML y arrastrar algunos controles para nuestro uso. El resultado final debe ser algo como esto.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/XAML-Page_thumb.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="XAML-Page_thumb" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/XAML-Page_thumb_thumb.png" width="445" height="243" /></a></p>
<p>Aquí está el objetivo, vamos a utilizar los controles para administrar los stados de varios tipos de información como se describe abajo.</p>
<p>*<strong>AppSetting</strong> – Este es un ejemplo de un nivel de aplicación que debe persistir a través de las instancias de la aplicación. El ejemplo más común podría ser el ajuste de un usuario para tu aplicación.</p>
<p>* <strong>App Transient Data</strong> – Este conjunto de controles simulará el nivel de información de la aplicación que es solo aplicable por instancia, pero puede ser utilizable en múltiples páginas XAML durante toda la aplicación. El mejor ejemplo sería alguna información de un servicio web que una aplicación busque cada vez que inicia.</p>
<p>*<strong> Page Transient Data</strong> – Este conjunto de controles&nbsp; permanece para el control de página específico que probablemente no queramos perder si el usuario sale de nuestra aplicación y vuelve de regreso desde el segundo plano.</p>
<p>Vamos a manejar cada tipo de información de forma separada. Así vamos a comenzar con el archivo App.xaml.cs (el lugar para manejar información global de la aplicación). Vamos a agregar unas propiedades así como un poco de código en el Constructor.</p>
<p>public PhoneApplicationFrame RootFrame { get; private set; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public bool AjustesApp { get; set; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public string InfoApp { get; set; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static new App Current<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get { return Application.Current as App; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public App()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UnhandledException += Application_UnhandledException;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitializeComponent();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitializePhoneApplication();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InfoApp = string.Empty;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (System.Diagnostics.Debugger.IsAttached)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Application.Current.Host.Settings.EnableFrameRateCounter = true;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (IsolatedStorageSettings.ApplicationSettings.Contains(&#8220;AppSetting&#8221;))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AjustesApp = (bool)IsolatedStorageSettings.ApplicationSettings["AppSetting"];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>Después, vamos a agregar algo de código a los manejadores de eventos de la aplicación. Nota el uso de la bandera IsApplicationInstancePreserved para decidir si estamos viniendo de los estados Dormant o Tombstoning en el manejador de eventos Activated. Ahora, no tuve una buena razón para agregrar ningún código especial a los manejadores de Launching y Closing de la aplicación, pero sientete libre de hacerlo si tu aplicación necesita ese código. También, nota el uso del diccionario Stat del PhoneApplicationService:</p>
<p>private void Application_Activated(object sender, ActivatedEventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (e.IsApplicationInstancePreserved)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Regresar desde Dormancy.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Regresar desde Tombstone.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (PhoneApplicationService.Current.State.ContainsKey(&#8220;AppData&#8221;))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InfoApp = PhoneApplicationService.Current.State["AppData"].ToString();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void Application_Deactivated(object sender, DeactivatedEventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PhoneApplicationService.Current.State["AppData"] = InfoApp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>Ahora, de vuelta a nuestro MainPage.xaml.cs, vamos a agregar los manejadores de eventos para el evento de cargando y el clic del botón para buscar algo de información (la cual creamos nosotros) así como el cambio de estado del CheckBox. Nota como mantenemos la información encontrada en nivel de la aplicación y también como guardamos inmediatamente los ajustes del usuario/aplicación en el almacenamiento aislado del teléfono.</p>
<p>private void chkAjusteAplicacion_Tap(object sender, System.Windows.Input.GestureEventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (IsolatedStorageSettings.ApplicationSettings.Contains(&#8220;AppSetting&#8221;))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IsolatedStorageSettings.ApplicationSettings.Remove(&#8220;AppSetting&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((bool)this.chkAjusteAplicacion.IsChecked)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IsolatedStorageSettings.ApplicationSettings.Add(&#8220;AppSetting&#8221;, true);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IsolatedStorageSettings.ApplicationSettings.Add(&#8220;AppSetting&#8221;, false);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void btnBuscar_Click(object sender, System.Windows.RoutedEventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; txtInfoApp.Text = &#8220;Esta es alguna información de ejemplo&#8230;&#8221;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; App.Current.InfoApp = txtInfoApp.Text;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void PhoneApplicationPage_Loaded(object sender, System.Windows.RoutedEventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chkAjustePagina.IsChecked = App.Current.AjustesApp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>Ahora, vamos a agregar los importantes eventos para la navegación de páginas. Aquí es donde obtenemos control de como alimentar la información mientras la página XAML viene a primer plano y te mueves fuera de ella.</p>
<p>protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; base.OnNavigatedTo(e);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (App.Current.InfoApp != null &amp;&amp; App.Current.InfoApp != string.Empty)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; txtInfoApp.Text = App.Current.InfoApp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (PhoneApplicationService.Current.State.ContainsKey(&#8220;PageData&#8221;))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; txtInfoPagina.Text = PhoneApplicationService.Current.State["PageData"].ToString();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (PhoneApplicationService.Current.State.ContainsKey(&#8220;PageSetting&#8221;))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chkAjustePagina.IsChecked = (bool)PhoneApplicationService.Current.State["PageSetting"];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; base.OnNavigatedFrom(e);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (PhoneApplicationService.Current.State.ContainsKey(&#8220;PageData&#8221;))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PhoneApplicationService.Current.State.Remove(&#8220;PageData&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (PhoneApplicationService.Current.State.ContainsKey(&#8220;PageSetting&#8221;))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PhoneApplicationService.Current.State.Remove(&#8220;PageSetting&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PhoneApplicationService.Current.State["PageData"] = txtInfoApp.Text;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PhoneApplicationService.Current.State["PageSetting"] = chkAjustePagina.IsChecked;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>¡Eso es todo! Hemos agregado el suficiente código de modo que los diferentes tipos de información sean administrados a través del ciclo de vida de la aplicación, cada una en una forma diferente y apropiada. Ahora dale una probada. Inicia la aplicación, has los cambios necesarios, ve a alguna otra aplicación y de regreso o salte y corre una instancia fresca de la aplicación. La información y el estado deberían ser preservadas como se espera. Una ejecución típica con los ajustes necesarios deberá verse así:</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/App-and-Page-State_thumb.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="App-and-Page-State_thumb" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/App-and-Page-State_thumb_thumb.png" width="196" height="356" /></a></p>
<p>Ahora, quizá notes una cosa, en ambos, en el emulador o en el teléfono que mientras navegamos por la aplicación, nos salimos y después regresamos en el runtime de Windows Phone Mango, es difícil predecir cuando la aplicación sea desechada. En la mayoría de los casos, si es desactivada, la aplicación simplemente queda en estado dormido y vuelve a la vida. Así que a menos que que configuremos a la aplicación para ir directo a Tombstoning, no hay una forma definitiva de probar esto.</p>
<p>¡No te preocupes! Hay un simple valor de depuración que forzará el tombstone en tu aplicación al momento en que sea desactivada. Así que incluso si la aplicación puede estar en estado dormido, este parámetro, mostrado abajo, la forzara a ir al Tombstone. Esto obviamente ayudará a nuestras pruebas.</p>
<p>En Resumen</p>
<p>Agregando puntos de interrupción a varios manejadores de eventos y viendo cuando se disparan durante el ciclo de vida de la aplicación, es una forma genial de entender el modelo de ejecución. Así que ¿Qué esperas? Ve y has uso completo de FAS y como alimentar a tu aplicación de forma correcta durante cualquier etapa de ella.</p>
<p>Resultado, usuarios felices y tu más feliz ¡Adios!</p>
<p>Para descargar este ejemplo entero de la aplicación de Windows Phone usando los conceptos aquí mostrados, puedes hacerlo en el enlace siguiente. </p>
<p><a href="http://aminespinoza.com/materialBlog/31dias/Dia_24_ModeloEjecucion.zip">Puedes descargar el código aquí.</a> </p>
<p>Mañana, Chris Koeing va a hablar acerca de otra genial herramienta disponible para nosotros en Visual Studio 2010, la herramienta de análisis de rendimiento de Silverlight. Nos vemos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-23-modelo-de-ejecucin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 22: App Connect</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-22-app-connect/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-22-app-connect/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 01:30:20 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/?p=3418</guid>
		<description><![CDATA[Esta es una traducción de Day 22: App Connect, puedes encontrarlo aquí en su versión original en inglés. ¿Qué es App Connect? Windows Phone Mango introduce una multitud de mejoras fantásticas al ya genial sistema operativo Windows Phone. Además de estas, hay un número de mejoras al motor de búsqueda de Bing en el teléfono. Mientas que muchos de esos elementos como búsqueda visual dirección paso a paso están hechos para los usuarios, Microsoft también introdujo unos cuantos elementos que permitan a los desarrolladores integrar aplicaciones en los resultados de búsquedas ya sea vía respuestas instantáneas, una forma de resaltar aplicaciones relevantes para búsquedas específicas, o vía un nuevo elemento en Mango llamado Quick Cards. Quick Cards son elementos que aparecen en cuertas búsquedas que permiten a los usuarios encontrar mas acerca de cierto productos, ubicaciones o películas dentro de Bing. En la imagen de abajo se muestra un ejemplo de resultados de búsqueda que incluyen Quick Cards para muchos libros que coincidan con la búsqueda del usuario. Al dar clic en alguno de esos elementos navegarás hacía la Quick Card del producto la cual te permite encontrar mas información de un producto centralizado en la localización como se muestra [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/22/31-days-of-mango-day-22-app-connect/">Esta es una traducción de Day 22: App Connect, puedes encontrarlo aquí en su versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia22.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia22_thumb.png" alt="dia22" width="600" height="75" border="0" /></a></p>
<p><span style="font-size: large"><strong>¿Qué es App Connect?</strong></span></p>
<p>Windows Phone Mango introduce una multitud de mejoras fantásticas al ya genial sistema operativo Windows Phone. Además de estas, hay un número de mejoras al motor de búsqueda de Bing en el teléfono. Mientas que muchos de esos elementos como búsqueda visual dirección paso a paso están hechos para los usuarios, Microsoft también introdujo unos cuantos elementos que permitan a los desarrolladores integrar aplicaciones en los resultados de búsquedas ya sea vía respuestas instantáneas, una forma de resaltar aplicaciones relevantes para búsquedas específicas, o vía un nuevo elemento en Mango llamado Quick Cards.</p>
<p>Quick Cards son elementos que aparecen en cuertas búsquedas que permiten a los usuarios encontrar mas acerca de cierto productos, ubicaciones o películas dentro de Bing. En la imagen de abajo se muestra un ejemplo de resultados de búsqueda que incluyen Quick Cards para muchos libros que coincidan con la búsqueda del usuario.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image002.jpg"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image002_thumb.jpg" alt="clip_image002" width="214" height="390" border="0" /></a></p>
<p>Al dar clic en alguno de esos elementos navegarás hacía la Quick Card del producto la cual te permite encontrar mas información de un producto centralizado en la localización como se muestra abajo.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0041.jpg"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image0041_thumb.jpg" alt="clip_image0041" width="209" height="380" border="0" /></a></p>
<p>App Connect es otro nuevo elemento en Windows Phone Mango que permite a las aplicaciones ser enlistadas en las elementos de las Quick Cards que son relevantes para cuestiones de una búsqueda. Desde aquí, el usuario puede dar clic y lanzar la aplicación y tener la experiencia que viene de la Quick Card personalizada desde la cual el usuario llegó.</p>
<p>Es importante notar que hasta ahora solo los Estados Unidos soportan Quick Cards de productos y películas, pero también mencionar que paulatinamente ser irá extendiendo. Sin considerar esta limitación actual, también veremos el texto de resultados de las búsquedas localizadas.</p>
<p>Checa <a title="http://msdn.microsoft.com/en-us/library/hh202957%28v=VS.92%29.aspx#BKMK_AppConnect" href="http://msdn.microsoft.com/en-us/library/hh202957%28v=VS.92%29.aspx#BKMK_AppConnect">http://msdn.microsoft.com/en-us/library/hh202957%28v=VS.92%29.aspx#BKMK_AppConnect</a> para una lista mas detallada y actualizada de los tipos de Quick Cards que están soportadas.</p>
<p>Similares a las Quick Cards, los desarrolladores pueden también hacer que sus aplicaciones estén al pendiente de los escenarios donde son ejecutadas como por Bing Instant Answers, otra mejora de Mango a la búsqueda de Bing. Bing Instant Answers permite a Bing resaltar ciertas aplicaciones que considere son relevantes para una búsqueda específica.</p>
<p>Para este artículo estaremos creando una aplicación que te permita rápidamente buscar un libro para un sitio de ventas en línea tomando ventaja de la integración de búsquedas de Quick Cards para libros, revistas y dando una experiencia personalizada si fue lanzada desde Bing Instant Answers.</p>
<p><strong><span style="font-size: large">Comenzar con la extensión de búsqueda</span></strong></p>
<p>Ajustar tu aplicación para tomar ventaja de App Connect es relativamente fácil a pesar de que hay un número de pasos que necesitarás seguir para hacer funcionar las cosas.</p>
<p>Comenzaremos creando un nuevo proyecto de Windows Phone Application en la opción de Windows Phone 7.1.</p>
<p><strong><span style="font-size: large">Registrar extensiones de búsqueda</span></strong></p>
<p>Para que Windows Phone sepa que tu aplicación soporta App Connect, necesitas agregar una entrada al archivo de manifiesto diciendo al teléfono que la aplicación soporte la extensión de búsqueda. Esto es importante y debería incluir los tipos de producto relevantes para tu aplicación.</p>
<p>Expande el nodo de propiedades del archivo de proyectos y ve a WMAppManifest.xml. Este es el manifiesto de la aplicación del teléfono para el Marketplace y define toda la información relevante de tu aplicación. Necesitarás agregar un nuevo nodo dentro del elemento App ilustrado en el siguiente archivo.</p>
<p>&lt;Deployment xmlns=&#8221;<a href="http://schemas.microsoft.com/windowsphone/2009/deployment&quot;">http://schemas.microsoft.com/windowsphone/2009/deployment&#8221;</a> AppPlatformVersion=&#8221;7.1&#8243;&gt;<br />
&lt;App xmlns=&#8221;" ProductID=&#8221;{b8d10135-ffd2-48e0-852d-42a55e277b37}&#8221; Title=&#8221;Dia_22_AppConnect&#8221; RuntimeType=&#8221;Silverlight&#8221; Version=&#8221;1.0.0.0&#8243; Genre=&#8221;apps.normal&#8221;  Author=&#8221;Dia_22_AppConnect author&#8221; Description=&#8221;Sample description&#8221; Publisher=&#8221;Dia_22_AppConnect&#8221;&gt;<br />
&lt;IconPath IsRelative=&#8221;true&#8221; IsResource=&#8221;false&#8221;&gt;ApplicationIcon.png&lt;/IconPath&gt;<br />
&lt;Capabilities&gt;&lt;/Capabilities&gt;<br />
&lt;Tasks&gt;<br />
&lt;DefaultTask  Name =&#8221;_default&#8221; NavigationPage=&#8221;MainPage.xaml&#8221;/&gt;<br />
&lt;/Tasks&gt;<br />
&lt;Tokens&gt;<br />
&lt;PrimaryToken TokenID=&#8221;Dia_22_AppConnectToken&#8221; TaskName=&#8221;_default&#8221;&gt;<br />
&lt;TemplateType5&gt;<br />
&lt;BackgroundImageURI IsRelative=&#8221;true&#8221; IsResource=&#8221;false&#8221;&gt;Background.png&lt;/BackgroundImageURI&gt;<br />
&lt;Count&gt;0&lt;/Count&gt;<br />
&lt;Title&gt;Dia_22_AppConnect&lt;/Title&gt;<br />
&lt;/TemplateType5&gt;<br />
&lt;/PrimaryToken&gt;<br />
&lt;/Tokens&gt;<br />
&lt;Extensions&gt;<br />
&lt;!&#8211; Extensión beta, solo para uso de pruebas y desarrollo &#8211;&gt;<br />
&lt;Extension ExtensionName=&#8221;Productos&#8221; ConsumerID=&#8221;{5B04B775-356B-4AA0-AAF8-6491FFEA5661}&#8221; TaskID=&#8221;_default&#8221; ExtraFile=&#8221;Extensiones/Extras.xml&#8221; /&gt;<br />
&lt;!&#8211; Extensiones de producción, para ingrsar al Marketplace &#8211;&gt;<br />
&lt;Extension ExtensionName=&#8221;Bing_Productos_Libros_y_Revistas&#8221; ConsumerID=&#8221;{5B04B775-356B-4AA0-AAF8-6491FFEA5661}&#8221; TaskID=&#8221;_default&#8221; ExtraFile=&#8221;Extensiones/Extras.xml&#8221; /&gt;<br />
&lt;/Extensions&gt;<br />
&lt;/App&gt;<br />
&lt;/Deployment&gt;</p>
<p>El aspecto importante de esto son los dos elementos de Extension. ExtensionName identifica con que tipo de extensión para integrar con las Quick Cards se usará. Visita <a title="http://msdn.microsoft.com/en-us/library/hh202958%28v=VS.92%29" href="http://msdn.microsoft.com/en-us/library/hh202958%28v=VS.92%29">http://msdn.microsoft.com/en-us/library/hh202958%28v=VS.92%29</a> para una lista completa de Quick Cards disponibles.</p>
<p>El emulador maneja el App Connect de forma diferente que en la versión final de Mango que se ejecuta en el teléfono. En el emulador todos los productos Quick Card tienen una categoría de “Productos” en lugar los ExtensionNames individuales mas específicos. Esto es para decir que si registramos nuestra aplicación para soportar libros y revistas usando “Bing_Productos_Libros_y_Revistas”, nuestra aplicación mostraría la Quick Card de un libro en el dispositivo pero no en el emulador y si registramos para solo soportar solo la categoría de “Productos”, la aplicación parecería trabajar bien en el emulador pero no trabajaría propiamente en dispositivos físicos. Debido a que vas a querer soportar ambos, la categoría “Productos” así como cualquier categoría que quisieras manejar definiendo múltiples elementos de Extensión.</p>
<p>Los otros campos en el elemento de Extensión son relativamente simples con los cuales trabajar: ConsumerID identifica la extensibilidad de búsqueda así como la extensión de elemento y no debería ser cambiada. IDTarea especifica la tarea que debería ser lanzada cuando la extensión sea activdada. ArchivoExtra le dice a la aplicación hacia donde mirar para información adicional necesaria para soportar la integración de búsqueda y debe apuntar a Extensiones/Extras.xml o App Connect no funcionará.</p>
<p><strong><span style="font-size: large">Configurar información adicional necesaria para el App Connect</span></strong></p>
<p>Dado que nuestro proyecto no contiene el archivo XML al que hacemos referencia en las dos extensiones que registramos, deberemos crarlo. Da clic derecho en el proyecto en el explorador de soluciones y selecciona “Add –&gt; New Folder”, renombralo como “Extensiones”, da clic derecho sobre la carpeta y selecciona “Add –&gt; New Item”. Selecciona el archivo XML de la lista y nómbralo “Extras.xml”. El nombre y ruta del archivo debe ser exacto o las extensiones de búsqueda no funcionarán propiamente.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image006.jpg"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image006_thumb.jpg" alt="clip_image006" width="436" height="260" border="0" /></a></p>
<p>Ahora tienes el archivo Extras.xml en la carpeta. Desde aquí necesitaremos agregar un nodo ExtrasInfo al archivo XML que defina como se comportará la aplicación con las extensiones que hemos registrado.</p>
<p>&lt;ExtrasInfo&gt;<br />
&lt;AppTitle&gt;<br />
&lt;default&gt;Soporte Libro&lt;/default&gt;</p>
<p>&lt;en-EN&gt;Book Helper&lt;/en-EN&gt;<br />
&lt;fr-FR&gt;Livre Helper&lt;/fr-FR&gt;<br />
&lt;zh-CN&gt;本书帮助器&lt;/zh-CN&gt;<br />
&lt;/AppTitle&gt;</p>
<p>&lt;Consumer ConsumerID=&#8221;{5B04B775-356B-4AA0-AAF8-6491FFEA5661}&#8221;&gt;</p>
<p>&lt;ExtensionInfo&gt;<br />
&lt;Extensions&gt;<br />
&lt;ExtensionName&gt;Productos&lt;/ExtensionName&gt;<br />
&lt;ExtensionName&gt;Bing_Productos_Libros_y_Revistas&lt;/ExtensionName&gt;<br />
&lt;/Extensions&gt;<br />
&lt;CaptionString&gt;<br />
&lt;default&gt;Search vendors for books and eBooks&lt;/default&gt;</p>
<p>&lt;en-EN&gt;Búsqueda de libros y libros electrónicos de varios proveedores&lt;/en-EN&gt;<br />
&lt;fr-FR&gt;Recherche de livres et eBooks provenant de divers fournisseurs&lt;/fr-FR&gt;<br />
&lt;zh-CN&gt;搜索图书和电子图书来自不同供应商&lt;/zh-CN&gt;<br />
&lt;/CaptionString&gt;<br />
&lt;/ExtensionInfo&gt;</p>
<p>&lt;/Consumer&gt;<br />
&lt;/ExtrasInfo&gt;</p>
<p>El elemento AppTitle y sus hijos le dicen a Windows Phone como llamar a nuestra aplicación ( y le da algunas cadenas localizadas para diferentes idiomas). El nodo “default” dentro de este es usado si una cadena local no puede ser encontrada y debería representar el título de la aplicación en el lenguaje neutral de la aplicación. Los nodos adicionales pueden ser agregados con nombres que coincidan con el código del idioma para el cual sea la cadena local. Por ejemplo, es-ES en este ejemplo indica la cadena usada en ajustes de idioma español.</p>
<p>El nodo Consumer tiene un ConsumerID que coincide con el ConsumerID que registramos en el archivo WMAppManifest.xml. Dentro de este nodo esta un nodo llamado ExtensionInfo con un nodo de Extensiones que contienen elementos ExtensionName que definen las extensiones que dijimos que se podrían soportar.</p>
<p>El elemento CaptionString define el mensaje usado a un lado de la imagen de la extensión de búsqueda y es localizado de la misma forma que AppTitle. Un ejemplo de esta aplicación mostrando una extensión de búsqueda es el ejemplo de abajo.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image008.jpg"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image008_thumb.jpg" alt="clip_image008" width="205" height="373" border="0" /></a></p>
<p>Nota que el ícono de la aplicación es usado para esta imagen y el fondo podría ser claro u oscuro dependiendo del tema. Consecuentemente, la transparencia en los íconos de una aplicación no podrían ser utilizadas cuando la integración con App Connect se dé. Adicionalmente, el elemento pivote para AppConnect en las Quick Cards dice “extras” mientras que en un dispositivo Mango, este pivote esta etiquetado como “apps”.</p>
<p>Si necesitas especificar diferentes letras para diferentes tipos de productos, puedes hacerlo declarando múltiples elementos ExtensionName en un elemento ExtensionInfo y otros en otro, mientras que todos tus ExtensionNames que digas estén representados en un ExtensionInfo.</p>
<p><strong><span style="font-size: large">Ajustar el URI mapping</span></strong></p>
<p>Cuando un usuario entra a la aplicación usando App Conect, el runtime intentará navegar a la URI /SearchExtras. Para soportar este punto de entrada necesitaremos ajustar algunos mapeos de URI para redireccionar el tráfico a la página apropiada. Para hacer esto, definiremos un recurso UriMapper en los recursos de la aplicación en App.xaml y agregando el siguiente recursos a Application.Resources:</p>
<p>&lt;Application.Resources&gt;<br />
&lt;nav:UriMapper x:Key=&#8221;UriMapper&#8221; xmlns:nav=&#8221;clr-namespace:System.Windows.Navigation;assembly=Microsoft.Phone&#8221;&gt;<br />
&lt;nav:UriMapper.UriMappings&gt;<br />
&lt;nav:UriMapping Uri=&#8221;/SearchExtras&#8221; MappedUri=&#8221;/MainPage.xaml&#8221; /&gt;<br />
&lt;/nav:UriMapper.UriMappings&gt;<br />
&lt;/nav:UriMapper&gt;<br />
&lt;/Application.Resources&gt;</p>
<p>Definir este recurso no es suficiente. Necesitamos decirle a la aplicación que encuentre y use este UriMapper para resolver solicitudes. Hacemos esto agregando la siguiente línea de código al constructor en App.xaml.cs:</p>
<p>RootFrame.UriMapper = Resources["UriMapper"] as UriMapper;</p>
<p>Esto dirigirá correctamente todo el tráfico entrante de App Connect para navegar en la MainPage una vez que tu aplicación inicie. Si quisieramos, podríamos especificar una página particular en la propiedad MappedUri que es específica para el App Connect, pero para los propósitos de este ejemplo, esto será suficiente.</p>
<p>Tomar ventaja de la integración con App Connect</p>
<p>Hasta ahora, si corres tu aplicación en el emulador y después vas a la búsqueda de Bing en el dispositivo usando la tecla de buscar, verías tu aplicación listada en el control Pivot “extras” para una Quick Card del producto –siempre y cuando esté hecha para dar soporte – mapeos de tipo de producto individual no funcionan para el emulado, pero si para un dispositivo real (y viceversa ).</p>
<p>Desafortunadamente, nustra aplicación no hace aún nada con la información proveniente por App Connect. Para arreglar esto, vamos a comenzar definiendo la interfaz del usuario. Ve a MainPage.xaml y reemplaza el Grid llamado LayoutRoot y todos sus hijos con el siguiente XAML.</p>
<p>&lt;Grid Background=&#8221;Transparent&#8221;&gt;<br />
&lt;Grid.RowDefinitions&gt;<br />
&lt;RowDefinition Height=&#8221;Auto&#8221; /&gt;<br />
&lt;RowDefinition Height=&#8221;*&#8221; /&gt;<br />
&lt;/Grid.RowDefinitions&gt;<br />
&lt;StackPanel Margin=&#8221;12,17,0,28&#8243;&gt;<br />
&lt;TextBlock Text=&#8221;LA LIGA SILVERLIGHT&#8221; Style=&#8221;{StaticResource PhoneTextNormalStyle}&#8221; /&gt;<br />
&lt;TextBlock Text=&#8221;app connect&#8221; x:Name=&#8221;txtTitulo&#8221; TextWrapping=&#8221;Wrap&#8221; Margin=&#8221;9,-7,0,0&#8243; Style=&#8221;{StaticResource PhoneTextTitle1Style}&#8221; /&gt;<br />
&lt;/StackPanel&gt;<br />
&lt;ScrollViewer Margin=&#8221;12,0,12,0&#8243; Grid.Row=&#8221;1&#8243;&gt;<br />
&lt;StackPanel&gt;<br />
&lt;TextBlock x:Name=&#8221;txtTituloLibro&#8221; TextWrapping=&#8221;Wrap&#8221; Visibility=&#8221;Collapsed&#8221; Style=&#8221;{StaticResource PhoneTextLargeStyle}&#8221; Text=&#8221;Book title goes here&#8221; /&gt;<br />
&lt;TextBlock TextWrapping=&#8221;Wrap&#8221; x:Name=&#8221;txtSinBusqueda&#8221; Text=&#8221;Para usar este productos, utiliza las funciones de búsqueda para buscar un libro y después selecciona esta aplicación desde la sección de aplicaciones.&#8221;<br />
Style=&#8221;{StaticResource PhoneTextNormalStyle}&#8221; /&gt;<br />
&lt;HyperlinkButton HorizontalContentAlignment=&#8221;Left&#8221; Foreground=&#8221;{StaticResource PhoneAccentBrush}&#8221;<br />
Margin=&#8221;{StaticResource PhoneVerticalMargin}&#8221; Content=&#8221;Buscar en Amazon&#8221; Click=&#8221;ManejarBusquedaAmazon&#8221; /&gt;<br />
&lt;HyperlinkButton HorizontalContentAlignment=&#8221;Left&#8221; Foreground=&#8221;{StaticResource PhoneAccentBrush}&#8221;<br />
Margin=&#8221;{StaticResource PhoneVerticalMargin}&#8221; Content=&#8221;Buscar en Barnes y Nobde&#8221; Click=&#8221;ManejarBusquedaBarnesAndNoble&#8221; /&gt;<br />
&lt;/StackPanel&gt;<br />
&lt;/ScrollViewer&gt;<br />
&lt;/Grid&gt;</p>
<p>Esto define una interfaz de usuario que será capaz de funcionar en cualquier aplicación independiente (en el caso del lanzamiento de una aplicación normal o servir como una página de detalles si la aplicación es lanzada usando App Connect. Preestablecidamente, la aplicación se verá como la siguiente imagen.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image010.jpg"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image010_thumb.jpg" alt="clip_image010" width="218" height="395" border="0" /></a></p>
<p>Manejar los parámetros de consulta</p>
<p>Obviamente, nos gustaría ser capaces de hacer algo especial si lanzamos la aplicación desde App Connect en una Quick Card que lanzó a la aplicación. Afortunadamente, cuando entramos a una página vía App Connect, el contexto de la navegación de la página contiene dos parámetros de consulta que nos pueden ayudar a identificar información básica en la Quick Card que lanzó la aplicación. La cadena de consulta ProductName contendrá el nombre del producto que esta asociadocon la Quick Card que els usuario acaba de ver y el argumento Categoría será el ExtensionName que esta asociado con esa Quick Card.</p>
<p>Es importante esperar para que la página se cargue antes de checar los parámetros de consulta dado que el NavigationContext no estará disponible hasta que la carga haya sido completada.</p>
<p>Dado que esta es información es muy básica, es aún útil para aplicaciones que necesiten pre poblar campos o controles con nombres de productos o para páginas que necesitan ser flexibles lo suficiente para manejar múltiples tipos de productos. Ten en mente que para propósitos de depuración Category será siempre “Productos2 en el emulador, pero tendrá los valores correctos cuando corramos la aplicación en un dispositivo.</p>
<p>Para nuestra aplicación de ejemplo, tendremos la página desplegando el nombre del producto, si llegamos a la aplicación por medio de App Connect, pero dejaremos el existente si es que tenemos un inicio ordinario. Debido a que el punto de entrada de la aplicación y los extras de búsqueda usan la misma página para nuestra demo, es importante checar la existencia de la cadena de consulta antes de usarlas.</p>
<p>Aquí está el archivo C# del MainPage modificado que incluye la lógica para pasar los parámetros de consulta y manejar los clics de los hyperlinks.</p>
<p>public partial class MainPage : PhoneApplicationPage<br />
{<br />
private string libro;</p>
<p>public MainPage()<br />
{<br />
InitializeComponent();<br />
Loaded += EventoCargado;<br />
}</p>
<p>private void EventoCargado(object sender, RoutedEventArgs e)<br />
{<br />
if (NavigationContext.QueryString.ContainsKey(&#8220;ProductName&#8221;))<br />
{<br />
libro = NavigationContext.QueryString["ProductName"];<br />
txtTitulo.Text = &#8220;Detalles Libro&#8221;;<br />
}<br />
else if (NavigationContext.QueryString.ContainsKey(&#8220;bing_query&#8221;))<br />
{<br />
libro = NavigationContext.QueryString["bing_query"];<br />
txtTitulo.Text = &#8220;Búsqueda seleccionada&#8221;;<br />
}<br />
else<br />
{<br />
libro = null;<br />
}</p>
<p>if (!string.IsNullOrWhiteSpace(libro))<br />
{<br />
txtTitulo.Text = libro;<br />
txtSinBusqueda.Visibility = Visibility.Collapsed;<br />
txtTituloLibro.Visibility = Visibility.Visible;<br />
}<br />
else<br />
{<br />
txtSinBusqueda.Visibility = Visibility.Visible;<br />
txtTituloLibro.Visibility = Visibility.Collapsed;<br />
}<br />
}</p>
<p>private void ManejarBusquedaBarnesAndNoble(object sender, RoutedEventArgs e)<br />
{<br />
if (string.IsNullOrWhiteSpace(libro))<br />
{<br />
IrA(&#8220;http://www.barnesandnoble.com/ebooks/index.asp&#8221;);<br />
}<br />
else<br />
{<br />
IrA(&#8220;http://productsearch.barnesandnoble.com/search/results.aspx?store=BOOK&amp;keyword=\&#8221;" + libro.Replace(&#8221; &#8220;, &#8220;+&#8221;) + &#8220;\&#8221;");<br />
}<br />
}</p>
<p>private void ManejarBusquedaAmazon(object sender, RoutedEventArgs e)<br />
{<br />
if (string.IsNullOrWhiteSpace(libro))<br />
{<br />
IrA(&#8220;http://www.amazon.com/gp/aw/sb.html/sn=Books&#8221;);<br />
}<br />
else<br />
{<br />
IrA(&#8220;http://www.amazon.com/gp/aw/s/?k=&#8221; + libro.Replace(&#8221; &#8220;, &#8220;+&#8221;));<br />
}<br />
}</p>
<p>private static void IrA(string address)<br />
{<br />
var webTask = new Microsoft.Phone.Tasks.WebBrowserTask();<br />
webTask.Uri = new Uri(address);<br />
webTask.Show();<br />
}<br />
}</p>
<p>Ahora, cuando lancemos la aplicación por medio de App Connect vemos lo siguiente:</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image012.jpg"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image012_thumb.jpg" alt="clip_image012" width="232" height="421" border="0" /></a></p>
<p>Soportar App Instant Answers</p>
<p>Otro elemento introducido en Windows Phone Mango es App Instant Answers. Este es un elemento automático de la búsqueda de Bing donde Bing decide lo relevantes que pueden ser para colocarlas en la cima de los resultados. No tienes que hacer nada para soportar el lanzamiento desde Instant Answers pero puedes tomar ventaja de la información pasada por esta funcionalidad si así lo quieres. Esta información es expuesta por medio de un parámetro de la cadena de consulta llamado “bing_query” y es accedido similarmente por los parámetros ProductName y Category.</p>
<p>Modificar nuestra aplicación de ejemplo para tomar ventaja de Instant Answres es extremadamente fácil como es muestra en la primera mitad del método EventoCargado</p>
<p>if (NavigationContext.QueryString.ContainsKey(&#8220;ProductName&#8221;))<br />
{<br />
libro = NavigationContext.QueryString["ProductName"];<br />
txtTitulo.Text = &#8220;Detalles Libro&#8221;;<br />
}<br />
else if (NavigationContext.QueryString.ContainsKey(&#8220;bing_query&#8221;))<br />
{<br />
libro = NavigationContext.QueryString["bing_query"];<br />
txtTitulo.Text = &#8220;Búsqueda seleccionada&#8221;;<br />
}</p>
<p>Esta modificación permite a la aplicación obtener el título del libro desde el nombre de producto de la Quick Card si alguno esta presente o desde la consulta de Bing que generó el resultado de Instant Answers. La imagen de abajo muestra el entrar a la aplicación por medio de Instant Answers para la cadena de búsquda “Sphere by Michael Crichton”</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image014.jpg"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image014_thumb.jpg" alt="clip_image014" width="258" height="469" border="0" /></a></p>
<p><strong><span style="font-size: large">Probar App Connect</span></strong></p>
<p>Quizá te estés preguntando como probar Instant Answers o adjuntar un depurador al trabajar con las extensiones de búsqueda. Este es un punto válido dado que no hay una buena forma de influenciar los resultados de las búsquedas de Bing usando el emulado y cuando se trabaja con extensiones de búsqueda, el atributo Category no registra lo mismo que debería en el dispositivo. También puede convertir el tiempo consumido para navegar a Bing, ejecutar una búsqueda específica y después lanzar la aplicación usando App Connect. Afortunadamente, hay una forma fácil de simular el lanzamiento de tu aplicación ya sea por medio de las extensiones de búsqueda o por medio de Instant Answers.</p>
<p>Dado que podemos predecir los parámetros de la cadena de consulta que Quick Cards generará cuando entre a nuestra aplicación, es posible colocar manualmente estos valores en el punto de entrada de la aplicación para propósitos de prueba. Las aplicaciones Windows Phone almacenan la dirección de la página preestablecida dentro del archivo WMAppManifest.xml en el nodo de propiedades de nuestro proyecto. Abre este archivo y encuentra el elemento DefaultTask dentro de la colección Tasks.  Se debería ver como esto.</p>
<p><strong>&lt;DefaultTask Name =&#8221;_default&#8221; NavigationPage=&#8221;MainPage.xaml&#8221;/&gt;</strong></p>
<p>Este elemento le dice a la aplicación hacia donde navegar cuando la aplicación inicie y puede ser modificado para apuntar hacia el archivo que tu desees. Puede también ser modificado para simular el ingreso a la aplicación vía las extensiones de búsqueda o Instant Answers especificando los parámetros de la cadena de consulta. Por ejemplo, la siguiente entrada fue usada para probar Instant Answers en la sección de arriba.</p>
<p><strong>&lt;DefaultTask Name =&#8221;_default&#8221; NavigationPage=&#8221;MainPage.xaml?bing_query=Sphere by Michael Crichton&#8221;/&gt;</strong></p>
<p>Las modificaciones para simular un punto de entrada por la extensión de búsqueda para un producto similar son muy parecidas. Nota que dado que estamos especificando múltiples parámetros para la cadena de consulta, estamos usando <strong>&amp;amp; </strong>Es importante como se ve en el siguiente fragmento.</p>
<p><strong>&lt;DefaultTask Name =&#8221;_default&#8221; NavigationPage=&#8221;MainPage.xaml?Category=Bing_Products_Books_and_Magazines&amp;amp;ProductName=Sphere&#8221;/&gt;</strong></p>
<p>Por supuesto, una vez que hayas terminado de probar y estés listo para publicar la aplicación, asegúrate de remover cualquier parámetro de la cadena de consulta que hayas ingresado manualmente para que la aplicación funcione como se espera.</p>
<p>Quizá ocasionalmente caigas dentro de errores de publicación al hacer modificaciones al archivo WMAppManifest.xml e intentes lanzar la aplicación en el emulador. Si la publicación muestra el mensaje “Installation of the application failed. Run time error has occurred. Fix the Capabilities in WMAppManifest.xml file.” y tu sección de capacidades luce bien, solo reconstruye la aplicación y prueba de nuevo.</p>
<p><strong><span style="font-size: large">En resumen</span></strong></p>
<p>Esto abarca la cobertura de App Connect e Instant Answers, dos formas sencillas y fáciles de utilizar que permiten a tu aplicación integrarse con puntos de extensibilidad en el motor de búsqueda mejorado de Bing para Windows Phone Mango.</p>
<p>Para descargar este ejemplo entero de la aplicación de Windows Phone usando los conceptos aquí mostrados, puedes hacerlo en el enlace siguiente.</p>
<p><a href="http://aminespinoza.com/materialBlog/31dias/Dia_22_AppConnect.zip">Puedes descargar el código aquí.</a></p>
<p>Mañana, Samidip Basu esta de vuelta para discutir el modelo de ejecución en Windows Phone, incluyendo Fast App Switching, y como Tombstoning (el cual fue cubierto en el <a href="http://www.jeffblankenburg.com/2010/10/14/31-days-of-windows-phone-day-14-tombstoning-multi-tasking/">Día 14 de los 31 días d Windows Phone</a>) ha cambiado ligeramente para acomodarse al nuevo sistema operativo 7.5. Nos vemos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-22-app-connect/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 21: Sockets</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-21-sockets/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-21-sockets/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 03:50:03 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/2011/12/da-21-sockets/</guid>
		<description><![CDATA[Este artículo es una traducción de Day 21: Sockets, puedes encontrarlo aquí en su versión original en inglés. Hoy vamos a darle un vistazo al nuevo soporte para sockets anunciado en Windows Phone 7.1. Así que ¿Qué son los sockets? Simplemente son los mecanismos de comunicación basados en el protocolo TCP/IP  que es usado para aplicaciones remotas como imprimir, conferencias por video y mucho mas. Antes de meternos en como escribir sockets basados en Windows Phone, vamos a tomar un tiempo para entender que son los sockets por completo. Sockets – ¿Qué esta involucrado? Las aplicaciones se comunican vía sockets basadas en una dirección de sockets. Una dirección de socket es una combinación de una dirección TCP/IP y un puerto. Usando esta información, las aplicaciones de pueden comunicar con entre ellas por medio de una red local o desde internet. El artículo mencionado abajo te dará una muy buena explicación de los términos y tecnología detrás de los sockets. Como programador, todo lo que necesitas saber es como conectar (si usando TCP/IP) y como enviar/recibir información. Los Sockets son una tecnología de bajo nivel. Esto quiere decir que necesitas determinar la información que es enviada y como es leída. Mientras [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/21/31-days-of-mango-day-21-sockets/">Este artículo es una traducción de Day 21: Sockets, puedes encontrarlo aquí en su versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia21.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia21_thumb.png" alt="dia21" width="600" height="75" border="0" /></a></p>
<p>Hoy vamos a darle un vistazo al nuevo soporte para sockets anunciado en Windows Phone 7.1. Así que ¿Qué son los sockets? Simplemente son los mecanismos de comunicación basados en el protocolo TCP/IP  que es usado para aplicaciones remotas como imprimir, conferencias por video y mucho mas.</p>
<p>Antes de meternos en como escribir sockets basados en Windows Phone, vamos a tomar un tiempo para entender que son los sockets por completo.</p>
<p>Sockets – ¿Qué esta involucrado?</p>
<p>Las aplicaciones se comunican vía sockets basadas en una dirección de sockets. Una dirección de socket es una combinación de una dirección TCP/IP y un puerto. Usando esta información, las aplicaciones de pueden comunicar con entre ellas por medio de una red local o desde internet.</p>
<p>El artículo mencionado abajo te dará una muy buena explicación de los términos y tecnología detrás de los sockets. Como programador, todo lo que necesitas saber es como conectar (si usando TCP/IP) y como enviar/recibir información.</p>
<p>Los Sockets son una tecnología de bajo nivel. Esto quiere decir que necesitas determinar la información que es enviada y como es leída. Mientras que esto puede ser propenso para analizar errores, te da un beneficio tremendo en términos velocidad de transferencia de datos sobre los servicios web.</p>
<p>Aquí tienen un link a un artículo detallado sobre sockets y el soporte en Windows Phone 7.1:</p>
<p><a title="http://msdn.microsoft.com/en-us/library/hh202874%28v=vs.92%29.aspx" href="http://msdn.microsoft.com/en-us/library/hh202874%28v=vs.92%29.aspx">http://msdn.microsoft.com/en-us/library/hh202874%28v=vs.92%29.aspx</a></p>
<p>Así que ¡Comencemos!</p>
<p>Una vista general rápida</p>
<p>Lo mínimo, necesitamos crear una aplicación de servidor que reciba la información enviada por el cliente. Para la demo escogimos una aplicación Silverlight (Out of the browser).</p>
<p>Nota: Hemos corrido la aplicación Silverlight en el modo fuera del navegador con permisos elevados de modo que podamos acceder a la información de los socket recibida.</p>
<p>Necesitamos estar de acuerdo en que la información es enviada al host –&gt; un número de tabla, orden de información y nivel de picante.<br />
<pre><code>public class OrderReceivedEventArgs : EventArgs
{
public int tableNumber { get; set; }
public int spiceLevel { get; set; }
public string order { get; set; }
}</code></pre></p>
<p>También desplegaremos los dispositivos Windows Phone 7 conectados al host. Esto ayuda a la persona a administrar al host para que sepa cuantos servidores están trabajando al mismo tiempo. Esta información viene desde el objeto “Device Info”. Aquí está el código fuente de la declaración:</p>
<p><pre><code>public class DeviceInfo : INotifyPropertyChanged
{
private IPEndPoint _DeviceEndPoint;
private string _DeviceOrServerName;
public DeviceInfo(string deviceOrServerName, IPEndPoint endPoint)
{
_DeviceEndPoint = endPoint;
_DeviceOrServerName = deviceOrServerName;
}
}</code></pre><br />
Aquí hay un pantallazo del cliente:</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image002_thumb1.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image002_thumb1_thumb.png" alt="clip_image002_thumb1" width="536" height="402" border="0" /></a></p>
<p>También necesitamos que los clientes Windows Phone tomen la orden, una aplicación simple la cual toma la información de arriba y la ingresa.</p>
<p>Aquí hay un pantallazo de la aplicación Windows Phone:</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image004_thumb.jpg"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image004_thumb_thumb.jpg" alt="clip_image004_thumb" width="215" height="399" border="0" /></a></p>
<p>Como puedes ver, tenemos el nombre del servidor en la aplicación hasta arriba. Esta es la aplicación generada pero es una extensión que podemos darle al usuario la habilidad para ingresar y usar la información ingresada para mostrar el nombre del servidor ingresado.</p>
<p>Tenemos dos sliders a considerar:</p>
<p>1.- El primer slider es el de escoger el numero de la tabla. Esto evalúa del 1 al 10. Esta es una calificación muy simplista para la selección de las tablas y trabajará fácilmente para incluso 20-30 tablas como el slider es muy preciso permite una fácil selección táctil.</p>
<p>2.- El segundo slider es elegir el nivel de picante. Viene principalmente desde mi gusto de la comida picante pero también es algo muy especificado al ordenar comida.</p>
<p>El rango esta asignado de 1 a 10.</p>
<p>El tercer elemento es un TextBox para poner el detalle de las órdenes. SI quieres ampliar esta demostración, puedes agregar una selección desplazable de elementos de menú y un DataGrid para agregar cada elemento seleccionado del menú. Para este ejemplo lo hemos mantenido tan simple como ingresar texto.</p>
<p>Y finalmente necesitamos un botón para enviar la orden. ¡Eso es todo!</p>
<p>Los siguientes puntos importantes deberían ser notados:</p>
<p>1.- La clase RestaurantCommands: Esta clase contiene los comandos permitidos en nuestra aplicación de sockets y debe ser comunes al cliente y el recipiente para entender el mensaje enviado y recibido.</p>
<p>2.- UdpAnySourceMulticastChannel.cs y UdpPacketReceivedEventArgs.cs: Estos son dos archivos que hemos tomado desde la aplicación multicast que contiene el código de los sockets UDP para unirse al grupo, enviando y recibiendo información.</p>
<p>3.- Clase Order: Esta clase maneja toda la comunicación de la aplicación. La comunicación para la aplicación esta hecha de un número de comandos que hemos definido en la clase RestaurantCommand.cs. Esos comandos con la gramática, un conjunto de acciones que podemos transmitir, recibir e interpretar.</p>
<p><strong><span style="font-size: large">Entendiendo el ejemplo</span></strong></p>
<p>Prerequisitos: Instala las herramientas de Mango desde <a href="http://create.msdn.com">http://create.msdn.com</a>. Esto debería darte Visual Studio 2010 y el Windows Phone SDK que necesitas para desarrollar aplicaciones para Windows Phone. También estamos corriendo una aplicación Silverlight en el cliente. Descarga Visual Studio Express C# para obtener las plantillas requeridas.</p>
<p>* Abre Visual Studio, navega a la solución y ábrela.</p>
<p>* Nota: El archivo de solución tiene dos proyectos de inicio. El proyecto “TakeMyOrder” de Windows Phone 7 y la aplicación “PointOfSaleApp” de Silverlight.</p>
<p>* Este es un ejemplo de socket multicast. Para correr esto necesitas desplegar l ejemplo Windows Phone 7 al teléfono y correr la aplicación Silverlight en el cliente.</p>
<p>* Alternativamente, si no tienes un teléfono, despliega la aplicación Silverlight en otra computadora (una máquina virtual quizá) y ejecuta la aplicación Windows Phone 7 en el emulado en el cliente.</p>
<p>* No puedes correr la aplicación Silverlight y Windows Phone 7 en el emulador en la misma máquina.</p>
<p>* Si tienes múltiples máquinas y teléfonos, puedes correr la aplicación Windows Phone simultáneamente en todos ellos. Esto te dará una sensación de múltiples servidores tomando la orden e ingresándolas todas.</p>
<p>* Dado que estamos usando el protocolo UDP, no hay una garantía de que los mensajes enviados son recibidos. Esto es debido al hecho de que no hay una conexión par a par entre los dos dispositivos. En su lugar, los dispositivos se unen en un grupo multicast identificado por una dirección IP y un puerto.</p>
<p>Sin embargo al correr la aplicación, como verás, la comunicación es bastante fluida.</p>
<p><strong><span style="font-size: large">Como funciona</span></strong></p>
<p>* Lanza la aplicación Silverlight en modo fuera del explorador.</p>
<p>* Lanza la aplicación Windows Phone en el teléfono o en un emulador corriendo en otra máquina.</p>
<p>* El cliente mostrará el nombre del servidor y la dirección del punto final.</p>
<p>* Hasta ahora estás listo para colocar una orden.</p>
<p>* En la aplicación Windows Phone , usa el slider de la tabla y escoge una tabla desde uno a diez.</p>
<p>* Ingresa una orden. Por ejemplo, arroz frito con pollo y camarón. Coca sin hielo etc.</p>
<p>* Utiliza el slider de picante para ajustar el nivel de picante deseado. ¡Diez podría ser una excelente elección!</p>
<p>* Da clic en “Oder”. En este punto la aplicación Windows Phone 7 envía el comando “EnviarOrden” a todos los dispositivos en el grupo. Alternativamente podriamos filtrarlo  para enviar la orden solo para el host.</p>
<p>* En el cliente, la orden es recibida y agregada a la tabla “Incoming Orders”. Esto se muestra con un estado de “En proceso” y un identificador único de orden (basado en el número de ordenes recibidas) es asignado.</p>
<p>* Digamos que tenemos una cocina súper veloz y la orden esta lista tan pronto como la recibimos. Selecciona la opción de “In Process” y selecciona el botón “Order Ready”. El cliente envía el estado de la orden a todos los dispositivos en la red y actualiza el estado en la tabla. Ve debajo utilizando INotifyPropertyChanged.</p>
<p>* El dispositivo Windows Phone recibe el estado de la orden en todos los dispositivos. Alternativamente podríamos haber filtrado para eviarlo solo al dispositivo que emitió la orden.</p>
<p>Aquí hay un pantallazo después de que la orden esta completa.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image006_thumb1.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image006_thumb1_thumb.png" alt="clip_image006_thumb1" width="536" height="402" border="0" /></a></p>
<p>Entendiendo el código.</p>
<p>Aquí hay unas piezas clave del código para entenderlo.</p>
<p><strong>Unirse al grupo:</strong>Los dispositivos se unen al grupo usando los siguientes componentes clave:</p>
<p>/// &lt;summary&gt;<br />
/// All communication takes place using a UdpAnySourceMulticastChannel.<br />
/// A UdpAnySourceMulticastChannel is a wrapper we create around the UdpAnySourceMulticastClient.<br />
/// &lt;/summary&gt;<br />
/// &lt;value&gt;The channel.&lt;/value&gt;<br />
private UdpAnySourceMulticastChannel Channel { get; set; }</p>
<p>/// &lt;summary&gt;<br />
/// The IP address of the multicast group.<br />
/// &lt;/summary&gt;<br />
/// &lt;remarks&gt;<br />
/// A multicast group is defined by a multicast group address, which is an IP address<br />
/// that must be in the range from 224.0.0.0 to 239.255.255.255. Multicast addresses in<br />
/// the range from 224.0.0.0 to 224.0.0.255 inclusive are well-known reserved multicast<br />
/// addresses. For example, 224.0.0.0 is the Base address, 224.0.0.1 is the multicast group<br />
/// address that represents all systems on the same physical network, and 224.0.0.2 represents<br />
/// all routers on the same physical network.The Internet Assigned Numbers Authority (IANA) is<br />
/// responsible for this list of reserved addresses. For more information on the reserved<br />
/// address assignments, please see the IANA website.<br />
/// http://go.microsoft.com/fwlink/?LinkId=221630<br />
/// &lt;/remarks&gt;<br />
private const string GROUP_ADDRESS = &#8220;224.0.1.11&#8243;;</p>
<p>/// &lt;summary&gt;<br />
/// This defines the port number through which all communication with the multicast group will take place.<br />
/// &lt;/summary&gt;<br />
/// &lt;remarks&gt;<br />
/// The value in this example is arbitrary and you are free to choose your own.<br />
/// &lt;/remarks&gt;<br />
private const int GROUP_PORT = 54329;</p>
<p>El siguiente comando es necesario para unir al grupo:</p>
<p>//Send command to join the multi cast group<br />
App.Order.Join(serverName);</p>
<p>Y finalmente el método unir abre el canal de la comunicación.</p>
<p>/// &lt;summary&gt;<br />
/// Join the multicast group.<br />
/// &lt;/summary&gt;<br />
/// &lt;param name=&#8221;serverName&#8221;&gt;The server name I want to join as.&lt;/param&gt;<br />
/// &lt;remarks&gt;The server name is not needed for multicast communication. it is<br />
/// used in this example to identify each member of the multicast group with<br />
/// a friendly name. &lt;/remarks&gt;<br />
public void Join(string serverName)<br />
{<br />
if (IsJoined)<br />
{<br />
return;<br />
}</p>
<p>// Store my player name<br />
_serverName = serverName;</p>
<p>//Open the connection<br />
this.Channel.Open();<br />
}</p>
<p>We subscribe to the following events for processing:</p>
<p>/// &lt;summary&gt;<br />
/// Register for events on the multicast channel.<br />
/// &lt;/summary&gt;<br />
private void RegisterEvents()<br />
{<br />
// Register for events from the multicast channel<br />
this.Channel.Joined += new EventHandler(Channel_Joined);<br />
this.Channel.BeforeClose += new EventHandler(Channel_BeforeClose);<br />
this.Channel.PacketReceived += new EventHandler&lt;UdpPacketReceivedEventArgs&gt;(Channel_PacketReceived);<br />
}</p>
<p>Una nota particular es el evento “PacketReceived”. Procesamos todos los comandos recibidos (Dispositivo y cliente) en este manejador de eventos. Simplemente poner, pasamos el mensaje de entrada e identificamos el comando siendo enviado. Basado en el comando y número de argumentos identificaremos la acción a tomar.</p>
<p>Enviar la orden: El comando siguiente es utilizado para cuando el usuario de clic en el botón “Ordenar”.</p>
<p>App.Order.SendOrder(txtOrder.Text, TableSlider.Value.ToString(), spiceSlider.Value.ToString());</p>
<p>/// &lt;summary&gt;<br />
/// Send the order<br />
/// &lt;/summary&gt;<br />
/// &lt;param name=&#8221;Order&#8221;&gt;&lt;/param&gt;<br />
/// &lt;param name=&#8221;tableNumber&#8221;&gt;&lt;/param&gt;<br />
/// &lt;param name=&#8221;spiceLevel&#8221;&gt;&lt;/param&gt;<br />
public void SendOrder(string Order,string tableNumber, string spiceLevel)<br />
{<br />
if (this.Channel != null)<br />
{<br />
//Send order to all devices. Only the server will process the send order command. Others will simply ignore it.<br />
this.Channel.Send(RestaurantCommands.SendOrderFormat, _serverName, Order, tableNumber, spiceLevel);<br />
}<br />
}</p>
<p>Nuestro formato “SendOrderFormat” se verá así:</p>
<p>public const string SendOrder = &#8220;SO&#8221;;<br />
public const string SendOrderFormat = SendOrder + CommandDelimeter + &#8220;{0}&#8221; + CommandDelimeter + &#8220;{1}&#8221; + CommandDelimeter + &#8220;{2}&#8221; + CommandDelimeter + &#8220;{3}&#8221;;</p>
<p>&nbsp;</p>
<p>Aquí está el código para el evento enviar:</p>
<p>/// &lt;summary&gt;<br />
/// Sends the specified format. This is a multicast message that is sent to all members of the multicast group.<br />
/// &lt;/summary&gt;<br />
/// &lt;param name=&#8221;format&#8221;&gt;The format.&lt;/param&gt;<br />
/// &lt;param name=&#8221;args&#8221;&gt;The args.&lt;/param&gt;<br />
public void Send(string format, params object[] args)<br />
{<br />
try<br />
{<br />
if (this.IsJoined)<br />
{<br />
byte[] data = Encoding.UTF8.GetBytes(string.Format(format, args));<br />
this.Client.BeginSendToGroup(data, 0, data.Length, new AsyncCallback(SendToGroupCallback), null);<br />
}<br />
}<br />
catch (SocketException socketEx)<br />
{</p>
<p>// See if we can do something when a SocketException occurs.<br />
HandleSocketException(socketEx);<br />
}<br />
catch (InvalidOperationException)<br />
{<br />
Debug.WriteLine(&#8220;BeginSendToGroup IOE&#8221;);<br />
}<br />
}</p>
<p>Así que como puedes ver, basado en el formato el mensaje es formateado y transmitido.</p>
<p>Recibir la orden:</p>
<p>En el cliente, el mensaje es recibido por el manejador definido por el evento “PacketReceived”</p>
<p>string message = e.Message.Trim(&#8221;);<br />
string[] messageParts = message.Split(RestaurantCommands.CommandDelimeter.ToCharArray());</p>
<p>else if (messageParts.Length == 5 &amp;&amp; messageParts[0]== RestaurantCommands.SendOrder)<br />
{<br />
//Status of order received<br />
OrderReceivedEventArgs args = new OrderReceivedEventArgs();<br />
args.tableNumber = Convert.ToInt32(messageParts[3]);<br />
args.spiceLevel = Convert.ToInt32( messageParts[4]);<br />
args.order = messageParts[2];<br />
if (DataReceivedFromDevice != null)<br />
{<br />
DataReceivedFromDevice(this, args);<br />
}<br />
}</p>
<p>Es un mecanismo de comunicación muy simple. Una vez que lo hemos identificado, pasado y creado nuestros argumentos para el método de información recibida.</p>
<p>En nuestra aplicación, manejamos el evento y agregamos la orden de entrada a la colección de órdenes.</p>
<p>/// &lt;summary&gt;<br />
/// Handles incoming orders<br />
/// &lt;/summary&gt;<br />
/// &lt;param name=&#8221;sender&#8221;&gt;&lt;/param&gt;<br />
/// &lt;param name=&#8221;e&#8221;&gt;&lt;/param&gt;<br />
void Order_DataReceivedFromDevice(object sender, OrderReceivedEventArgs e)<br />
{<br />
int OrderID = App.OrdersCollection.Count +1;<br />
Orders objOrders = new Orders(OrderID, e.tableNumber, e.spiceLevel, e.order);<br />
App.OrdersCollection.Add(objOrders);<br />
}</p>
<p>Problemas conocidos</p>
<p>* De vez en cuando recibirás un error cuando termines de depurar.</p>
<p>* El nombre del ensamblado &#8216;System.Net.debug.resources, Version=2.0.5.0, Culture=en-US, PublicKeyToken=7cec85d7bea7798e&#8217;, o una de sus dependencias no fue encontrada.</p>
<p>* Este es un problema conocido como se indica aquí <a href="http://forums.create.msdn.com/forums/p/89666/537141.aspx">http://forums.create.msdn.com/forums/p/89666/537141.aspx</a>. En algunas ocasiones que el error es alcanzado, tienes que cerrar Visual Studio y re abrirlo.</p>
<p>INotifyPropertyChanged</p>
<p>Esta interfaz tiene que ser implementada en los objetos que usamos para enlazar los DataGrids. Incluso si las colecciones de objetos están declaradas como el mostrado abajo, la interfaz del usuario no se actualiza a menos que las propiedades en el objeto por sí mismo alcancen el evento de cambio de propiedad.</p>
<p>public static ObservableCollection&lt;DeviceInfo&gt; Devices = new ObservableCollection&lt;DeviceInfo&gt;();</p>
<p>Enviar el estado de la orden: Similar al de arriba, un mecanismo parecido es implementado para enviar el estado de la orden.</p>
<p>/// &lt;summary&gt;<br />
/// Sends the order status<br />
/// &lt;/summary&gt;<br />
/// &lt;param name=&#8221;OrderID&#8221;&gt;&lt;/param&gt;<br />
/// &lt;param name=&#8221;status&#8221;&gt;&lt;/param&gt;<br />
public void SendOrderStatus(int OrderID, string status)<br />
{<br />
if (this.Channel != null)<br />
{<br />
//Send order to all devices. Only the server will process the send order command. Others will simply ignore it.<br />
this.Channel.Send(RestaurantCommands.ReceiveOrderFormat, _serverName, OrderID, status);<br />
}<br />
}</p>
<p>public const string ReceiveOrder = &#8220;RO&#8221;;<br />
public const string ReceiveOrderFormat = ReceiveOrder + CommandDelimeter + &#8220;{0}&#8221; + CommandDelimeter + &#8220;{1}&#8221; + CommandDelimeter + &#8220;{2}&#8221;;</p>
<p>else if (messageParts.Length == 4 &amp;&amp; messageParts[0] == RestaurantCommands.ReceiveOrder)<br />
{<br />
//Status of order received<br />
OrderStatusReceivedEventArgs args = new OrderStatusReceivedEventArgs();<br />
args.orderId = Convert.ToInt32(messageParts[2]);<br />
args.orderStatus = messageParts[3];<br />
if (DataReceivedFromDevice != null)<br />
{<br />
DataReceivedFromDevice(this, args);<br />
}<br />
}</p>
<p>/// &lt;summary&gt;<br />
/// Shows a message box with the order status<br />
/// &lt;/summary&gt;<br />
/// &lt;param name=&#8221;sender&#8221;&gt;&lt;/param&gt;<br />
/// &lt;param name=&#8221;e&#8221;&gt;&lt;/param&gt;<br />
void Order_DataReceivedFromDevice(object sender, OrderStatusReceivedEventArgs e)<br />
{<br />
DiagnosticsHelper.SafeShow(&#8220;Order Status of &#8216;&#8221; +e.orderStatus + &#8220;&#8216; Received For Order:&#8221; + e.orderId.ToString());<br />
}</p>
<p>En resumen</p>
<p>Así que usando la ayuda obtenida es sumamente fácil implementar una aplicación usando sockets. Esta aplicación puede ser convertida a una aplicación de restaurante comprensiva simplemente extendiendo algunos elementos como modificar otros mas:</p>
<p>* Agregar la habilidad para seleccionar de un menú.</p>
<p>* Agregar la habilidad para ver las ordenes pendientes en los dispositivos.</p>
<p>* Agregar la habilidad de ingreso por usuario</p>
<p>Los pasos básicos para construir una aplicación de sockets son</p>
<p>*Decidir en el tipo de socket de aplicación: Multicast (UDP) o Unicast (TCP).</p>
<p>*Decidir los comandos</p>
<p>*Comunicación.</p>
<p>*Procesos.</p>
<p>Esto debería darte una buena vista general del soporte de los sockets en Windows Phone. Puedes checar igual los ejemplos dados en <a href="http://msdn.microsoft.com/en-us/library/hh202874(v=vs.92).aspx">http://msdn.microsoft.com/en-us/library/hh202874(v=vs.92).aspx</a></p>
<p>Para descargar este ejemplo entero de la aplicación de Windows Phone usando sockets, puedes hacerlo en el enlace siguiente.</p>
<p><a href="http://aminespinoza.com/materialBlog/31dias/Day21-Sockets.zip">Puedes descargar el código aquí.</a></p>
<p>Mañana, Matt Eland va a guiarte para usar App Conect (también conocida como la extensión de búsqueda) para hacer que tu aplicación se muestre a los usuarios, incluso si no la han instalado en su dispositivo. ¡Nos vemos!</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-21-sockets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 20: Crear tonos de llamada</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-20-crear-tonos-de-llamada/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-20-crear-tonos-de-llamada/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 06:45:02 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/2011/12/da-20-crear-tonos-de-llamada/</guid>
		<description><![CDATA[Esta es una traduccion de Day 20: Creating Ringtones, puedes encontrarlo aquí en su versión original en inglés. Hoy vamos a hablar acerca de los tonos de llamada. Con la actualización Mango de Windows Phone, puedes como desarrollador tener la habilidad de escribir aplicaciones que puedan guardar un tono de llamada personalizado a su dispositivo para su posterior uso. Esta habilidad es otra forma de dar al usuario una oportunidad de tener una experiencia mas personalizada en su teléfono. Criterios para el archivo de audio Antes de que puedas guardar un tono de llamada en el teléfono, hay algunas estipulaciones en el archivo de audio que necesitas saber. El archivo de audio debe cumplir con los siguientes criterios: - Puede ser solo de formato WMA o MP3 - No puede ser mayor a 1 MB - Debe estar desbloqueado (libre de derechos). Método SaveRingtoneTask Chooser Para guardar un tono de llamada de tu aplicación al sistema, necesitas usar la API Chooser. El Chooser es una API que permite al que la llame la habilidad de lanzar aplicaciones del sistema desde su propia aplicación. Ejemplos de esto incluyen la habilidad de lanzar la aplicación de contactos para obtener información acerca de [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/20/31-days-of-mango-day-20-creating-ringtones/">Esta es una traduccion de Day 20: Creating Ringtones, puedes encontrarlo aquí en su versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia20.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia20_thumb.png" alt="dia20" width="600" height="75" border="0" /></a></p>
<p>Hoy vamos a hablar acerca de los tonos de llamada. Con la actualización Mango de Windows Phone, puedes como desarrollador tener la habilidad de escribir aplicaciones que puedan guardar un tono de llamada personalizado a su dispositivo para su posterior uso. Esta habilidad es otra forma de dar al usuario una oportunidad de tener una experiencia mas personalizada en su teléfono.</p>
<p>Criterios para el archivo de audio</p>
<p>Antes de que puedas guardar un tono de llamada en el teléfono, hay algunas estipulaciones en el archivo de audio que necesitas saber.</p>
<p>El archivo de audio debe cumplir con los siguientes criterios:</p>
<p>- Puede ser solo de formato WMA o MP3</p>
<p>- No puede ser mayor a 1 MB</p>
<p>- Debe estar desbloqueado (libre de derechos).</p>
<p><span style="font-size: large"><strong>Método SaveRingtoneTask Chooser</strong></span></p>
<p>Para guardar un tono de llamada de tu aplicación al sistema, necesitas usar la API Chooser. El Chooser es una API que permite al que la llame la habilidad de lanzar aplicaciones del sistema desde su propia aplicación. Ejemplos de esto incluyen la habilidad de lanzar la aplicación de contactos para obtener información acerca de una persona, la aplicación de Bing Maps para encontrar direcciones o una ubicación, y lanzar la aplicación de tonos de llamada. La aplicación de tonos de llamada es una aplicación que te permite guardar un archivo de audio a la lista de tonos de llamada del sistema. La tarea que necesitas llamar para lanzar la aplicación de tonos de llamada es llamada SaveRingtone Task.</p>
<p>Crear una aplicación con un tono de llamada personalizado</p>
<p>Para entender mejor esto y como usar esta tarea, vamos a construir nuestra propia aplicación de tono de llamada que tome un archivo de audio de la aplicaciones a guardarlo a la lista de tonos de llamada del sistema.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb111.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb11_thumb.png" alt="image_thumb11" width="232" height="440" border="0" /></a></p>
<p>Para llamar al chooser SaveRingtoneTask, simplemente necesitas instanciar un objeto de este chooser y definir un delegado que correrá una vez que el usuario este completo con la aplicación. El ejemplo de abajo despliega la aplicación mostrada arriba.</p>
<p>using System;<br />
using System.Windows;<br />
using Microsoft.Phone.Controls;<br />
using Microsoft.Phone.Tasks;</p>
<p>namespace Dia_20_TonosLlamada<br />
{<br />
public partial class MainPage : PhoneApplicationPage<br />
{<br />
private readonly SaveRingtoneTask tonoPersonalizado;</p>
<p>public MainPage()<br />
{<br />
InitializeComponent();<br />
tonoPersonalizado = new SaveRingtoneTask();<br />
tonoPersonalizado.Completed += tonoPersonalizado_Completed;<br />
}</p>
<p>void tonoPersonalizado_Completed(object sender, TaskEventArgs e)<br />
{<br />
MessageBox.Show(@&#8221;Ve de vuelta a la aplicación de tonos de llamada. La referencia a e.TaskResult, en tu código,<br />
si quieres ver si el guardado fue exitoso.&#8221;);<br />
}</p>
<p>private void btnGuardar_Click(object sender, System.Windows.RoutedEventArgs e)<br />
{<br />
tonoPersonalizado.Source = new Uri(&#8220;appdata:/Audio/AudioEjemplo.wma&#8221;);<br />
tonoPersonalizado.DisplayName = &#8220;Tono de llamada personalizado&#8221;;<br />
tonoPersonalizado.Show();<br />
}<br />
}<br />
}</p>
<p>Cosas para considerar</p>
<p>* Necesitas definir un manejador de eventos Completed que correrá una vez que el usuario haya completado la tarea. Este método es un gran lugar para checar como ver lo que el usuario hizo en la tarea y actuar de acuerdo a ello.</p>
<p>* Para llamar a la aplicación, solo necesitas llamar al método Show() en el chooser.</p>
<p>* Puedes acceder a los archivos de audio desde la información que es parte de la aplicación (appdata: )así como del almacenamiento aislado (isostore: ).</p>
<p>En Resumen</p>
<p>Para resumir las cosas de hoy, los tonos personalizados le dan a los usuarios una oportunidad de tener una experiencia mas personalizada con sus nuevos Windows Phone. Al llamar a la SaveRingtoneTask puedes dar una puerta para que el usuario sea capaz de añadir este nivel de personalización a sus teléfonos.</p>
<p>¡Que te diviertas escribiendo código!</p>
<p>Para descargar una versión funcional de la aplicación Windows Phone cubierta en este artículo, puedes hacerlo en el enlace siguiente.</p>
<p><a href="http://aminespinoza.com/materialBlog/31dias/Dia_20_TonosLlamada.zip">Descarga el código aquí.</a></p>
<p>Mañana, Parag Joshi estará cubriendo una nueva tecnología disponible para los desarrolladores de Windows Phone que ha estado en una gran demanda: sockets. Nos vemos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-20-crear-tonos-de-llamada/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 18: Usando informaci&#243;n de ejemplo</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-18-usando-informacin-de-ejemplo/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-18-usando-informacin-de-ejemplo/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 06:01:58 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Blend]]></category>
		<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/2011/12/da-18-usando-informacin-de-ejemplo/</guid>
		<description><![CDATA[Esta es una traducción de Day 18: Using Sample Data, puedes encontrarlo aquí en la versión original en inglés. Hoy, vamos a explorar otro gran elemento de Expression Blend creando un poco de información de ejemplo que nuestra aplicación puede usar. Muchas veces, cuando comienzas a crear una aplicación, quieres ver como se verá la información en la interfaz antes de que la base de datos (o servicio web) esté listo. Para hacer esto, podemos usar Expression Blend. Desde que he usado Expression Blend y muchas de sus características en el pasado,  podría darte algunas lecturas recomendadas aquí. * 31 days of Windows Phone &#124; Day 5: System Theming * 31 days of Windows Phone &#124; Day 6: Application Bar * 31 days of Windows Phone &#124; Day 29: Animations * Expression Blend Training Kit Para el artículo de hoy, vamos a meternos directamente. Si quieres probar esta aplicación en tu Windows Phone gratis,  está disponible en el Windows Phone Marketplace. Crear tu aplicación de Windows Phone Como en la mayoría de mis artículos en esta serie, también he creado un video para demostrar lo que estoy tratando de cumplir en este artículo. Explicaré todo lo que esté mostrado en [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/18/31-days-of-mango-day-18-using-sample-data/">Esta es una traducción de Day 18: Using Sample Data, puedes encontrarlo aquí en la versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia18.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia18_thumb.png" alt="dia18" width="600" height="75" border="0" /></a></p>
<p>Hoy, vamos a explorar otro gran elemento de Expression Blend creando un poco de información de ejemplo que nuestra aplicación puede usar. Muchas veces, cuando comienzas a crear una aplicación, quieres ver como se verá la información en la interfaz antes de que la base de datos (o servicio web) esté listo. Para hacer esto, podemos usar Expression Blend.</p>
<p>Desde que he usado Expression Blend y muchas de sus características en el pasado,  podría darte algunas lecturas recomendadas aquí.</p>
<p>* <a href="http://www.jeffblankenburg.com/post/31-Days-of-Silverlight-7c-Day-5-System-Theming.aspx">31 days of Windows Phone | Day 5: System Theming</a></p>
<p>* <a href="http://www.jeffblankenburg.com/post/31-Days-of-Windows-Phone-7c-Day-6-Application-Bar.aspx">31 days of Windows Phone | Day 6: Application Bar</a></p>
<p>* <a href="http://www.jeffblankenburg.com/post/31-Days-of-Windows-Phone-7c-Day-29-Animations.aspx">31 days of Windows Phone | Day 29: Animations</a></p>
<p>* <a href="http://www.microsoft.com/expression/resources/BlendTraining/">Expression Blend Training Kit</a></p>
<p>Para el artículo de hoy, vamos a meternos directamente. Si quieres probar esta aplicación en tu Windows Phone gratis,  está disponible en el Windows Phone Marketplace.</p>
<p><a href="http://www.windowsphone.com/es-MX/apps/eb0abc9b-9a1e-4e77-830f-ffee47b5ef03"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/11/DownloadIcon1.png" alt="" border="0" /></a></p>
<p><strong><span style="font-size: large">Crear tu aplicación de Windows Phone</span></strong></p>
<p>Como en la mayoría de mis artículos en esta serie, también he creado un video para demostrar lo que estoy tratando de cumplir en este artículo. Explicaré todo lo que esté mostrado en el video, pero si prefieres verlo primero, aquí esta.</p>
<p><a href="http://www.youtube.com/watch?feature=player_embedded&amp;v=H2CjM9Ss0Ms">Puedes ver el video aquí.</a></p>
<p>Comenzaremos creando un nuevo proyecto de Windows Phone. Espero que hayas hecho esto esto ya muchas veces en Visual Studio 2010, así que comenzaré por hacerlo por medio de Expression Blend esta ocasión.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image8.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image8_thumb.png" alt="image8" width="380" height="323" border="0" /></a></p>
<p>Una vez que tengas tu proyecto, con tu MainPage.xaml abierta, vamos a agregar un ListBox a nuestra página. Para hacer esto, da clic en la en la barra de menú ubicada a la izquierda, escoge “Controls” y selecciona el ícono del ListBox.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image9.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image9_thumb.png" alt="image9" width="380" height="325" border="0" /></a></p>
<p>Ya que hayas seleccionado el ListBox, puedes hacer clic y arrastrarlo en la superficie de diseño.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image10.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image10_thumb.png" alt="image10" width="252" height="420" border="0" /></a></p>
<p>He expandido mi ListBox para tomar el espacio entero dentro de mi grid ContentPanel que fue creado “por default” cuando cree mi proyecto (Este es todo el espacio que esta abajo del texto que dice “page name” en la pantalla).</p>
<p>Crear un poco de información de ejemplo</p>
<p>Si miras en la esquina derecha de Expression Blend, deberías ver una pestaña con la palabra “Data” en ella. Abre esta pestaña.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image11.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image11_thumb.png" alt="image11" width="314" height="479" border="0" /></a></p>
<p>Al dar clic en el botón de “New Sample Data” en la parte superior derecha de este panel, seremos capaces de comenzar a crear nuestra aplicación de ejemplo.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image12.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image12_thumb.png" alt="image12" width="417" height="419" border="0" /></a></p>
<p>Esto hará que se muestre un cuadro de diálogo “New Sample Data”. Dale a tu información un nombre (Nombré a la mía Muebles, para seguir el ejemplo que usé en el video).</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image13.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image13_thumb.png" alt="image13" width="453" height="219" border="0" /></a></p>
<p>Notarás que tienes la opción para definir esta información en tu proyecto, o en una página específica. Yo recomiendo escoger “Project” porque creará bastantes estructuras en tu aplicación que puedas usar en mas de una sola forma.</p>
<p>Al dar clic en OK te mandará de regreso a la pestaña de “Data”, con unas cuantas cosas agregadas.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image14.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image14_thumb.png" alt="image14" width="256" height="391" border="0" /></a></p>
<p>Ahora tenemos una estructura que parecería familiar a cualquiera que haya trabajado con una base de datos antes. “Muebles” representa nuestra base de datos y “Colección” es una tabla en esa base de datos. “Propiedad 1” y “Propiedad 2” son campos en la tabla de Colección.</p>
<p>Voy a agregar dos nuevas propiedades a la base de datos y renombrar las dos existentes, así las cosas serán mas descriptivas. La colección se volverá “Sillas” y ahora tenemos 4 propiedades: SKU, Precio, Descripción e Imagen.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image15.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image15_thumb.png" alt="image15" width="261" height="399" border="0" /></a></p>
<p>En la extrema derecha de cada propiedad, hay un ícono para indicar que tipo de información es. Para descripción, quiero tener una larga cadena de palabras. Puedes hacer esto eligiendo el tipo de cadena “Lorem ipsum”. Esto nos dará cadenas aleatorias de 20 palabras, sin ninguna palabra mayor a 8 caracteres.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image16.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image16_thumb.png" alt="image16" width="261" height="399" border="0" /></a></p>
<p>Queremos que la propiedad imagen contenga imágenes, así que deberías elegir el tipo Imagen. Puedes especificar tu propio set de imágenes si quieres, nosotros haremos eso un poco después en este artículo.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image17.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image17_thumb.png" alt="image17" width="261" height="399" border="0" /></a></p>
<p>Ajustaré rápidamente la propiedad Precio a un tipo String/Price y SKU a un valor de nombre con 6 caracteres.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image18.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image18_thumb.png" alt="image18" width="261" height="399" border="0" /></a>  <a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image19.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image19_thumb.png" alt="image19" width="261" height="399" border="0" /></a></p>
<p>Si das clic en el botón de “View Sample Data” a la derecha del título de Sillas, se te mostrará en una tabla la información que contiene información aleatoria para cada una de las propiedades que hemos especificado. Al cambiar el valor del número de registros al fondo, puedes determinar cuantos registros te gustaría usar.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/SNAGHTML27ad8b6d.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/SNAGHTML27ad8b6d_thumb.png" alt="SNAGHTML27ad8b6d" width="600" height="410" border="0" /></a></p>
<p>Ahí lo tienes. Hemos creado la información de ejemplo. En este punto, estás probablemente preguntándote como sabía que debía usar imágenes de sillar. Sin importar el nombre de la estructura de tu información, si usas un tipo de imagen y no especificas un conjunto de imágenes, este conjunto de imágenes será siempre el utilizado. No hay magia, solo una demostración con truco.</p>
<p>Para cambiar las imágenes a algo mas apropiado en tu proyecto, puedes re abrir la definición para la propiedad de imagen que creé y especificar una carpeta en tu computadora. Cuando hagas esto, terminarás con valores de ejemplo que se verán mas como estos (asumiendo que hayas usado las imágenes que yo usé).</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/SNAGHTML27b15a01.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/SNAGHTML27b15a01_thumb.png" alt="SNAGHTML27b15a01" width="600" height="410" border="0" /></a></p>
<p>Ahora es momento de usar esta información.</p>
<p>Usar la información de ejemplo en una aplicación Windows Phone</p>
<p>Primero, a pesar de que es llamada “Información de ejemplo”, si tienes un conjunto pequeño de información estática que estés intentando utilizar en tu aplicación, no hay absolutamente nada malo al hacerla parte permanente de tu aplicación. Dicho esto, para hacer que esta información se vaya a nuestro ListBox que creamos desde casi el principio, puedes simplemente arrastrar “Sillas” de la pestaña de datos directamente a tu control ListBox, algo como esto (la caja azul es mi mouse arrastrando la información al ListBox, puedes darle clic a la imagen para hacerla mas larga).</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb1.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb_thumb.png" alt="image_thumb" width="559" height="350" border="0" /></a></p>
<p>En el momento en que dejas a tu aplicación ir, inmediatamente creará dos cosas para ti.</p>
<p>* Una plantilla de datos para diseñar los elementos individuales en el ListBox.</p>
<p>* Un enlazado entre la información de ejemplo y tu ListBox</p>
<p>En este ejemplo, la plantilla de datos es almacenada directamente dentro de nuestra página MainPage y se ve como esto.</p>
<p>&lt;DataTemplate x:Key=&#8221;ChairsItemTemplate&#8221;&gt;<br />
&lt;StackPanel Width=&#8221;297&#8243;&gt;<br />
&lt;Canvas Height=&#8221;143&#8243; Margin=&#8221;1,0,-57,0&#8243;&gt;<br />
&lt;TextBlock Text=&#8221;{Binding SKU}&#8221; Canvas.Top=&#8221;44&#8243; Canvas.Left=&#8221;148&#8243; Width=&#8221;205&#8243;/&gt;<br />
&lt;TextBlock Text=&#8221;{Binding Price}&#8221; FontSize=&#8221;16&#8243; Foreground=&#8221;#FF339933&#8243; Canvas.Top=&#8221;86&#8243; Width=&#8221;205&#8243; Canvas.Left=&#8221;148&#8243; Height=&#8221;50&#8243;/&gt;<br />
&lt;TextBlock Text=&#8221;{Binding Description}&#8221; Height=&#8221;32&#8243; TextWrapping=&#8221;Wrap&#8221; Width=&#8221;298&#8243; Canvas.Top=&#8221;8&#8243; Canvas.Left=&#8221;148&#8243;/&gt;<br />
&lt;Image Source=&#8221;{Binding Image}&#8221; HorizontalAlignment=&#8221;Left&#8221; Height=&#8221;136&#8243; Width=&#8221;136&#8243;/&gt;<br />
&lt;/Canvas&gt;<br />
&lt;/StackPanel&gt;<br />
&lt;/DataTemplate&gt;</p>
<p>Verás que nuestro ListBox contiene un ItemTemplate enlazado a este DataTemplate y el ItemSource es definido como nuestra información Silla</p>
<p>&lt;ListBox Margin=&#8221;8,8,0,8&#8243; ItemTemplate=&#8221;{StaticResource ChairsItemTemplate}&#8221; ItemsSource=&#8221;{Binding Chairs}&#8221; SelectionChanged=&#8221;ListBox_SelectionChanged&#8221;/&gt;</p>
<p>Para editar la apariencia de nuestro DataTemplate, podemos usar Expression Blend para hacer esto también. Da clic derecho en tu ListBox en Expression Blend y escoge</p>
<p>Edit Additional Templates &gt; Edit Generated Items (Item Template) &gt; Edit Current</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb11.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb1_thumb.png" alt="image_thumb1" width="439" height="378" border="0" /></a></p>
<p>Al hacer esto, notarás que muchas  cosas en nuestra interfaz ha cambiado. Primero, hasta arriba de nuestro panel de diseño, ahora indica que estamos trabajando en ItemTemplate de nuestro ListBox.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image221.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image22_thumb1.png" alt="image22" width="445" height="120" border="0" /></a></p>
<p>En segundo lugar, echa un vistazo a tu panel de Object and Timeline. Ahora específicamente enfocado en el contenido del ItemTemplate el cual contiene 3 TextBlock y un control de Imagen.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image23.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image23_thumb.png" alt="image23" width="341" height="278" border="0" /></a></p>
<p>Podemos ahora manipular los elementos de nuestro ItemTemplate directamente en el diseño de la superficie. Por ejemplo, solo hice la primer imagen mas grande. Dado que estamos editando la plantilla, notarás que todas esas imágenes también se hacen mas grandes.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image24.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image24_thumb.png" alt="image24" width="231" height="380" border="0" /></a></p>
<p>En la siguiente imagen, notarás que moví el TextBlock de Description al fondo de la plantilla y alineados a la derecha todos los TextBlock. El Precio también incrementó el tamaño de su fuente y el color de fuente es ahora verde.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image25.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image25_thumb.png" alt="image25" width="231" height="380" border="0" /></a></p>
<p>Hasta ahora, a menos de que tengas la necesidad de hacerlo mas presentable, tienes un aplicación trabajando. Al correrla en el emulador resultará en una aplicación que tiene un ListBox con un desplazador. Así es como aparece, basado en los cambios que he hecho.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image26.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image26_thumb.png" alt="image26" width="231" height="420" border="0" /></a></p>
<p><strong><span style="font-size: large">¿Donde esta toda la información almacenada?</span></strong></p>
<p>Ahora que podemos desplegar toda la aplicación en el emulador, la información aparece, podemos usarla y manipularla, quizá te estás preguntando donde está almacenada en nuestra aplicación, y como funciona.</p>
<p>Si le das un vistazo a la estructura de tu proyecto, notarás una nueva carpeta llamada SampleData.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image27.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image27_thumb.png" alt="image27" width="255" height="341" border="0" /></a></p>
<p>Dentro de esta carpeta, tienes un archivo llamado Muebles.xaml el cual contiene tu información actual generada. Su contenido es algo como esto:</p>
<p>&lt;!&#8211;<br />
*********    DO NOT MODIFY THIS FILE     *********<br />
This file is regenerated by a design tool. Making<br />
changes to this file can cause errors.<br />
&#8211;&gt;<br />
&lt;SampleData:Furniture xmlns:SampleData=&#8221;clr-namespace:Expression.Blend.SampleData.Furniture&#8221; xmlns=&#8221;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;&gt;<br />
&lt;SampleData:Furniture.Chairs&gt;<br />
&lt;SampleData:ChairsItem SKU=&#8221;November 1, 2011&#8243; Price=&#8221;http://bit.ly/mango31-day1&#8243; Image=&#8221;/Day18_BlendSampleData;component/SampleData/Furniture/Furniture_Files/Day1-EmulatorTools.png&#8221; Description=&#8221;Day #1 &#8211; The New Emulator Tools&#8221; /&gt;<br />
&lt;SampleData:ChairsItem SKU=&#8221;November 2, 2011&#8243; Price=&#8221;http://bit.ly/mango31-day2&#8243; Image=&#8221;/Day18_BlendSampleData;component/SampleData/Furniture/Furniture_Files/Day2-DeviceStatus.png&#8221; Description=&#8221;Day #2 &#8211; DeviceStatus&#8221; /&gt;<br />
&lt;SampleData:ChairsItem SKU=&#8221;November 3, 2011&#8243; Price=&#8221;http://bit.ly/mango31-day3&#8243; Image=&#8221;/Day18_BlendSampleData;component/SampleData/Furniture/Furniture_Files/Day3-Reminders.png&#8221; Description=&#8221;Day #3 &#8211; Alarms &amp;amp; Reminders&#8221; /&gt;<br />
&lt;SampleData:ChairsItem SKU=&#8221;November 4, 2011&#8243; Price=&#8221;http://bit.ly/mango31-day4&#8243; Image=&#8221;/Day18_BlendSampleData;component/SampleData/Furniture/Furniture_Files/Day4-Compass.png&#8221; Description=&#8221;Day #4 &#8211; Compass&#8221; /&gt;<br />
&lt;SampleData:ChairsItem SKU=&#8221;November 5, 2011&#8243; Price=&#8221;http://bit.ly/mango31-day5&#8243; Image=&#8221;/Day18_BlendSampleData;component/SampleData/Furniture/Furniture_Files/Day5-Gyroscope.png&#8221; Description=&#8221;Day #5 &#8211; Gyroscope&#8221; /&gt;<br />
&lt;SampleData:ChairsItem SKU=&#8221;November 6, 2011&#8243; Price=&#8221;http://bit.ly/mango31-day6&#8243; Image=&#8221;/Day18_BlendSampleData;component/SampleData/Furniture/Furniture_Files/Day6-Motion.png&#8221; Description=&#8221;Day #6 &#8211; Motion API&#8221; /&gt;<br />
&lt;SampleData:ChairsItem SKU=&#8221;November 7, 2011&#8243; Price=&#8221;http://bit.ly/mango31-day7&#8243; Image=&#8221;/Day18_BlendSampleData;component/SampleData/Furniture/Furniture_Files/Day7-RawCamera.png&#8221; Description=&#8221;Day #7 &#8211; Raw Camera Feed&#8221; /&gt;<br />
&lt;SampleData:ChairsItem SKU=&#8221;November 8, 2011&#8243; Price=&#8221;http://bit.ly/mango31-day8&#8243; Image=&#8221;/Day18_BlendSampleData;component/SampleData/Furniture/Furniture_Files/Day8-ContactsAPI.png&#8221; Description=&#8221;Day #8 &#8211; Contacts API&#8221; /&gt;<br />
&lt;SampleData:ChairsItem SKU=&#8221;November 9, 2011&#8243; Price=&#8221;http://bit.ly/mango31-day9&#8243; Image=&#8221;/Day18_BlendSampleData;component/SampleData/Furniture/Furniture_Files/Day9-CalendarAPI.png&#8221; Description=&#8221;Day #9 &#8211; Calendar API&#8221; /&gt;<br />
&lt;SampleData:ChairsItem SKU=&#8221;November 10, 2011&#8243; Price=&#8221;http://bit.ly/mango31-day10&#8243; Image=&#8221;/Day18_BlendSampleData;component/SampleData/Furniture/Furniture_Files/Day10-NetworkInformation.png&#8221; Description=&#8221;Day #10 &#8211; Network Information&#8221; /&gt;<br />
&lt;SampleData:ChairsItem SKU=&#8221;November 11, 2011&#8243; Price=&#8221;http://bit.ly/mango31-day11&#8243; Image=&#8221;/Day18_BlendSampleData;component/SampleData/Furniture/Furniture_Files/Day11-LiveTiles.png&#8221; Description=&#8221;Day #11 &#8211; Live Tiles&#8221; /&gt;</p>
<p>La estructura actual de la información en este archivo esta definida por el archivo Muebles.xaml.cs, el cual contiene las clases y propiedades que están mostradas aquí, también las referencias a la ubicación de nuestras imágenes.</p>
<p>//      *********    DO NOT MODIFY THIS FILE     *********<br />
//      This file is regenerated by a design tool. Making<br />
//      changes to this file can cause errors.<br />
namespace Expression.Blend.SampleData.Furniture<br />
{<br />
using System;</p>
<p>// To significantly reduce the sample data footprint in your production application, you can set<br />
// the DISABLE_SAMPLE_DATA conditional compilation constant and disable sample data at runtime.<br />
#if DISABLE_SAMPLE_DATA<br />
internal class Furniture { }<br />
#else</p>
<p>public class Furniture : System.ComponentModel.INotifyPropertyChanged<br />
{<br />
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;</p>
<p>protected virtual void OnPropertyChanged(string propertyName)<br />
{<br />
if (this.PropertyChanged != null)<br />
{<br />
this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));<br />
}<br />
}</p>
<p>public Furniture()<br />
{<br />
try<br />
{<br />
System.Uri resourceUri = new System.Uri(&#8220;/Day18_BlendSampleData;component/SampleData/Furniture/Furniture.xaml&#8221;, System.UriKind.Relative);<br />
if (System.Windows.Application.GetResourceStream(resourceUri) != null)<br />
{<br />
System.Windows.Application.LoadComponent(this, resourceUri);<br />
}<br />
}<br />
catch (System.Exception)<br />
{<br />
}<br />
}</p>
<p>private Chairs _Chairs = new Chairs();</p>
<p>public Chairs Chairs<br />
{<br />
get<br />
{<br />
return this._Chairs;<br />
}<br />
}<br />
}</p>
<p>public class ChairsItem : System.ComponentModel.INotifyPropertyChanged<br />
{<br />
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;</p>
<p>protected virtual void OnPropertyChanged(string propertyName)<br />
{<br />
if (this.PropertyChanged != null)<br />
{<br />
this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));<br />
}<br />
}</p>
<p>private string _SKU = string.Empty;</p>
<p>public string SKU<br />
{<br />
get<br />
{<br />
return this._SKU;<br />
}</p>
<p>set<br />
{<br />
if (this._SKU != value)<br />
{<br />
this._SKU = value;<br />
this.OnPropertyChanged(&#8220;SKU&#8221;);<br />
}<br />
}<br />
}</p>
<p>private string _Price = string.Empty;</p>
<p>public string Price<br />
{<br />
get<br />
{<br />
return this._Price;<br />
}</p>
<p>set<br />
{<br />
if (this._Price != value)<br />
{<br />
this._Price = value;<br />
this.OnPropertyChanged(&#8220;Price&#8221;);<br />
}<br />
}<br />
}</p>
<p>private System.Windows.Media.ImageSource _Image = null;</p>
<p>public System.Windows.Media.ImageSource Image<br />
{<br />
get<br />
{<br />
return this._Image;<br />
}</p>
<p>set<br />
{<br />
if (this._Image != value)<br />
{<br />
this._Image = value;<br />
this.OnPropertyChanged(&#8220;Image&#8221;);<br />
}<br />
}<br />
}</p>
<p>private string _Description = string.Empty;</p>
<p>public string Description<br />
{<br />
get<br />
{<br />
return this._Description;<br />
}</p>
<p>set<br />
{<br />
if (this._Description != value)<br />
{<br />
this._Description = value;<br />
this.OnPropertyChanged(&#8220;Description&#8221;);<br />
}<br />
}<br />
}<br />
}</p>
<p>public class Chairs : System.Collections.ObjectModel.ObservableCollection&lt;ChairsItem&gt;<br />
{<br />
}<br />
#endif<br />
}</p>
<p>Finalmente, tienes el folder, el cual contiene todas las imágenes que estamos usando. Dado que es usamos ambas colecciones de imágenes, las de las sillas y las de mi colección propia, encontrarás cada una de ellas en esta carpeta para ti. Como los comentarios lo muestran, si estás planeando editar esta información de ejemplo desde Blend, no lo hagas. Tus cambios serán ignorados. Estos son archivos generados de código y deberán ser tratados como tales.</p>
<p>En Resumen</p>
<p>Aquí lo tienes. Tienes una aplicación que usa la información de ejemplo que creaste en Expression Blend para poblar un ListBox usando un DataTemplate. Hay muchos lugares donde podrás encontrar esta técnica útil, así que tenlo en mente para conjuntos de información estática en lugar de usar algo mas complicado como una base de datos o un servicio web.</p>
<p>Si quieres descargar una aplicación entera de Windows Phone que use esta información de ejemplo, puedes hacerlo en el siguiente link.</p>
<p><a href="http://aminespinoza.com/materialBlog/31dias/Dia_18_InformacionEjemplo.zip">Puedes descargar el código aquí.</a></p>
<p>Mañana, Doug Mair esta de vuelta para discutir la adición de el TiltEffec a los elementos XAML dándote un poco de interacción a los gestos táctiles de tu usuario. Nos vemos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-18-usando-informacin-de-ejemplo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 17: Usando Windows Azure</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-17-usando-windows-azure/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-17-usando-windows-azure/#comments</comments>
		<pubDate>Wed, 14 Dec 2011 00:15:03 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[MVVM]]></category>
		<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/2011/12/da-17-usando-windows-azure/</guid>
		<description><![CDATA[Esta es una traducción Day 17: Using Windows Azure, puedes encontrarlo aquí en la versión original en inglés. Windows Phone + Windows Azure = Mejor unidos Algunas de las mas interesantes aplicaciones de Windows Phone utilizarán servicios de algún tipo. Esos servicios podrían ser servicios web para dar acceso a la lógica de negocio, así como en aplicaciones ASP.NET tradicionales. Esos servicios podrían también ser servicios de administración de identidad, dando un camino para manejar la autenticación de nuestra aplicación. Modo tradicional Típicamente nosotros levantamos uno o mas servidores y después desplegamos los servicios e información en ellos. Hacerlo así puede ser un proceso costoso – en tiempo y dinero –. Necesitamos tomar el tiempo para construir, configurar y asegurar los servicios. También necesitamos mantener estos servidores (hardware, fallos, reparaciones de sistema, etc.). Prediciendo cuantos servidores y que tamaño necesitamos para soportar nuestra aplicación es igualmente un reto. Comprar demasiado hará que hayamos gastado el dinero de alguien. Comprar muy pocos hará a los usuarios (y a los jefes) molestarse. Todo esto nos forza como desarrolladores a preocuparnos por la infraestructura, cuando todo lo que queremos es construir el siguiente hit de aplicaciones móviles. Modo moderno Una de las tendencias [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/17/31-days-of-mango-day-17-using-windows-azure/">Esta es una traducción Day 17: Using Windows Azure, puedes encontrarlo aquí en la versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia17.png"><img style="border-width: 0px;border-style: none;border-color: -moz-use-text-color;padding-left: 0px;padding-right: 0px;padding-top: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia17_thumb.png" alt="dia17" width="604" height="79" border="0" /></a></p>
<p>Windows Phone + Windows Azure = Mejor unidos</p>
<p>Algunas de las mas interesantes aplicaciones de Windows Phone utilizarán servicios de algún tipo. Esos servicios podrían ser servicios web para dar acceso a la lógica de negocio, así como en aplicaciones ASP.NET tradicionales. Esos servicios podrían también ser servicios de administración de identidad, dando un camino para manejar la autenticación de nuestra aplicación.</p>
<p><strong><span style="font-size: large">Modo tradicional</span></strong></p>
<p>Típicamente nosotros levantamos uno o mas servidores y después desplegamos los servicios e información en ellos. Hacerlo así puede ser un proceso costoso – en tiempo y dinero –. Necesitamos tomar el tiempo para construir, configurar y asegurar los servicios. También necesitamos mantener estos servidores (hardware, fallos, reparaciones de sistema, etc.). Prediciendo cuantos servidores y que tamaño necesitamos para soportar nuestra aplicación es igualmente un reto. Comprar demasiado hará que hayamos gastado el dinero de alguien. Comprar muy pocos hará a los usuarios (y a los jefes) molestarse. Todo esto nos forza como desarrolladores a preocuparnos por la infraestructura, cuando todo lo que queremos es construir el siguiente hit de aplicaciones móviles.</p>
<p><strong><span style="font-size: large">Modo moderno</span></strong></p>
<p>Una de las tendencias prevalecientes ahora es la de utilizar servicios (nota “servicios” y no “servidores”) otorgados por una plataforma en la nube. La plataforma Windows Azure nos da los servicios que nos permiten el despliegue de nuestros servicios web. Escribimos la aplicación y la desplegamos –y dejamos a Windows Azure hacer el resto-. Windows Azure también ofrece acceso a  servicios de almacenamiento escalables y altamente disponibles en forma de tablas, blobs y colas.</p>
<p>* Las tablas son un mecanismo semi-estructurado de almacenamiento que es capaz de almacenar información masiva muy eficiente (piensa en NoSQL, no una base de datos relacional).</p>
<p>* Los blobs esencialmente actúan como un sistema de archivos gigante para almacenar lo que tu quieras (imágenes, películas, documentos, etc.).</p>
<p>* Las colas sirven como un mecanismo de mensajes de peso ligero para pasar información entre sistemas desconectados.</p>
<p>Adicionalmente, Windows Azure ofrece un servicio de administración de identidad, los Servicios de control de acceso (ACS pos sus siglas en inglés) que nos da una forma fácil de autenticar a los usuarios vía proveedores de identidad múltiples. ACS viene pre configurado para soportar mayores redes sociales, así como Facebook, Yahoo!, Windows Live ID y Google. ACS puede igualmente dar “tap”en una empresa vía Active Directroy, Fefederation Services (ADSFv2). ACS es específicamente genial para aplicaciones móviles si es que los usuarios tienen ya un perfil social de algún tipo. De hecho, los usuarios de Windows Phone deben tener ya un Windows Live ID.</p>
<p>Hay numerosos beneficios para utilizar una plataforma como Windows Azure para crear tus aplicaciones Windows Phone. Para los iniciantes, es rápido. Puedes usar Visual Studio para escribir ambos servicios, tanto Windows Phone como Windows Azure. Una vez que el código esté escrito, el servicio puede estar disponible en internet en cuestión de un par de minutos. Usar Windows Azure puede resultar igualmente muy barato. Puedes almacenar tanta información como tu quieras comenzando por solo $0.14 USD/GB al mes. Debido a que todo el desarrollo puede ser hecho localmente en tu máquina de desarrollo, no necesitas incluso comenzar a pagar sino hasta que comience a correr tu servicio en la nube. Todo esto nos permite enfocarnos en crear aplicaciones geniales para Windows Phone y los servicios pueden hacerla mas ligera, además de no preocuparnos por la infraestructura.</p>
<p><strong><span style="font-size: large">Vamos a hacerlo</span></strong></p>
<p>Vamos a darle un vistazo rápido al flujo de como construir una muy simple aplicación para Windows Phone que cuente con servicios disponibles en la plataforma Windows Azure.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/Architecture-v3.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/Architecture-v3_thumb.png" alt="Architecture v3" width="408" height="501" border="0" /></a></p>
<p>Algunos de los aspectos principales de esta arquitectura y flujo de información incluyen:</p>
<p>1.- La necesidad de autenticar a los usuarios de la aplicación de Windows Phone. Las redes sociales mas grandes como Facebook, Windows Live, Yahoo! y Google parecen las opciones lógicas. Dejaremos que los Windows Azure Access Control Services(ACS) maneje ese trabajo (mas detalles abajo).</p>
<p>2.- Un servicio WCF REST que servirá como el sostén principal de la lógica de aplicación y provee el acceso seguro a nuestra información.</p>
<p>Una cosa para apuntar aquí es como el teléfono está accesando a la tabla y blob en Winsows Azure. La API nativa para Windows Azure es una API REST. Esto incluye acceder al almacenamiento así como a las tablas y blobs. Uno de los aspectos de seguridad del almacenamiento de Windows Azure es que todos los accesos están protegidos por llaves de acceso. La llave de acceso necesita ser enviada en cada solicitud (parte de la llamada REST) a Windows Azure. Estas llaver podrían ser mantenidas en secreto. Dado que queremos mantener nuestros secretos, un secreto, no queremos poner las llaves de acceso en el teléfono. Hacer esto dejaría a nuestra información secreta irse libremente, y eso podría ser malo para nosotros. Es posible cambiar las llaves de acceso (p. ej. si las llaves fueron comprometidas), y si cambiaron, necesitaríamos actualizar la aplicación para leer la nueva llave. Para estar seguros, creamos un servicios web proxy por el cual todas la solicitudes al almacenamiento serán canalizadas. Esto mantiene nuestra información secreta así y nos permite desarrollar un servicio en una forma muy SOA.</p>
<p>Hay dos formas básicas en las cuales podemos crear este servicio web. Los amigos geniales en microsoft, han creado el <a href="http://watwp.codeplex.com/">Windows Azure Toolkit for Windows Phone</a> el cual provee amplios recursos y ejemplos para escribir aplicaciones de Windows Phone que consuman servicios de Windows Azure. Incluido en este toolkit hay plantillas de proyectos las cuales se saltan todo el proceso para trabajar con ACS, almacenamiento (tablas, blobs y colas) e incluso recipientes para Push Notifications.</p>
<p>Sin embargo, para los propósitos de este artículo, vamos a crear un servicio WCF REST que vamos a poder consumir fácilmente en nuestra aplicación Windows Phone. El servicio WCF no solo sirve como puente para acceder al almacenamiento de Windows Azure, sino que también contendrá nuestra lógica. Si quisiéramos podríamos extender el servicio WCF para otros propósitos también –tales como alimentar una aplicación ASP.NET o incluso aplicaciones para otras plataformas móviles-. No nos meteremos mucho en varios aspectos del almacenamiento de Windows Azure aquí, dado que eso esta cubierto en profundidad en el <a href="http://msdn.microsoft.com/en-us/windowsazure/wazplatformtrainingcourse.aspx">Windows Azure Training Kit</a> (checa el módulo de Explorando el almacenamiento de Windows Azure).</p>
<p><strong><span style="font-size: large">Almacenamiento de tablas.</span></strong></p>
<p>Para comenzar, necesitamos una entidad básica que almacenaremos en el almacenamiento de tablas de Windows Azure.</p>
<p>using System;<br />
using Microsoft.WindowsAzure.StorageClient;</p>
<p>namespace Servicio.Entidades<br />
{<br />
public class Coche : TableServiceEntity<br />
{<br />
public Coche()<br />
{<br />
}</p>
<p>public Coche(string make, string modelo, int anio, string descripcion, string imagenUrl)<br />
{<br />
PartitionKey = make;<br />
RowKey = DateTime.UtcNow.Ticks.ToString();<br />
Make = make;<br />
Modelo = modelo;<br />
Anio = anio;<br />
Descripcion = descripcion;<br />
DireccionImagen = imagenUrl;</p>
<p>}</p>
<p>public string Make { get; set; }<br />
public string Modelo { get; set; }<br />
public int Anio { get; set; }<br />
public string Descripcion { get; set; }<br />
private string DireccionImagen { get; set; }</p>
<p>}<br />
}</p>
<p>Hasta aquí podemos crear un método simpl como parte de nuestro servicio WCF que pueda manejar algo de lógica (quizá validando una llave de aplicación de cualquier forma) y guardar la entidad al almacenamiento de tablas. (Nota: La clase CarDataSource es un simple envoltorio creado para simplificar algo de código, ver la clase entera en la descarga al final de este artículo).</p>
<p>public class CarService : ICarService<br />
{<br />
public void AddCar(Car car)<br />
{<br />
try<br />
{<br />
var key = ValidateApplicationKey();<br />
if (key)<br />
{<br />
var carDataSource = new CarDataSource();<br />
carDataSource.CreateCar(car);<br />
}<br />
}<br />
catch (Exception)<br />
{<br />
throw new WebFaultException&lt;string&gt;(&#8220;Failed to create a new car.&#8221;, HttpStatusCode.InternalServerError);<br />
}<br />
}</p>
<p>}</p>
<p>Con el servicio en su lugar, podemos llamarlo desde nuestra aplicación Windows Phone así como podríamos llama a cualquier otro servicio web REST. Descarga el paquete completo para ver ese código.</p>
<p>Almacenamiento Blob</p>
<p>Como se mencionó antes, el almacenamiento blob provee un medio para almacenar contenido tales como documentos PDF, imágenes, películas o cualquier otro archivo que quieras tener. Cada archivo es considerado un “blob” y los blobs residen en un contendor. Los contenedores (y además los blobs residentes) están preestablecidamente accesibles solo a aquellos que tengan la llave de acceso al almacenamiento apropiada (la misma llave usada por el almacenamiento de la tabla). Con la llave de acceso, podemos hacer cualquier operación que queramos (leer, crear, borrar, etc.) Es posible cambiar los permisos de un contenedor para permitir el acceso anónimo de lectura, el cual podría ser genial cuando, por ejemplo, necesitamos que todo el mundo vea imágenes desde nuestra aplicación Windows Phone.</p>
<p>¿Qué es lo que vamos a hacer si queremos permitir a alguien tener acceso al contenedor por un periodo de tiempo específico y solo tener un conjunto de permisos durante ese tiempo? La respuesta es usar un Firma de Acceso Compartida (SAS por sus siglas en inglés). Una firma de acceso compartida es una URL especialmente elaborada como cadena de consulta que contiene los permisos de acceso(solo crear, solo borrar, crear y borrar, etc.) y el espacio de tiempo en el cual esos permisos son válidos. Podemos crear una SAS y después dar esta a quien queramos permitirle ese acceso al almacenamiento blob. En nuestro ejemplo, podemos solicitar una Firma de Acceso Compartida desde el servicio WCF y después usar la URL de la SS pra guardar imágenes directamente desde nuestro teléfono en el almacenamiento blob de Windows Azure.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/SAS-Workflow.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/SAS-Workflow_thumb.png" alt="SAS Workflow" width="466" height="202" border="0" /></a></p>
<p>El proceso para crear una firma de acceso compartido será como sigue:</p>
<p>public Uri CreateCarImageSharedAccessSignature()<br />
{<br />
Uri signatureUri = null;</p>
<p>var key = ValidateApplicationKey();<br />
if (key)<br />
{<br />
try<br />
{<br />
CloudBlobContainer container = CreateContainer(&#8220;cars&#8221;);</p>
<p>// Set permissions on the container.<br />
var sas = container.GetSharedAccessSignature(<br />
new SharedAccessPolicy<br />
{<br />
Permissions =<br />
SharedAccessPermissions.Write |<br />
SharedAccessPermissions.List,<br />
SharedAccessStartTime = DateTime.UtcNow,<br />
SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromMinutes(5)<br />
});</p>
<p>// Trim the leading &#8216;?&#8217; to prevent there from being two in the resulting URI.<br />
var uriBuilder = new UriBuilder(container.Uri) {Query = sas.TrimStart(&#8216;?&#8217;)};<br />
signatureUri = uriBuilder.Uri;<br />
}<br />
catch (Exception ex)<br />
{<br />
throw new WebFaultException&lt;string&gt;(ex.Message, HttpStatusCode.InternalServerError);<br />
}<br />
}</p>
<p>return signatureUri;<br />
}</p>
<p><strong><span style="font-size: large">Control de acceso</span></strong></p>
<p>Ahora que tenemos las bases en posición para acceder a los servicios de almacenamiento de Windows Azure, vamos a agregar una forma de autenticar a lo usuarios de nuestra aplicación. Antes discutimos rápidamente los servicios de control de acceso de Windows Azure (ACS). ACS provee una solución de administración de identidad. Esto nos permite autenticar a los usuarios en Facebook, Yahoo!, Windows Live ID o Google sin tener que escribir el código para cada uno de ellos. Una vez autenticados, vamos a obtener una serie de respuestas que contengan información acerca del usuario (típicamente su nombre y dirección de correo). Podemos entonces usar esa información para personalizar la aplicación o manejar alguna forma de registro de usuarios (preguntar al usuario por mas información). Le elección de cual identidad de proveedor es enteramente nuestra, y es todo hecho vía configuración.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/WP7-ACS-Control-with-Yahoo-and-Google.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/WP7-ACS-Control-with-Yahoo-and-Google_thumb.png" alt="WP7 ACS Control with Yahoo and Google" width="200" height="375" border="0" /></a></p>
<p>ACS es un servicio aún simple de usar pero muy poderoso, Para aprender mas de ACS, por favor visita <a href="http://www.microsoft.com/windowsazure/learn/control-access/#introductory">http://www.microsoft.com/windowsazure/learn/control-access/#introductory</a>.</p>
<p>Es muy fácil agregar soporte ACS a una aplicación Windows Phone. Microsoft recientemente lanzó un paquete NuGet que hace el proceso demasiado simple. El paquete NuGet es genial, permitiéndote una solución muy flexible –podemos simplemente elegir agregar ACS a nuestra aplicación y hacerlo de una forma que es fácil a introduce las dependencias mínimas. Puedes encontrar el paquete NuGet buscando por “Access Control Service” en la herramienta de administración de paquetes NuGet en Visual Studio.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/ACS-NuGet-Package-in-VStudio.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/ACS-NuGet-Package-in-VStudio_thumb.png" alt="ACS NuGet Package in VStudio" width="604" height="324" border="0" /></a></p>
<p>O puedes intalar el paquete desde la consola de administración de paquetes NuGet.</p>
<p><strong>PM&gt; Install-Package Phone.Identity.AccessControl.BasePage</strong></p>
<p>De cualquier forma, se ajustarán los controles necesarios en tu aplicación Windows Phone para utilizar ACS. Una vez configurados, podrás seguir las instrucciones dadas para configurar tu aplicación Windows Phone para usar la configuración ACS. Usando el paquete NuGet para agregar soporte ACS a tu aplicación Windows Phone es considerado de alguna forma un proceso avanzado, de esta forma se queda la configuración ACS para nosotros. Hay instrucciones detalladas <a href="http://msdn.microsoft.com/en-us/wazplatformtrainingcourse_acsandwindowsphone7_topic2">aquí</a> las cuales proveen una guía detallada paso a paso para crear un nuevo espacio de nombres ACS y cualquier configuración necesaria. La tarea 2 en la guía es probablemente un buen punto de inicio, pero la guía completa es una excelente lectura también.</p>
<p><strong><span style="font-size: large">Push Notifications</span></strong></p>
<p>Si queríamos, es también muy fácil agregar soporte de notificaciones a nuestra solución. Hay un nuevo paquete NuGet que hace las configuraciones necesarias de una manera muy fácil – muy parecido a lo que vimos al agregar soporte pasa los Servicios de control de acesso. El proceso para hacer esto esta fácilmente demostrado en un video en <a href="http://channel9.msdn.com/posts/Windows-Phone-Push-Notifications-and-Windows-Azure">Channel 9</a>.</p>
<p>Los paquete NuGet para soportar las notificaciones son muy sencillas de hacer también.</p>
<p><strong>PM&gt; Install-Package Phone.Notifications.BasePage</strong> (El lado cliente/teléfono se ajusta con el registro del servicio en la nube de notificaciones).</p>
<p><strong>PM&gt; Install-Package CloudServices.Notifications</strong> (El lado servidor trabaja con el Servicio de Notificaciones de Microsoft).</p>
<p>Microsoft ha lanzado recientemente bastantes paquetes NuGet que hacen que trabajar con Windows Azure desde nuestro Windows Phone sea sencillo. Hay paquetes para ACS, push notifications, y membresías (los tradicionales nombreUsuarios/Contraseñas). Asegúrate de checar esos paquetes pues te permiten fácilmente mezclar y encontrar los elementos necesarios para tu aplicación.</p>
<p><strong><span style="font-size: large">En resumen</span></strong></p>
<p>¡Deberíamos estar completos con nuestra aplicación de Windows Phone alimentada por servicios en la nube! Aquí hemos visto cuan fácil puede ser obtener muchos servicios disponibles en la plataforma Windows Azure. Podemos simplemente crear un servicio web que nos dará acceso a nuestra lógica y sirva como puente a los servicios de almacenamiento de Windows Azure. Es también bastante sencillo agregar autenticación de Facebook, Yahoo!, Windows Live o Google a una aplicación existente gracias a los nuevos paquetes NuGet. Descarga el ejemplo completo abajo.</p>
<p>Para descargar una aplicación completa del ejemplo que cubrió a este artículo, puedes hacerlo en el siguiente enlace.</p>
<p><a href="http://aminespinoza.com/materialBlog/31dias/Dia_17_WindowsAzure.zip">Descarga el código aquí</a></p>
<p>Para iniciar con Windows Azure, regístrate para una prueba por 90 días.</p>
<p><a href="http://www.microsoft.com/windowsazure/free-trial/">http://www.microsoft.com/windowsazure/free-trial/</a>.</p>
<p><strong><span style="font-size: large">Recursos</span></strong></p>
<p>* <a href="http://www.microsoft.com/windowsazure">Windows Azure</a></p>
<p>* <a href="http://www.microsoft.com/windowsazure/sdk/">Windows Azure SDK</a></p>
<p>* <a href="http://msdn.microsoft.com/en-us/windowsazure/wazplatformtrainingcourse.aspx">Windows Azure Platform Training Kit</a></p>
<p>* <a href="http://watwp.codeplex.com/">Windows Azure Toolkit para Windows Phone 7</a></p>
<p>* <a href="http://www.wadewegner.com/2011/11/nuget-packages-for-windows-azure-and-windows-phone-developers/">Paquetes NuGet para Windows Azure y Windows Phone</a></p>
<p>* <a href="http://www.microsoft.com/windowsazure/learn/control-access/#introductory">Servicios de control de acceso de Windows Azure</a></p>
<p>* <a href="http://msdn.microsoft.com/en-us/library/windowsazure/gg433066.aspx">Como crear una cuenta de almacenamiento en Windows Azure</a></p>
<p>* <a href="http://www.microsoft.com/windowsazure/scenarios/mobile-applications">Escenarios para usar Windows Azure con tus aplicaciones móviles</a></p>
<p>* Íconos de la arquitectura de Windows Azure cortesía de <a href="http://davidpallmann.blogspot.com/">David Pallman</a>.</p>
<p>Mañana, vamos a discutir el uso de información de ejemplo, y como podemos usar Expression Blend para hacer esto increíblemente fácil para nosotros. ¡Nos vemos!</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-17-usando-windows-azure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 16: El explorador del almacenamiento aislado</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-16-el-explorador-del-almacenamiento-aislado/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-16-el-explorador-del-almacenamiento-aislado/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 05:46:52 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/2011/12/da-16-el-explorador-del-almacenamiento-aislado/</guid>
		<description><![CDATA[Esta es una traducción de Day 16: Isolated Storage Explorer, puedes encontrarlo aquí en la versión original en inglés. El SDK 7.1 incluye una nueva utilidad para los desarrolladores de Windows Phone, llamado Isolated Storage Explorer. En este artículo, deberíamos comenzar con las bases del uso del almacenamiento aislado y ver como el nuevo explorador del almacenamiento aislado se puede volver útil en aplicaciones de prueba que usan el almacenamiento aislado para archivos y directorios, apuntando a cualquiera de los runtimes, Windows Phone 7.0 y Windows Phone 7.1. Las bases Para las aplicaciones Windows Phone, el almacenamiento aislado es la solución y mantiene dentro de la caja de arena al almacenamiento aislado, para cualquier tipo de persistencia de datos (Jeff cubrió esto en el día 15 de la serie original 31 días de Windows Phone). La abstracción de acceso al sistema de archivos del sistema operativo tiene una obvia ventaja de seguridad y factibilidad mientras corramos aplicaciones de terceros. Debido a que nuestras aplicaciones realizan todo su almacenamiento de entrada y salida en el almacenamiento aislado, asegurándonos de mantenerlo acertado y limpio, eso es importante y es aquí en donde el explorador del almacenamiento aislado nos ayuda. El uso del [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/16/31-days-of-mango-day-16-isolated-storage-explorer/">Esta es una traducción de Day 16: Isolated Storage Explorer, puedes encontrarlo aquí en la versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia16.png"><img style="border-width: 0px;padding-left: 0px;padding-right: 0px;padding-top: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia16_thumb.png" alt="dia16" width="604" height="79" border="0" /></a></p>
<p>El SDK 7.1 incluye una nueva utilidad para los desarrolladores de Windows Phone, llamado Isolated Storage Explorer. En este artículo, deberíamos comenzar con las bases del uso del almacenamiento aislado y ver como el nuevo explorador del almacenamiento aislado se puede volver útil en aplicaciones de prueba que usan el almacenamiento aislado para archivos y directorios, apuntando a cualquiera de los runtimes, Windows Phone 7.0 y Windows Phone 7.1.</p>
<p><span style="font-size: large"><strong>Las bases</strong></span></p>
<p>Para las aplicaciones Windows Phone, el almacenamiento aislado es la solución y mantiene dentro de la caja de arena al almacenamiento aislado, para cualquier tipo de persistencia de datos (Jeff cubrió esto en el día 15 de la serie original <a href="http://www.jeffblankenburg.com/2010/09/30/31-days-of-windows-phone-7/">31 días de Windows Phone</a>). La abstracción de acceso al sistema de archivos del sistema operativo tiene una obvia ventaja de seguridad y factibilidad mientras corramos aplicaciones de terceros. Debido a que nuestras aplicaciones realizan todo su almacenamiento de entrada y salida en el almacenamiento aislado, asegurándonos de mantenerlo acertado y limpio, eso es importante y es aquí en donde el explorador del almacenamiento aislado nos ayuda.</p>
<p>El uso del almacenamiento aislado puede ser de tres tipos:</p>
<p>* Pares de valores/nombre persistentes por medio de la clase IsolatedStorageSettings.</p>
<p>* Archivos y directorios persistentes en el almacenamiento aislado</p>
<p>* Uso de SQL CE en la cima del almacenamiento aislado para la información relacional persistente.</p>
<p>Uno de estos, almacenar archivos y carpetas genéricos es un uso muy común del almacenamiento aislado. El emulador de Windows Phone siendo una máquina virtual, era complicado probar la precisión de nuestro sistema de Carpetas/Archivos antes del último lanzamiento del SDK 7.1 para Windows Phone Mango.</p>
<p>Ahora, con la instalación del SDK, obtenemos la utilidad del explorador del almacenamiento aislado que nos ayuda a ver desde adentro y manipular las carpetas y archivos almacenados dentro del almacenamiento aislado para checar por precisión en ambos casos, el emulador y un dispositivo desbloqueado para desarrollo. La herramienta de línea de comandos permite enlistar archivos en la raíz del almacenamiento aislado de la aplicación, también como, dentro de las carpetas o sub carpetas que fueron creados dentro del runtime de la aplicación. Además, podemos transferir una carpeta de archivos fuera del emulador/dispositivo a una carpeta designada en nuestra computadora y reemplazar las carpetas/archivos después al editar en el almacenamiento aislado. Esta es una ventaja distintiva de la capacidad de checar la estructura de archivos del almacenamiento de nuestra aplicación exactamente como se encuentra dentro en el almacenamiento aislado. También como nosotros manipulamos los contenidos de archivos y carpetas afuera del almacenamiento aislado y reemplazarlos así como regresarlos, obtenemos una oportunidad para probar como podría responder nuestra aplicación a cambios en estructuras de almacenamiento y otros casos límite. Hasta aquí la plática ¿Comenzamos con la acción?</p>
<p><strong><span style="font-size: large">Nuestra aplicación de ejemplo</span></strong></p>
<p>Vamos a comenzar con una aplicación demo de Windows Phone que crea unos archivos de ejemplo en la raíz del almacenamiento aislado, también unas carpetas con archivos en ellas. Así que Archivo &gt; Nuevo y comenzamos con un proyecto de la plantilla Pivot, con la primera sección mostrando los archivos editables en la Raíz, la segunda mostrando carpetas con archivos en ellas y la tercera es un poco molesta.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/File-New.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/File-New_thumb.png" alt="File-New" width="465" height="323" border="0" /></a></p>
<p>Mientras el inicio de la aplicación arranque, queremos un método de “todo en uno” para ajustas los archivos y carpetas de ejemplo para nosotros, comenzando al inicio del almacenamiento aislado de la aplicación. Así que aquí es donde tenemos el archivo de inicialización de App.xaml.cs para ajustar nuestra bandera de “una ocasión”:</p>
<p>using System.Windows;<br />
using Microsoft.Phone.Controls;<br />
using Microsoft.Phone.Shell;<br />
using System.Windows.Navigation;</p>
<p>namespace Dia_16_Almacenamiento<br />
{<br />
public partial class App : Application<br />
{<br />
public PhoneApplicationFrame RootFrame { get; private set; }<br />
public bool PrimerUso;</p>
<p>public App()<br />
{<br />
UnhandledException += Application_UnhandledException;<br />
InitializeComponent();<br />
InitializePhoneApplication();</p>
<p>if (System.Diagnostics.Debugger.IsAttached)<br />
{<br />
Application.Current.Host.Settings.EnableFrameRateCounter = true;<br />
PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;<br />
}</p>
<p>PrimerUso = true;<br />
}</p>
<p>//El resto del código<br />
}<br />
}</p>
<p>Ahora, nuestra página de inicio tiene una plantilla Pivot par desplegar los archivos y carpetas en el almacenamiento aislado, sin embargo, mientras corremos nuestra aplicación por primera vez, no habrá contenido en el almacenamiento aislado. Así que, aquí es como comenzamos en el C# de MainPage para agregar nuestro ejemplo de archivos y carpetas de una ocasión; esto es completamente opcional incluso si tu ya tienes contenido en el almacenamiento aislado por otros medios. Nota el uso del espacio de nombres para el almacenamiento aislado, con las clases IsolatedStorageFile y IsolatedStorageFileStream, las cuales nos ayudan al escribir archivos a la raíz del almacenamiento aislado o a los directorios ya creados.</p>
<p>using Microsoft.Phone.Controls;<br />
using System.IO.IsolatedStorage;<br />
using System.Collections.Generic;<br />
using System.IO;<br />
using System;</p>
<p>namespace Dia_16_Almacenamiento<br />
{<br />
public partial class MainPage : PhoneApplicationPage<br />
{<br />
IsolatedStorageFile almacenamientoArchivos;</p>
<p>public MainPage()<br />
{<br />
InitializeComponent();</p>
<p>almacenamientoArchivos = IsolatedStorageFile.GetUserStoreForApplication();</p>
<p>if ((App.Current as Dia_16_Almacenamiento.App).PrimerUso)<br />
CrearArchivosCarpetasIniciales();</p>
<p>(App.Current as Dia_16_Almacenamiento.App).PrimerUso = false;<br />
}</p>
<p>private void CrearArchivosCarpetasIniciales()<br />
{<br />
StreamWriter escritorArchivos = new StreamWriter(new IsolatedStorageFileStream(&#8220;ArchivoRoot1.txt&#8221;, FileMode.OpenOrCreate, almacenamientoArchivos));</p>
<p>escritorArchivos.WriteLine(&#8220;Información de prueba&#8221;);<br />
escritorArchivos.Close();<br />
escritorArchivos = new StreamWriter(new IsolatedStorageFileStream(&#8220;ArchivoRoot2.txt&#8221;, FileMode.OpenOrCreate, almacenamientoArchivos));<br />
escritorArchivos.WriteLine(&#8220;Información de prueba&#8221;);<br />
escritorArchivos.Close();</p>
<p>almacenamientoArchivos.CreateDirectory(&#8220;SubCarpeta1&#8243;);<br />
almacenamientoArchivos.CreateDirectory(&#8220;SubCarpeta2&#8243;);</p>
<p>escritorArchivos = new StreamWriter(new IsolatedStorageFileStream(&#8220;SubCarpeta1\\Archivo1SubDir1.txt&#8221;, FileMode.OpenOrCreate, almacenamientoArchivos));<br />
escritorArchivos.WriteLine(&#8220;Información de prueba&#8221;);<br />
escritorArchivos.Close();<br />
escritorArchivos = new StreamWriter(new IsolatedStorageFileStream(&#8220;SubCarpeta1\\Archivo2SubDir1.txt&#8221;, FileMode.OpenOrCreate, almacenamientoArchivos));<br />
escritorArchivos.WriteLine(&#8220;Información de prueba&#8221;);<br />
escritorArchivos.Close();<br />
escritorArchivos = new StreamWriter(new IsolatedStorageFileStream(&#8220;SubCarpeta2\\Archivo1SubDir2.txt&#8221;, FileMode.OpenOrCreate, almacenamientoArchivos));<br />
escritorArchivos.WriteLine(&#8220;Información de prueba&#8221;);<br />
escritorArchivos.Close();<br />
}<br />
}<br />
}</p>
<p>Para mas detalles y la variedad del sistema de archivos y las operaciones que puedes hacer con las clases IsolatedStorageFile e IsolatedStorageFileStream, por favor refierete a la documentación MSDN <a href="http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstoragefile.aspx">aquí</a> y <a href="http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstoragefilestream.aspx">aquí.</a></p>
<p>Así que ahora tenemos unos archivos de ejemplo en la raíz del almacenamiento aislado, también como en algunas carpetas personalizadas. Vamos a ver como podemos explorar el almacenamiento aislado y traer esos detalles a la interfaz. La búsqueda dinámica del almacenamiento aislado también va  a ayudarnos a probar cualquier cambio hecho al almacenamiento aislado desde fuera utilizando la herramienta del explorador del almacenamiento aislado. Para evitar un artículo grande, el XAML será omitido, pero esta disponible en el código para descargar. Las únicas cosas que estamos añadiendo aquí son una clase personalizada llamada SistemaDirectorio para mantener una guía de las estructuras de las carpetas y ayudar en el enlace, el código para buscar por archivos y carpetas, y los enlaces a los dos ListBox en el Pivot llamados lstRoot y lstCarpetasSistema. Así que así es como quedaría nuestro archivo modificado para la página principal.</p>
<p>using Microsoft.Phone.Controls;<br />
using System.IO.IsolatedStorage;<br />
using System.Collections.Generic;<br />
using System.IO;<br />
using System;</p>
<p>namespace Dia_16_Almacenamiento<br />
{<br />
public partial class MainPage : PhoneApplicationPage<br />
{<br />
IsolatedStorageFile almacenamientoArchivos;<br />
string[] archivosRaiz;<br />
string[] carpetas;<br />
string[] archivosCarpetas;</p>
<p>List&lt;SistemaDirectorio&gt; listDirectorySystem = new List&lt;SistemaDirectorio&gt;();</p>
<p>public class SistemaDirectorio<br />
{<br />
public string NombreCarpeta { get; set; }<br />
public string[] ArchivosEnCarpeta { get; set; }<br />
}</p>
<p>public MainPage()<br />
{<br />
InitializeComponent();</p>
<p>almacenamientoArchivos = IsolatedStorageFile.GetUserStoreForApplication();</p>
<p>if ((App.Current as Dia_16_Almacenamiento.App).PrimerUso)<br />
CrearArchivosCarpetasIniciales();</p>
<p>(App.Current as Dia_16_Almacenamiento.App).PrimerUso = false;</p>
<p>archivosRaiz = almacenamientoArchivos.GetFileNames();<br />
lstRoot.ItemsSource = archivosRaiz;</p>
<p>carpetas = almacenamientoArchivos.GetDirectoryNames();</p>
<p>foreach (string dir in carpetas)<br />
{<br />
archivosCarpetas = almacenamientoArchivos.GetFileNames(dir + &#8220;\\*&#8221;);</p>
<p>SistemaDirectorio nuevoDir = new SistemaDirectorio();<br />
nuevoDir.NombreCarpeta = dir;<br />
nuevoDir.ArchivosEnCarpeta = archivosCarpetas;</p>
<p>listDirectorySystem.Add(nuevoDir);<br />
}</p>
<p>lstCarpetasSistema.ItemsSource = listDirectorySystem;<br />
}</p>
<p>private void CrearArchivosCarpetasIniciales()<br />
{<br />
StreamWriter escritorArchivos = new StreamWriter(new IsolatedStorageFileStream(&#8220;ArchivoRoot1.txt&#8221;, FileMode.OpenOrCreate, almacenamientoArchivos));</p>
<p>escritorArchivos.WriteLine(&#8220;Información de prueba&#8221;);<br />
escritorArchivos.Close();<br />
escritorArchivos = new StreamWriter(new IsolatedStorageFileStream(&#8220;ArchivoRoot2.txt&#8221;, FileMode.OpenOrCreate, almacenamientoArchivos));<br />
escritorArchivos.WriteLine(&#8220;Información de prueba&#8221;);<br />
escritorArchivos.Close();</p>
<p>almacenamientoArchivos.CreateDirectory(&#8220;SubCarpeta1&#8243;);<br />
almacenamientoArchivos.CreateDirectory(&#8220;SubCarpeta2&#8243;);</p>
<p>escritorArchivos = new StreamWriter(new IsolatedStorageFileStream(&#8220;SubCarpeta1\\Archivo1SubDir1.txt&#8221;, FileMode.OpenOrCreate, almacenamientoArchivos));<br />
escritorArchivos.WriteLine(&#8220;Información de prueba&#8221;);<br />
escritorArchivos.Close();<br />
escritorArchivos = new StreamWriter(new IsolatedStorageFileStream(&#8220;SubCarpeta1\\Archivo2SubDir1.txt&#8221;, FileMode.OpenOrCreate, almacenamientoArchivos));<br />
escritorArchivos.WriteLine(&#8220;Información de prueba&#8221;);<br />
escritorArchivos.Close();<br />
escritorArchivos = new StreamWriter(new IsolatedStorageFileStream(&#8220;SubCarpeta2\\Archivo1SubDir2.txt&#8221;, FileMode.OpenOrCreate, almacenamientoArchivos));<br />
escritorArchivos.WriteLine(&#8220;Información de prueba&#8221;);<br />
escritorArchivos.Close();<br />
}<br />
}<br />
}</p>
<p>¿Parece mucho código? ¿Quieres probar esto por ti mismo? La forma mas fácil de que tenga sentido todo este código es descargar la solución de abajo, al final del artículo y correr la aplicación por ti mismo. Mientras corremos nuestra aplicación fresca al emulador, el método de “una ocasión” arriba nos crea los archivos de ejemplo en los directorios Raíz/Designados. Después, podemos tener el código para buscr el almacenamiento aislado por archivo y carpetas así como enlazarlos a la UI. Así que solo presiona F5 para correr la aplicación, la cual se debe ver como esto.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/Demo-App.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/Demo-App_thumb.png" alt="Demo-App" width="132" height="240" border="0" /></a><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/Directories-with-Files.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/Directories-with-Files_thumb.png" alt="Directories-with-Files" width="132" height="240" border="0" /></a><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/Root-Files.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/Root-Files_thumb.png" alt="Root-Files" width="132" height="240" border="0" /></a></p>
<p>Ahora podemos ver los archivos en el almacenamiento aislado. ¿No sería agradable si pudiéramos abrir cada archivo individual para mirar en el contenido y también ser capaces de editarlos? ¡Así que hagámoslo! De esta forma, nuestro explorador de almacenamiento aislado será capaz de checar por el contenido del archivo después de editarlo y deberíamos ser capaces de probar como se comporta nuestra aplicación cuando un archivo cualquiera es editado desde afuera del emulador. Esto puede definitivamente ser hecho por archivos dentro de una carpeta; pero bueno, entiendes la idea. Ahora, hagámoslo de lado, vamos a agregar una segunda página XAML a nuestro proyecto y permitirle abrir archivos individuales para la edición de contenido. Aquí esta la interfaz.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/Root-File-Edits.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/Root-File-Edits_thumb.png" alt="Root-File-Edits" width="192" height="349" border="0" /></a></p>
<p>Veamos como lo tenemos aquí. Primero, asignamos un manejador de evento de tipo MouseLeftButtonUp al ListBox en la página principal del Pivot, así nosotros podemos identificar cual archivo será el seleccionado por el usuario. Después, vamos a agregar este fragmento de código dentro del método.</p>
<p>private void lstRoot_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)<br />
{<br />
if (lstRoot.SelectedItem != null)<br />
{<br />
string archivoSeleccionado = lstRoot.SelectedItem.ToString();<br />
NavigationService.Navigate(new Uri(&#8220;/ContenidoArchivo.xaml?NombreArchivo=&#8221; + archivoSeleccionado, UriKind.Relative));</p>
<p>lstRoot.SelectedItem = null;<br />
}<br />
}</p>
<p>Así, esencialmente todo lo que estamos haciendo es cargar el nombre del archivo seleccionado en nuestra segunda página XAML. Ahora, vamos a ver como leemos el archivo en nuestra nueva página, ábrela para ediciones y finalmente guarda los cambios que el usuario pueda hacer.</p>
<p>using Microsoft.Phone.Controls;<br />
using System.Windows;<br />
using System.IO.IsolatedStorage;<br />
using System.IO;<br />
using System;</p>
<p>namespace Dia_16_Almacenamiento<br />
{<br />
public partial class ContenidoArchivo : PhoneApplicationPage<br />
{<br />
string nombreArchivo;</p>
<p>public ContenidoArchivo()<br />
{<br />
InitializeComponent();<br />
}</p>
<p>private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)<br />
{<br />
if (NavigationContext.QueryString.ContainsKey(&#8220;NombreArchivo&#8221;))<br />
{<br />
nombreArchivo = NavigationContext.QueryString["NombreArchivo"];<br />
txtNombreArchivo.Text = nombreArchivo;</p>
<p>LeerInformacionArchivo(nombreArchivo);<br />
}<br />
}</p>
<p>private void btnGuardar_Click(object sender, System.EventArgs e)<br />
{<br />
EditarDatosDeArchivo(nombreArchivo);<br />
}</p>
<p>private void LeerInformacionArchivo(string ruta)<br />
{<br />
using (IsolatedStorageFile appIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())<br />
{<br />
if (appIsolatedStorage.FileExists(ruta))<br />
{<br />
using (IsolatedStorageFileStream fileStream = appIsolatedStorage.OpenFile(ruta, FileMode.Open, FileAccess.Read))<br />
{<br />
using (StreamReader reader = new StreamReader(fileStream))<br />
{<br />
txtContenido.Text = reader.ReadLine();<br />
}<br />
}<br />
}<br />
}<br />
}</p>
<p>private void EditarDatosDeArchivo(string ruta)<br />
{<br />
using (IsolatedStorageFile appIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())<br />
{<br />
if (appIsolatedStorage.FileExists(ruta))<br />
{<br />
using (IsolatedStorageFileStream fileStream = appIsolatedStorage.OpenFile(ruta, FileMode.Open, FileAccess.Write))<br />
{<br />
using (StreamWriter writer = new StreamWriter(fileStream))<br />
{<br />
string editedText = txtContenido.Text.Trim();<br />
writer.Write(editedText);<br />
writer.Close();<br />
}<br />
}<br />
}<br />
}</p>
<p>this.NavigationService.Navigate(new Uri(&#8220;/DirectoryListings.xaml&#8221;, UriKind.Relative));<br />
}<br />
}<br />
}</p>
<p>Not como mientras la página carga, leemos el nombre del archivo del parámetro de consulta, como fue pasado desde nuestra página del control Pivot. Equipado solo con el nombre del archivo y una referencia al almacenamiento aislado de la aplicación, el método LeerInformacionArchivoes capaz de localizar el archivo y abrir su modo de lectura. ¿Qué sucede cuando el usuario hace algunas ediciones al contenido del archivo y presiona el botón guardar? ¡No hay problema! Simplemente llamamos al método EditarDatosDeArchivo el cual localiza y abre el archivo, esta ocasión el modo de escritura usa el objeto IsolatedStorageFileStream para escribir el contenido actualizado de vuelta al archivo.</p>
<p>Notarás que hasta ahora hemos sido capaces de crear y editar archivos de ejemplos en el almacenamiento aislado así como administrar las carpetas personalizadas. Aunque todo esto es útil, ¿No te sentirías mas confiado si pudieras ver la estructura de los archivos dentro del emulador/dispositivo para checar los archivos/carpetas y su contenido? No lo dudes mas, el explorador del almacenamiento aislado esta aquí para ayudar.</p>
<p>El uso del explorador del almacenamiento aislado</p>
<p>El explorador del almacenamiento aislado es una herramienta de línea de comandos que viene con el SDK 7.1 de Windows Phone. La utilería viene como ISETool.exe y puede ser encontrada en la ruta C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.1\Tools\IsolatedStorageExplorerTool. Así que vamos a ponernos en la línea de comandos para ello vamos a navegar a la ruta anterior de modo que podamos invocar la línea de comandos.</p>
<p>Comencemos. La herramienta ISE pude ver dentro del almacenamiento aislado del emulado o un dispositivo desbloqueado para desarrollo. La aplicación que cuenta con el almacenamiento aislado que quieres ver, necesita estar instalada en el emulador o dispositivo, pero la aplicación no necesita estar corriendo dado que el almacenamiento aislado se encuentra ahí. Así como cualquier otra línea de comandos, la herramienta ISE viene con algunas opciones sintácticas para ejecutar varios comandos. La sintaxis general es la siguiente;</p>
<p>Debemos ver cada una de las opciones por separado.</p>
<p>ISETool.exe <em>&lt;ts|rs|dir[:device-folder]&gt; &lt;xd|de&gt; &lt;Product GUID&gt; [&lt;computer-path&gt;]</em></p>
<p>Con nuestra aplicación demo de Windows Phone, hemos creado un ejemplo de “una ocasión” de archivos y carpetas personalizadas. Digamos que nuestra aplicación no está corriendo y que solo queremos tomar un vistazo dentro del almacenamiento aislado. Aquí está el comando.</p>
<p><em>ISETool.exe dir xd 04ce6350-faf0-4977-8e5b-fb288fc127c0</em></p>
<p>La secuencia es como sigue.</p>
<p>* ISETools.exe = Herramienta de línea de comandos</p>
<p>* dir = Enlista los archivos y carpetas de una carpeta de almacenamiento masivo específica o la raíz si nada es especificado.</p>
<p>* xd = Esto indica que estamos viendo en el almacenamiento aislado del emulador.</p>
<p>* de = Esto haría lo mismo que el anterior pero para un dispositivo Windows Phone</p>
<p>* &lt;Product GUID&gt; = Este es un ID específico de una aplicación de modo que la herramienta sepa a cual caja de arena del entorno mirar. El ID del producto puede ser encontrado en el WMAppManifest.xml de cada aplicación Windows Phone</p>
<p>Eso es todo. Nuestra amiga la línea de comandos enlista los archivos de ejemplo en la carpeta del almacenamiento aislado asó como las sub carpetas creadas. Si quieres echar un vistazo adentro de cualquier carpeta personalizada, aquí está el comando:</p>
<p><em>ISETool.exe dir:&#8221;SubCarpeta1&#8243; xd 04ce6350-faf0-4977-8e5b-fb288fc127c0</em></p>
<p>Notarás que cada elemento permanece en el comando anterior, pero en lugar de mirar a la raíz del almacenamiento aislado, la herramienta ahora enlista los archivos/sub carpetas que estén dentro del especificado.</p>
<p>Ahora, la parte realmente divertida ¿Qué pasa si queremos obtener el contenedor completo del almacenamiento aislado de una aplicación Windows Phone fuera del emulador o dispositivo? Bueno, se puede, aquí está como:</p>
<p><em>SETool.exe ts xd 04ce6350-faf0-4977-8e5b-fb288fc127c0 &#8220;C:\Users\Sami\Desktop&#8221;</em></p>
<p>Dos cosas fueron nuevas aquí:</p>
<p>* ts = Take Snapshot. Como el nombre lo sugiere, esto toma una captura de las carpetas y archivos de la raíz como se sepecifica.</p>
<p>* &lt;Computer Path&gt; = Esto simplemente dice al explorador del almacenamiento aislado que copie el almacenamiento aislado del dispositivo/emulador en una carpeta específica de la computadora.</p>
<p>Esto copia todos los contenidos de raíz del almacenamiento aislado específico en una carpeta llamada IsolatedStorage en la ruta especificada de la computadora; este folder y sus contenidos serán sobre escritos si existían previamente. El mismo comando puede copar solo los contenidos de una sub carpeta del almacenamiento aislado si una ruta es especificada. Si tu aplicación apunta a la versión 7.1 de Windows Phone, la carpeta resultado “IsolatedStorage” tendrá una carpeta llamada “Shared”, esto aloja la información de transferencia en segundo plano y el ShellContent para los live Tiles secundarios. Aquí esta como se verían si fueran copiados al escritorio de la máquina.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/Transfers-out-of-Emulator1_thumb.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/Transfers-out-of-Emulator1_thumb_thumb.png" alt="Transfers-out-of-Emulator1_thumb" width="527" height="160" border="0" /></a></p>
<p>&nbsp;</p>
<p>Ahora, acerca de reemplazar los archivos/carpetas de nuevo de tu computadora al almacenamiento aislado. Esto es genial para pruebas dado que te permite inspeccionar como manejaría tu aplicación los cambios en el contenido del archivo, así como cambios en la estructura de las carpetas. Aquí está el comando:</p>
<p><em>ISETool.exe rs xd 04ce6350-faf0-4977-8e5b-fb288fc127c0 &#8220;C:\Users\Sami\Desktop\IsolatedStore&#8221;</em></p>
<p>¿Qué hay de nuevo?</p>
<p>* rs = Restore Snapshot. Como en nombre lo sugiere, esto reemplaza los archivos y carpetas en el almacenamiento aislado en el emulador/dispositivo con los contenidos correspondientes a las carpetas de tu computadora. Nota que al regresar los contenidos modificados de donde fueron extraídos del almacenamiento aislado, tuvimos que agregar el “IsolatedStore” a nuestra la ruta fuente de nuestra computadora.</p>
<p>Míranos agregar un archivo de texto aleatorio al “IsolatedStore”, el cual corresponde a la raíz del almacenamiento aislado:</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/File-Additions.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/File-Additions_thumb.png" alt="File-Additions" width="532" height="326" border="0" /></a></p>
<p>Después de correr la línea de comandos por medio del explorador del almacenamiento aislado, el archivo mágicamente (ok, de hecho no) se muestra en el espacio correspondiente. Y para asegurarnos, nuestra aplicación Windows Phone actualiza los cambios en la estructura de la carpeta, además del contenido correcto del archivo en la siguiente ejecución:</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/File-Transfer-into-Emulator.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/File-Transfer-into-Emulator_thumb.png" alt="File-Transfer-into-Emulator" width="177" height="321" border="0" /></a><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/File-Contents-from-Desktop.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/File-Contents-from-Desktop_thumb.png" alt="File-Contents-from-Desktop" width="172" height="313" border="0" /></a></p>
<p>Y puedes ver la salida de todos los comandos que corrimos hasta ahora, solo para saber exactamente que esperar:</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/ISE-Command-Runs.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/ISE-Command-Runs_thumb.png" alt="ISE-Command-Runs" width="436" height="354" border="0" /></a></p>
<p><strong><span style="font-size: large">En resumen</span></strong></p>
<p>¡Eso es todo! Ahora, sin importar que archivos/carpetas estés almacenando en el almacenamiento aislado para tus aplicaciones Windows Phone, puedes ahora usar el almacenamiento aislado para estar completamente confiado con la estructura de las carpetas y contenido de los archivos de tu almacenamiento. Vamos a construir algunas aplicaciones para Windows Phone ¿Les parece?</p>
<p>Adios!</p>
<p>Para descargar una aplicación completa en la que puedas usar el almacenamiento aislado puedes hacerlo en el vínculo siguiente.</p>
<p><a href="http://aminespinoza.com/materialBlog/31dias/Dia_16_Almacenamiento.zip">Puedes descargar el código aquí.</a></p>
<p>Mañana, vamos a ver otro tema genial, usando Windows Azure para soportar tu aplicación Windows Phone. Nos vemos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-16-el-explorador-del-almacenamiento-aislado/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 15: La barra de progreso</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-15-la-barra-de-progreso/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-15-la-barra-de-progreso/#comments</comments>
		<pubDate>Sun, 11 Dec 2011 06:01:15 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/2011/12/da-15-la-barra-de-progreso/</guid>
		<description><![CDATA[Este artículo es una traducción de Day 15: ProgressBar, puedes encontrarlo aquí en la versión original en inglés. En cualquier momento que tengas una operación que tomará mas de un par de segundos para ser completada, es una buena idea dejar que tus usuarios sepan que sus aplicaciones están aún progresando y no solo se detuvieron en un ciclo para siempre. ¿Cómo podrías dejar a tus usuarios saber que es lo que esta pasando? Bueno, puedes mostrarles un mensaje de texto con el número de bytes descargados o segundos que restan para una operación. Pero comúnmente el usuario no se preocupa por tal nivel de detalle. La barra de progreso es una gran forma de mostrar a tus usuarios que una operación esta en progreso, sin molestarlos con tantos detalles. Una barra de progreso pude mostrar esta información en dos formas diferentes: Modo determinado e indeterminado. Modo indeterminado El modo indeterminado es cuando no puedes determinar cuanto tomará la operación para ser completada. Por ejemplo, si te estás conectando a un servidor, no necesitas saber cuando será completada la operación. El modo indeterminado de la barra de progreso muestra su estado mostrando puntos moviéndose de izquierda a derecha en una [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/15/31-days-of-mango-day-15-the-progress-bar/">Este artículo es una traducción de Day 15: ProgressBar, puedes encontrarlo aquí en la versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia15.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="dia15" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia15_thumb.png" width="604" height="79"></a></p>
<p>En cualquier momento que tengas una operación que tomará mas de un par de segundos para ser completada, es una buena idea dejar que tus usuarios sepan que sus aplicaciones están aún progresando y no solo se detuvieron en un ciclo para siempre.</p>
<p>¿Cómo podrías dejar a tus usuarios saber que es lo que esta pasando? Bueno, puedes mostrarles un mensaje de texto con el número de bytes descargados o segundos que restan para una operación. Pero comúnmente el usuario no se preocupa por tal nivel de detalle. La barra de progreso es una gran forma de mostrar a tus usuarios que una operación esta en progreso, sin molestarlos con tantos detalles. Una barra de progreso pude mostrar esta información en dos formas diferentes: Modo determinado e indeterminado.</p>
<p><strong><font size="5">Modo indeterminado</font></strong></p>
<p>El modo indeterminado es cuando no puedes determinar cuanto tomará la operación para ser completada. Por ejemplo, si te estás conectando a un servidor, no necesitas saber cuando será completada la operación. El modo indeterminado de la barra de progreso muestra su estado mostrando puntos moviéndose de izquierda a derecha en una animación. Esto es genial para mostrar que algo esta sucediendo, pero no le da al usuario una indicación del monto del progreso. Para hacer que una barra de progreso se muestre de manera indeterminada, selecciona el CheckBox de la propiedad <strong>IsIndeterminate </strong>de la barra de progreso.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb5.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="image_thumb5" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb5_thumb.png" width="344" height="43"></a></p>
<p><strong><font size="5">Modo determinado</font></strong></p>
<p>Si puedes determinar de manera aproximada cuanto tardará la operación&nbsp; en ser completada, usar el modo determinado para hacer a tu usuario saber el porcentaje que queda en la operación. Por ejemplo, si tu estás descargando un archivo, conoces el tamaño total del archivo, mientras la descarga continúe, obtienes actualizaciones que te digan el número de bytes descargados al momento.</p>
<p>Puedes entonces dividir el tamaño del archivo total por los bytes descargados para obtener el porcentaje de avance. Este código muestra un ejemplo de como podría ser hecho esto.</p>
<p>progressBar1.Value = (float)bytesRead / TotalFileSize;</p>
<p>Si quieres mostrarle a tu usuario el porcentaje de progreso que está tomando una operación, despliegas la información en una barra de progreso. Para mostrar el modo <strong>Determinado</strong>, elimina la selección <strong>IsIndeterminate</strong>&nbsp; y ajusta el valor para que se correlacione en el avance del porcentaje.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb4.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="image_thumb4" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb4_thumb.png" width="344" height="49"></a></p>
<p>Con Windows Phone 7.5 Mango, tienes dos opciones para la barra de progreso:</p>
<p>1) <strong>Progress Bar</strong> – Un control que puedes poner en donde quieras en tu página Silverlight.</p>
<p>2) <strong>Progress indicator</strong> – Un control que reside en la bandeja del sistema.</p>
<p>Vamos a comenzar hablando acerca de la ProgressBar.</p>
<p><strong><font size="5">ProgressBar</font></strong></p>
<p>La barra de progreso no está en la caja de herramientas de manera preestablecida, así que tendrás que agregarla a la pestaña en Visual Studio. Para hacer esto, da clic derecho en la caja de herramientas y selecciona “Escoger elementos…”. Busca entonces “ProgressBar” y seleccionala.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image002_thumb2.jpg"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="clip_image002_thumb2" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image002_thumb2_thumb.jpg" width="245" height="280"></a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image004_thumb3.jpg"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="clip_image004_thumb3" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image004_thumb3_thumb.jpg" width="409" height="293"></a></p>
<p>Después de una pequeña espera, verás una “Barra de progreso” en la caja de herramientas.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb8.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="image_thumb8" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/image_thumb8_thumb.png" width="277" height="149"></a></p>
<p>Ahora puedes arrastrar la barra de progreso en&nbsp; las páginas del XAML de tu Windows Phone. Esto agregará código como el siguiente en tu archivo XAML.</p>
<p>&lt;ProgressBar Name=&#8221;progressBar1&#8243; Value=&#8221;0&#8243;&gt;&lt;/ProgressBar&gt;
<p>Puedes ver el conjunto de propiedades del control como lo desees:</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image006_thumb1.jpg"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="clip_image006_thumb1" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image006_thumb1_thumb.jpg" width="328" height="288"></a></p>
<p>Puedes usar esta nueva <strong>ProgressBar</strong> en el modo determinado, asegúrate de que <strong>IsIndeterminate</strong> no esté seleccionada. Después puedes ajustar las propiedades <strong>Minimum</strong>, <strong>Maximum</strong> y <strong>Value</strong> del control.</p>
<p>En el código C# cuando tu operación este progresando, cambias la propiedad <strong>Value</strong> al valor deseado entre <strong>Minimum</strong> y <strong>Maximum</strong>. La barra de progreso se asegurará que que <strong>Value</strong> este siempre entre <strong>Minimum</strong> y <strong>Maximum. </strong>Puedes llenar la barra de progreso simplemente incrementando el valor basado en el progreso de tu operación.</p>
<p><strong><font size="5">Indicador de progreso</font></strong></p>
<p>Otra forma para mostrar progreso es usando un <strong>Progress Indicator</strong>. Este control aparece en la bandeja del sistema como se muestra abajo. Aquí hay un par de imágenes de la bandeja del sistema y el indicador de progreso en la bandeja del sistema.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image008_thumb2.jpg"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="clip_image008_thumb2" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image008_thumb2_thumb.jpg" width="344" height="100"></a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image010_thumb4.jpg"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="clip_image010_thumb4" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image010_thumb4_thumb.jpg" width="348" height="110"></a></p>
<p>Para usar el Progress Indicator debes agregar la sentencia using en tu código C#.</p>
<p>using Microsoft.Phone.Shell;</p>
<p>Puedes crear un Progress Indicator y agregarlo a la bandeja del sistema como esto.</p>
<p>&nbsp;</p>
<p>ProgressIndicator progressIndicator = new ProgressIndicator() {
<p>IsVisible = true, IsIndeterminate = false,
<p>Text = &#8220;Descargando archivos &#8230;&#8221; };
<p>SystemTray.SetProgressIndicator(this, progressIndicator);
<p>Nota que la propiedad <strong>Value</strong> del <strong>Progress Indicator</strong> debe siempre estar entre 0 y 1. Donde al igual que la <strong>ProgressBar</strong>, la propiedad <strong>Value</strong> debe estar entre <strong>Minimum</strong> y <strong>Maximum</strong>.</p>
<p>Aplicación de ejemplo</p>
<p>Dia_15_BarraDeProgreso es una aplicación que prueba ambos controles:</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image012_thumb2.jpg"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="clip_image012_thumb2" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image012_thumb2_thumb.jpg" width="217" height="390"></a></p>
<p>Aquí esta una vista general del código:</p>
<p>El código XAML muestra abajo todos los controles que usaremos en nuestra aplicación. Hay un <strong>ProgressBar</strong> para mostrar el progreso, un para de botones para iniciar o detener un temporizador para la simulación y un <strong>Slider</strong> el cual será utilizado para cambiar el valor del <strong>ProgressIndicator</strong>.</p>
<p>&lt;phone:PhoneApplicationPage <br />&nbsp;&nbsp;&nbsp; x:Class=&#8221;Dia_15_BaraDeProgreso.MainPage&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns=&#8221;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:x=&#8221;http://schemas.microsoft.com/winfx/2006/xaml&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:phone=&#8221;clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:shell=&#8221;clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:d=&#8221;http://schemas.microsoft.com/expression/blend/2008&#8243;<br />&nbsp;&nbsp;&nbsp; xmlns:mc=&#8221;http://schemas.openxmlformats.org/markup-compatibility/2006&#8243;<br />&nbsp;&nbsp;&nbsp; mc:Ignorable=&#8221;d&#8221; d:DesignWidth=&#8221;480&#8243; d:DesignHeight=&#8221;768&#8243;<br />&nbsp;&nbsp;&nbsp; FontFamily=&#8221;{StaticResource PhoneFontFamilyNormal}&#8221;<br />&nbsp;&nbsp;&nbsp; FontSize=&#8221;{StaticResource PhoneFontSizeNormal}&#8221;<br />&nbsp;&nbsp;&nbsp; Foreground=&#8221;{StaticResource PhoneForegroundBrush}&#8221;<br />&nbsp;&nbsp;&nbsp; SupportedOrientations=&#8221;Portrait&#8221; Orientation=&#8221;Portrait&#8221;<br />&nbsp;&nbsp;&nbsp; shell:SystemTray.IsVisible=&#8221;True&#8221;&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;Grid x:Name=&#8221;LayoutRoot&#8221; Background=&#8221;Transparent&#8221;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Grid.RowDefinitions&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;RowDefinition Height=&#8221;Auto&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;RowDefinition Height=&#8221;*&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/Grid.RowDefinitions&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel x:Name=&#8221;TitlePanel&#8221; Grid.Row=&#8221;0&#8243; Margin=&#8221;12,17,0,28&#8243;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock x:Name=&#8221;ApplicationTitle&#8221; Text=&#8221;LA LIGA SILVERLIGHT&#8221; Style=&#8221;{StaticResource PhoneTextNormalStyle}&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock x:Name=&#8221;PageTitle&#8221; Text=&#8221;barra&#8221; Margin=&#8221;9,-7,0,0&#8243; Style=&#8221;{StaticResource PhoneTextTitle1Style}&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/StackPanel&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Grid x:Name=&#8221;ContentPanel&#8221; Grid.Row=&#8221;1&#8243; Margin=&#8221;12,0,12,0&#8243;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock FontSize=&#8221;36&#8243; Foreground=&#8221;#FFDBE6FF&#8221; x:Name=&#8221;txtProgreso&#8221; Text=&#8221;Progress Indicator&#8221; TextWrapping=&#8221;Wrap&#8221; FontWeight=&#8221;Bold&#8221; /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock Text=&#8221;Arrastra el slider para ver el progreso en la bandeja del sistema.&#8221; FontSize=&#8221;20&#8243; TextWrapping=&#8221;Wrap&#8221; Foreground=&#8221;#FFDBE6FF&#8221; /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Slider x:Name=&#8221;sldProgreso&#8221; Width=&#8221;Auto&#8221; Maximum=&#8221;1&#8243; LargeChange=&#8221;0.1&#8243; SmallChange=&#8221;0.01&#8243; ValueChanged=&#8221;sldProgreso_ValueChanged&#8221; Margin=&#8221;50,0&#8243; /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock FontSize=&#8221;36&#8243; Text=&#8221;Progress Bar&#8221; TextWrapping=&#8221;Wrap&#8221; Foreground=&#8221;#FFDBE6FF&#8221; Margin=&#8221;0,50,0,0&#8243; FontWeight=&#8221;Bold&#8221; /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Button x:Name=&#8221;btnIniciar&#8221; Content=&#8221;Iniciar temporizador&#8221; Click=&#8221;btnIniciar_Click&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Button x:Name =&#8221;btnDetener&#8221; Content=&#8221;Reiniciar el temporizador&#8221; Click=&#8221;btnDetener_Click&#8221;&gt;&lt;/Button&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ProgressBar x:Name=&#8221;barraProgreso&#8221; Value=&#8221;0&#8243; IsIndeterminate=&#8221;False&#8221; Height=&#8221;50&#8243; SmallChange=&#8221;.5&#8243; LargeChange=&#8221;10&#8243;&gt;&lt;/ProgressBar&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/StackPanel&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/Grid&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/Grid&gt;<br />&lt;/phone:PhoneApplicationPage&gt;</p>
<p>Aquí está el código C#. Vamos a ir viendo lo que el código va haciendo.</p>
<p>Para comenzar, ajustamos las sentencias using para los controles que vamos a usar. Para el <strong>ProgressIndicator</strong>, debemos usar <strong>Microsoft.Windows.Shell</strong>. Después dentro de la clase que fue creada para la página, declaramos nuestras variables globales. Un <strong>ProgressIndicator</strong> es creado cuando después lo pongamos dentro de la bandeja del sistema. Creamos un <strong>DispatcherTimer</strong> llamado temporizador el cual será utilizado para simular una operación determinada. En el constructor ponemos el recién creado <strong>ProgressIndicator</strong> dentro de la bandeja de sistema y ajustamos el temporizador para que utilice el método <strong>temporizador_Tick</strong> cada 5000 ticks.</p>
<p>using System;<br />using System.Windows;<br />using System.Windows.Threading;<br />using Microsoft.Phone.Shell;<br />using Microsoft.Phone.Controls;</p>
<p>namespace Dia_15_BaraDeProgreso<br />{<br />&nbsp;&nbsp;&nbsp; public partial class MainPage : PhoneApplicationPage<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ProgressIndicator indicadorProgreso = new ProgressIndicator() { IsVisible = true, IsIndeterminate = false, Text = &#8220;Descargando archivo &#8230;&#8221; };<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DispatcherTimer temporizador = new DispatcherTimer();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public MainPage()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitializeComponent();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SystemTray.SetProgressIndicator(this, indicadorProgreso);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temporizador = new DispatcherTimer { Interval = new TimeSpan(5000) };<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temporizador.Tick += temporizador_Tick;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temporizador.Stop();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />}</p>
<p>Cuando el temporizador arranque y el método <strong>temporizador_Tick</strong> sea llamado, agregamos un valor a la propiedad Value de la <strong>ProgressBar</strong> para hacer parecer que la operación esta haciendo un progreso.</p>
<p>Abajo ese método estan los manejadores de eventos para los eventos de los botones. Ellos comienzan e inicializan el temporizador de modo que podemos simular una larga operación indeterminada. Al presionar el botón de inicio reinicia la propiedad <strong>Value</strong> de <strong>barraProgreso</strong> a 0, pero en esta ocasión detenemos igualmente el temporizador de avanzar.</p>
<p>El último método en&nbsp; la clase es el manejador de eventos <strong>sldProgreso_ValueChanged </strong>que es llamado cuando el slider es movido. Usaremos el valor del slider para posicionar el <strong>indicadorProgreso</strong>.</p>
<p>using System;<br />using System.Windows;<br />using System.Windows.Threading;<br />using Microsoft.Phone.Shell;<br />using Microsoft.Phone.Controls;</p>
<p>namespace Dia_15_BaraDeProgreso<br />{<br />&nbsp;&nbsp;&nbsp; public partial class MainPage : PhoneApplicationPage<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ProgressIndicator indicadorProgreso = new ProgressIndicator() { IsVisible = true, IsIndeterminate = false, Text = &#8220;Descargando archivo &#8230;&#8221; };<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DispatcherTimer temporizador = new DispatcherTimer();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public MainPage()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitializeComponent();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SystemTray.SetProgressIndicator(this, indicadorProgreso);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temporizador = new DispatcherTimer { Interval = new TimeSpan(5000) };<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temporizador.Tick += temporizador_Tick;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temporizador.Stop();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void temporizador_Tick(object sender, EventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; barraProgreso.Value += barraProgreso.SmallChange;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void btnIniciar_Click(object sender, System.Windows.RoutedEventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; barraProgreso.Value = 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temporizador.Start();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void btnDetener_Click(object sender, System.Windows.RoutedEventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; barraProgreso.Value = 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temporizador.Stop();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void sldProgreso_ValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs&lt;double&gt; e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; indicadorProgreso.Value = e.NewValue;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />}</p>
<p><strong><font size="5">En resumen</font></strong></p>
<p>Así es como puedes usar una barra de progreso en una aplicación Windows Phone Mango. En unas pocas líneas de código puedes rápidamente agregar una barra de progres bien elaborada a cualquier control de una aplicación Silverlight for Windows Phone. Puedes crear un <strong>ProgressIndicator</strong> al cual puedes poner en la bandeja del sistema, o puedes crear una <strong>ProgressBar</strong> la cual puedes desplegar en cualquier lado de la página de la aplicación.</p>
<p>Las barras de progreso son esenciales para aplicaciones con operaciones prolongadas. Dan al usuario una sensación de que la aplicación esta trabajando para ellos y los regresará al lugar original cuando la operación se complete. Tus usuarios se sentirán mejor al esperar si son informados del progreso de la aplicación.</p>
<p>Para descargar la versión de la aplicación que fue creada en este artículo, puedes hacerlo en el siguiente enlace.</p>
<p><a href="http://aminespinoza.com/materialBlog/31dias/Dia_15_BaraDeProgreso.zip">Puedes descargar el código aquí.</a></p>
<p>Mañana, vamos a ver el Explorador del almacenamiento aislado, el cual te permite ver e inspeccionar la información que has almacenado en el Isolated Storage en tu emulador. Samidip Basu te mostrará el como y porque de este nuevo elemento. Nos vemos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-15-la-barra-de-progreso/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 14: Usando OData</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-14-usando-odata/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-14-usando-odata/#comments</comments>
		<pubDate>Sat, 10 Dec 2011 19:10:26 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/2011/12/da-14-usando-odata/</guid>
		<description><![CDATA[Este artículo es una traducción de Day 14: Using OData, puedes encontrarlo aquí en la versión original en inglés. Este artículo fue escrito por el autor invitado Chris Woodruff. Puedes encontrar a Chris en Twitter como @cwoodruff. Chris es también participante del podcast Deep Fried Bytes, así que puedes darle un vistazo ahí también. Hoy vamos a estar viendo como consumir información de un feed OData y también ajustar tareas completas de información que las aplicaciones Windows Phone necesitan ajustar. ¿Qué es OData? El enunciado oficial para Open Data Protocol (OData) que es un protocolo web para consultar y actualizar información que da una forma de desbloquear tu información y liberarla de los silos que existen en las aplicaciones hoy. Realmente lo que significa es que podemos seleccionar, guardar, borrar y actualizar información desde nuestras aplicaciones así como lo hemos estado haciendo en bases de datos SQL por años. El beneficio es la flexibilidad de ajustes y librerías que Microsoft ha creado para los desarrolladores de aplicaciones de Windows Phone Mango. El beneficio viene de el hecho de que OData tiene un estándar que permite un claro entendimiento de la información gracias a los metadatos del elemento. Detrás de cámaras, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/14/31-days-of-mango-day-14-using-odata/">Este artículo es una traducción de Day 14: Using OData, puedes encontrarlo aquí en la versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia14.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="dia14" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia14_thumb.png" width="604" height="79"></a></p>
<p>Este artículo fue escrito por el autor invitado Chris Woodruff. Puedes encontrar a Chris en Twitter como @cwoodruff. Chris es también participante del podcast Deep Fried Bytes, así que puedes darle un vistazo ahí también.</p>
<p>Hoy vamos a estar viendo como consumir información de un feed OData y también ajustar tareas completas de información que las aplicaciones Windows Phone necesitan ajustar.</p>
<p><font size="5"><strong>¿Qué es OData?</strong></font></p>
<p>El enunciado oficial para Open Data Protocol (OData) que es un protocolo web para consultar y actualizar información que da una forma de desbloquear tu información y liberarla de los silos que existen en las aplicaciones hoy. Realmente lo que significa es que podemos seleccionar, guardar, borrar y actualizar información desde nuestras aplicaciones así como lo hemos estado haciendo en bases de datos SQL por años. El beneficio es la flexibilidad de ajustes y librerías que Microsoft ha creado para los desarrolladores de aplicaciones de Windows Phone Mango. El beneficio viene de el hecho de que OData tiene un estándar que permite un claro entendimiento de la información gracias a los metadatos del elemento.</p>
<p>Detrás de cámaras, mandamos solicitudes OData a un servidor web que cuenta con el feed OData a través de solicitudes HTTP usando el protocolo para OData. Puedes leer mas de esto <a href="http://www.odata.org/">aquí.</a></p>
<p><strong><font size="5">Ajustar OData para tu aplicación Mango</font></strong></p>
<p>Ahora con el SDK 7.1 de Windows Phone, tenemos una gran experiencia para usar OData en nuestras aplicaciones. En a versión previa del SDK, teníamos que usar una herramienta externa para generar nuestra clases proxy basadas en un feed OData, primero creamos un nuevo proyecto para aplicación de Silverlight for Windows Phone Databound Application.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image002_thumb.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="clip_image002_thumb" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image002_thumb_thumb.png" width="479" height="331"></a></p>
<p>Hemos creado un proyecto con los ajustes iniciales como se muestran en pantalla.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image003.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="clip_image003" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image003_thumb.png" width="330" height="281"></a></p>
<p>Para importar y ver tu feed OData accesible desde tu proyecto, necesitarás agregar el feed a través de Add Service Reference in Visual Studio 2010</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image004_thumb.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="clip_image004_thumb" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image004_thumb_thumb.png" width="330" height="279"></a></p>
<p>La opción de agregar una nueva referencia te será presentada e ingresarás la URL para el feed OData con el que deseas trabajar como se muestra abajo. Presiona el botón Go&nbsp; en Visual Studio 2010 para obtener la información acerca del feed y finalmente presiona OK para añadir el feed OData a tu proyecto.</p>
<p>Usaremos este feed para este proyecto con estadísticas históricas de baseball.</p>
<p><a href="http://www.baseball-stats.info/OData/baseballstats.svc/">http://www.baseball-stats.info/OData/baseballstats.svc/</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image006_thumb.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="clip_image006_thumb" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image006_thumb_thumb.png" width="422" height="341"></a></p>
<p>Ahora tienes tu clase proxy que te permitirá trabajar con la información proveniente tu feed OData. A agregar el feed OData a tu proyecto, también ha agregado la referencia al ensamblado&nbsp; System.Data.Services.Client que te permitirá trabajar con el feed de OData e información.</p>
<p><font size="5"><strong>La clase DataServiceCollection</strong></font></p>
<p>El nombre de espacio System.Data.Services.Client es como un conjunto mágico de clases que te permiten hacer muchas cosas emocionantes con tu información OData. No iremos mas allá del espacio de nombres DataServiceCollection pero espero que explores la rica colección de clases en algún punto.</p>
<p>La clase DataServiceCollection es la clase que le dará a tu proyecto y a ti como desarrollador, la oportunidad de ajustar un arreglo completo de trabajo usando los datos y metadatos de tu OData. Tendrás capacidades completas a tu disposición basado en las reglas que fueron usadas para desarrollar el feed OData. Lo más que OData te permitirá son las operaciones CRUD (Crear, Leer, Actualizar y Borrar por sus siglas en inglés) en la información. En este artículo solo veremos la funcionalidad Read de DataServiceCollection para permitirte obtener y enlazar datos dentro de tu aplicación.</p>
<p><font size="5"><strong>Obtener Información de tu fedd OData</strong></font></p>
<p>Vamos a meternos en el trabajo de lleno y comenzar. Tendrás un MainPage.xaml en tu proyecto que fue creado como la página de inicio para tu aplicación como se muestra abajo. He actualizado las propiedades ApplicationTitle y PageTitle para tener una mejor descripción de la aplicación.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image008_thumb.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="clip_image008_thumb" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image008_thumb_thumb.png" width="210" height="387"></a></p>
<p>Agrega los siguientes enunciados using a tu proyecto. Esto te permitirá usar la clase DataServiceCollection también como la referencia del servicio que ajustamos antes.</p>
<p>using System.Data.Services.Client;<br />using Dia_14_OData.ServicioDatos;</p>
<p>Crear las siguientes variables privadas en el código MainPage.xaml.cs para el Main Page. Esto te dará una referencia a tu feed OData vía la variable contexto, la colección de los equipos de la Liga Mayor de Baseball (equipos) que existe en el feed OData y finalmente el equipo seleccionado (equipoSeleccionado) que permitirá al proyecto mostrar una lista de los años que el equipo seleccionado ha jugado.</p>
<p>private TeamFranchise equipoSeleccionado;<br />private BaseballStatsEntities contexto;</p>
<p>&nbsp;</p>
<p>Necesitaremos obtener la información obtenida del feed OData y después implementaremos el evento Loaded para el MainPage como se muestra a continuación.</p>
<p>private void MainPage_Loaded(object sender, RoutedEventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; contexto = new BaseballStatsEntities(new Uri(&#8220;http://www.baseball-stats.info/OData/baseballstats.svc/&#8221;));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; App.ViewModel.Equipos.LoadCompleted += Equipos_Loaded;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var consulta = from t in contexto.TeamFranchise<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; orderby<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t.franchName<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where t.active == &#8220;Y&#8221;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select t;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; App.ViewModel.Equipos.LoadAsync(consulta);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>Me han preguntado porque la necesidad de dar de nuevo la URI del feed, si es que ya lo hicimos al momento de agregar la referncia al servicio. Lo hicimos, pero esa referencia a la URI del feed fue solo para permitir la generación de las clases proxy basadas en los metadatos del feed. Necesitamos siempre dar la URI del servicio del feed OData cuando creemos nuestro contexto de datos.</p>
<p>Inicializamos la variable privada equipos como una DataServiceCollection&lt;T&gt; genérica del tipo TeamFranchise la cual es un tipo de entidad que existe en el feed OData. Asociamos el manejador de eventos Equipos.LoadCompleted con un nuevo método y finalmente obtendremos nuestra información utilizando LINQ. Una de las grandes razones para usar la clase DataServiceCollection&lt;T&gt; es que permite crear sentencias LINQ para consultar información así como enlazarla directamente a nuestras vistas XAML (veremos eso en la siguiente sección).</p>
<p>La acción final que debemos colocar es obtener la información a partir de la sentencia LINQ. La clase DataServiceCollection de manera asíncrona obtendrá la información para nosotros también. Recuerda que así como en Silverlight, nuestros proyectos de Windows Phone deben realizar acciones asíncronas.</p>
<p>Necesitamos tener un método que cargará nuestra informacón en un DataContext que hemos creado.</p>
<p>private void Equipos_Loaded(object sender, LoadCompletedEventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (e.Error == null)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (App.ViewModel.Equipos.Continuation != null)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; App.ViewModel.Equipos.LoadNextPartialSetAsync();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Ajusta el DataContext del ListBox a los datos de los equipos.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.LayoutRoot.DataContext = App.ViewModel.Equipos;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show(string.Format(&#8220;Tenemos un error: {0}&#8221;, e.Error.Message));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>Ahora tenemos nuestros equipos de baseball cargados en la variable Equipos y lista para ser enlazada. Antes de mostrarte como enlazar la información al MainPage del proyecto, quiero ver como también trabajar con las clases de entidades asociadas y basadas en la variable Equipos.</p>
<p>Necesitamos modificar el MainViewModel para contener la información desde el feed OData que fue consultado en MainPage.xaml.cs. Aquí está el código para el MainViewModel.cs</p>
<p>using System;<br />using System.ComponentModel;<br />using System.Data.Services.Client;<br />using Dia_14_OData.ServicioDatos;</p>
<p>namespace Dia_14_OData<br />{<br />&nbsp;&nbsp;&nbsp; public class MainViewModel : INotifyPropertyChanged<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public MainViewModel()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.Equipos = new DataServiceCollection&lt;TeamFranchise&gt;();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public DataServiceCollection&lt;TeamFranchise&gt; Equipos { get; private set; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public bool IsDataLoaded<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private set;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void LoadData()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.IsDataLoaded = true;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public event PropertyChangedEventHandler PropertyChanged;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void NotifyPropertyChanged(String propertyName)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PropertyChangedEventHandler handler = PropertyChanged;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (null != handler)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; handler(this, new PropertyChangedEventArgs(propertyName));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />}</p>
<p>Enlazar información de tus vistas desde OData</p>
<p>Ahora nos meteremos dentro del lado XAML del proyecto para mostrar como la información localizada del feed OData en el MainViewModel esta enlazada al ListBox en la vista MainPage y también a la vista DetailsPage.</p>
<p>El MainPage.xaml ha sido asociado con el MainViewModel localizaco en el archivo MainViewModel.cs por medio del DataContext que creamos en el constructor del MainPage.</p>
<p>DataContext = App.ViewModel;</p>
<p>No le hemos hecho mucho al código XAML que fue creado cuando comenzamos el proyecto de tipo Windows Phone Databound Application. Eliminamos la siguiente línea debido a que no tenemos información en tiempo de diseño.</p>
<p> d:DataContext=&#8221;{d:DesignData SampleData/MainViewModelSampleData.xaml}&#8221;</p>
<p>También necesitamos cambiar el Binding de MainListBox a solo {Binding} debido a que ajustamos la siguiente línea de código en el método Equipos_Loaded.</p>
<p>this.LayoutRoot.DataContext = App.ViewModel.Equipos;</p>
<p>Esto hará que la colección DataServiceCollection contenga todos los equipos de baseball que obtuvimos a partir de OData, y quede lista para enlazarla en el XAML del MainPage.</p>
<p>&lt;phone:PhoneApplicationPage x:Class=&#8221;Dia_14_OData.MainPage&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns=&#8221;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:x=&#8221;http://schemas.microsoft.com/winfx/2006/xaml&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:phone=&#8221;clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:shell=&#8221;clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:d=&#8221;http://schemas.microsoft.com/expression/blend/2008&#8243;<br />&nbsp;&nbsp;&nbsp; xmlns:mc=&#8221;http://schemas.openxmlformats.org/markup-compatibility/2006&#8243; <br />&nbsp;&nbsp;&nbsp; mc:Ignorable=&#8221;d&#8221; d:DesignWidth=&#8221;480&#8243; d:DesignHeight=&#8221;768&#8243; <br />&nbsp;&nbsp;&nbsp; FontFamily=&#8221;{StaticResource PhoneFontFamilyNormal}&#8221;<br />&nbsp;&nbsp;&nbsp; FontSize=&#8221;{StaticResource PhoneFontSizeNormal}&#8221;<br />&nbsp;&nbsp;&nbsp; Foreground=&#8221;{StaticResource PhoneForegroundBrush}&#8221;<br />&nbsp;&nbsp;&nbsp; SupportedOrientations=&#8221;Portrait&#8221;&nbsp; Orientation=&#8221;Portrait&#8221;<br />&nbsp;&nbsp;&nbsp; shell:SystemTray.IsVisible=&#8221;True&#8221;&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;Grid x:Name=&#8221;LayoutRoot&#8221; Background=&#8221;Transparent&#8221;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Grid.RowDefinitions&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;RowDefinition Height=&#8221;Auto&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;RowDefinition Height=&#8221;*&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/Grid.RowDefinitions&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel x:Name=&#8221;TitlePanel&#8221; Grid.Row=&#8221;0&#8243; Margin=&#8221;12,17,0,28&#8243;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock x:Name=&#8221;ApplicationTitle&#8221; Text=&#8221;LA LIGA SILVERLIGHT&#8221; Style=&#8221;{StaticResource PhoneTextNormalStyle}&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock x:Name=&#8221;PageTitle&#8221; Text=&#8221;OData&#8221; Margin=&#8221;9,-7,0,0&#8243; Style=&#8221;{StaticResource PhoneTextTitle1Style}&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/StackPanel&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Grid x:Name=&#8221;ContentPanel&#8221; Grid.Row=&#8221;1&#8243; Margin=&#8221;12,0,12,0&#8243;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ListBox x:Name=&#8221;MainListBox&#8221; Margin=&#8221;0,0,-12,0&#8243; ItemsSource=&#8221;{Binding}&#8221; SelectionChanged=&#8221;MainListBox_SelectionChanged&#8221;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ListBox.ItemTemplate&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;DataTemplate&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel Margin=&#8221;0,0,0,17&#8243; Width=&#8221;432&#8243; Height=&#8221;78&#8243;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock Text=&#8221;{Binding Path=franchName}&#8221; TextWrapping=&#8221;NoWrap&#8221; Style=&#8221;{StaticResource PhoneTextExtraLargeStyle}&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/StackPanel&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/DataTemplate&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/ListBox.ItemTemplate&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/ListBox&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/Grid&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/Grid&gt;<br />&lt;/phone:PhoneApplicationPage&gt;</p>
<p>&nbsp;</p>
<p>Cuando corras la aplicación en el emulador de Windows Phone verás que los equipos de baseball ahora se muestran en la aplicación.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image010.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="clip_image010" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image010_thumb.png" width="255" height="464"></a></p>
<p>Obtener la información del equipo seleccionado y mostrarla después de que la aplicación navegue a DetailPage.xaml es muy simple con unas líneas de código. Queremos asignar el equipo que fue seleccionado en el MainPage y después asociarlo al DataContext de DetailsPage con el objeto del equipo de baseball en la colección DataServiceCollection en el MainViewModel. El código para DetailsPage.xaml.cs esta abajo.</p>
<p>using System.Windows.Navigation;<br />using Microsoft.Phone.Controls;</p>
<p>namespace Dia_14_OData<br />{<br />&nbsp;&nbsp;&nbsp; public partial class DetailsPage : PhoneApplicationPage<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Constructor<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public DetailsPage()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitializeComponent();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // When page is navigated to set data context to selected item in list<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected override void OnNavigatedTo(NavigationEventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string selectedIndex = &#8220;&#8221;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (NavigationContext.QueryString.TryGetValue(&#8220;selectedItem&#8221;, out selectedIndex))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int index = int.Parse(selectedIndex);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataContext = App.ViewModel.Equipos[index];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />}</p>
<p>De nuevo, el código XAML en DetailsPage.xaml es muy simple, también las propiedades ApplicationTitle siendo cambiada junto con PageTitle, enlazadas a la propiedad franchName del equipo seleccionado. Quería mostrar la propiedade activa también solo como información adicional.</p>
<p>&lt;phone:PhoneApplicationPage <br />&nbsp;&nbsp;&nbsp; x:Class=&#8221;Dia_14_OData.DetailsPage&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns=&#8221;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:x=&#8221;http://schemas.microsoft.com/winfx/2006/xaml&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:phone=&#8221;clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:shell=&#8221;clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone&#8221;<br />&nbsp;&nbsp;&nbsp; xmlns:d=&#8221;http://schemas.microsoft.com/expression/blend/2008&#8243;<br />&nbsp;&nbsp;&nbsp; xmlns:mc=&#8221;http://schemas.openxmlformats.org/markup-compatibility/2006&#8243;<br />&nbsp;&nbsp;&nbsp; mc:Ignorable=&#8221;d&#8221; d:DesignWidth=&#8221;480&#8243; d:DesignHeight=&#8221;768&#8243; <br />&nbsp;&nbsp;&nbsp; FontFamily=&#8221;{StaticResource PhoneFontFamilyNormal}&#8221;<br />&nbsp;&nbsp;&nbsp; FontSize=&#8221;{StaticResource PhoneFontSizeNormal}&#8221;<br />&nbsp;&nbsp;&nbsp; Foreground=&#8221;{StaticResource PhoneForegroundBrush}&#8221;<br />&nbsp;&nbsp;&nbsp; SupportedOrientations=&#8221;Portrait&#8221;&nbsp; Orientation=&#8221;Portrait&#8221; <br />&nbsp;&nbsp;&nbsp; shell:SystemTray.IsVisible=&#8221;True&#8221;&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;Grid x:Name=&#8221;LayoutRoot&#8221; Background=&#8221;Transparent&#8221; d:DataContext=&#8221;{Binding Items[0]}&#8221;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Grid.RowDefinitions&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;RowDefinition Height=&#8221;Auto&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;RowDefinition Height=&#8221;*&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/Grid.RowDefinitions&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;StackPanel x:Name=&#8221;TitlePanel&#8221; Grid.Row=&#8221;0&#8243; Margin=&#8221;12,17,0,28&#8243;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock x:Name=&#8221;ApplicationTitle&#8221; Text=&#8221;LA LIGA SILVERLIGHT&#8221; Style=&#8221;{StaticResource PhoneTextNormalStyle}&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock x:Name=&#8221;ListTitle&#8221; Text=&#8221;{Binding franchName}&#8221; Margin=&#8221;9,-7,0,0&#8243; Style=&#8221;{StaticResource PhoneTextTitle1Style}&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/StackPanel&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Grid x:Name=&#8221;ContentPanel&#8221; Grid.Row=&#8221;1&#8243; Margin=&#8221;12,0,12,0&#8243;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock x:Name=&#8221;ContentText&#8221; Text=&#8221;{Binding active}&#8221; TextWrapping=&#8221;Wrap&#8221; Style=&#8221;{StaticResource PhoneTextNormalStyle}&#8221;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/Grid&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/Grid&gt;</p>
<p>&lt;/phone:PhoneApplicationPage&gt;</p>
<p>Al correr la aplicación y seleccionar un equipo de baseball de la página principal, esta navegará hacia la página de detalles donde verás lo siguiente.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image012_thumb.png"><img style="border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px" border="0" alt="clip_image012_thumb" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/clip_image012_thumb_thumb.png" width="232" height="422"></a></p>
<p>&nbsp;</p>
<p>En resumen</p>
<p>Para resumir, usar OData para consumir información es muy sencillo. Hay muchos mas elementos que System.Data.Services.Client y específicamente DataServiceCollection pueden ofrecerte como desarrollador. Espero que hayas visto como puedes hacer que las aplicaciones Windows Phone puedan manejar información con muy poco esfuerzo.</p>
<p>Para descargar el proyecto completo para Visual Studio 2010, puedes hacerlo en el siguiente enlace.</p>
<p><a href="http://aminespinoza.com/materialBlog/31dias/Dia_14_OData.zip">Puedes descargar el código aquí.</a></p>
<p>Mañana el autor invitado Doug Mair te mostrará como usar la ProgressBar para entretener e informar a tu usuario acerca de una descarga o un proceso de largo alcance. Nos vemos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-14-usando-odata/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 13: El test kit del Marketplace</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-13-el-test-kit-del-marketplace/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-13-el-test-kit-del-marketplace/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 15:50:40 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/2011/12/da-13-el-test-kit-del-marketplace/</guid>
		<description><![CDATA[Este artículo es una traducción de Day 13: Marketplace Test Kit, puedes encontrarlo aquí en la versión original en inglés. El trayecto final para tu aplicación Windows Phone en desarrollo es el publicarla en el Marketplace para compartirla alrededor del mundo. El proceso de sumisión del Marketplace es bastante sencillo, sin embargo hay requerimientos que cada una de todas las aplicaciones deben pasar antes de estar certificadas en el MarketPlace. El proceso para certificar tu aplicación podría tomar días o semanas dependiendo de cuantos requerimientos haya fallado tu aplicación durante el proceso de certificación. El tiempo para certificación puede ser acortado sustancialmente con el nuevo http://msdn.microsoft.com/en-us/library/hh394032%28v=VS.92%29.aspxincluido en el Windows Phone SDK 7.1 Nota: Cada desarrollador de Windows Phone necesita entender los Requisitos de Ingreso de Aplicaciones. Correr tu proyecto Windows Phone por medio del Marketplace Test Kit, te ayudará a determinar si tu aplicación esta lista para subirla al Windows Phone Marketplace. Antes de la disponibilidad del Marketplace Test Kit, los desarrolladores podrían subir su aplicación al Marketplace y debían esperar por un periodo de tiempo antes de saber si su aplicacición pasaba la certificación o no. Algunas ocasiones los errores de ingreso eran tan simples como subir la versión [...]]]></description>
			<content:encoded><![CDATA[<p>Este artículo es una traducción de Day 13: Marketplace Test Kit, puedes encontrarlo aquí en la versión original en inglés.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia13.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="dia13" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia13_thumb.png" width="604" height="79"></a></p>
<p>El trayecto final para tu aplicación Windows Phone en desarrollo es el publicarla en el Marketplace para compartirla alrededor del mundo. El proceso de sumisión del Marketplace es bastante sencillo, sin embargo hay requerimientos que cada una de todas las aplicaciones deben pasar antes de estar certificadas en el MarketPlace. El proceso para certificar tu aplicación podría tomar días o semanas dependiendo de cuantos requerimientos haya fallado tu aplicación durante el proceso de certificación. El tiempo para certificación puede ser acortado sustancialmente con el nuevo <a title="http://msdn.microsoft.com/en-us/library/hh394032%28v=VS.92%29.aspx" href="http://msdn.microsoft.com/en-us/library/hh394032%28v=VS.92%29.aspx">http://msdn.microsoft.com/en-us/library/hh394032%28v=VS.92%29.aspx</a>incluido en el <a href="http://create.msdn.com/en-us/home/getting_started">Windows Phone SDK 7.1</a></p>
<p><strong><font size="5">Nota: Cada desarrollador de Windows Phone necesita entender los <a href="http://msdn.microsoft.com/en-us/library/hh184844(v=VS.92).aspx">Requisitos de Ingreso de Aplicaciones.</a></font></strong></p>
<p>Correr tu proyecto Windows Phone por medio del Marketplace Test Kit, te ayudará a determinar si tu aplicación esta lista para subirla al <a href="http://www.windowsphone.com/es-MX/marketplace?wa=wsignin1.0">Windows Phone Marketplace</a>. Antes de la disponibilidad del Marketplace Test Kit, los desarrolladores podrían subir su aplicación al Marketplace y debían esperar por un periodo de tiempo antes de saber si su aplicacición pasaba la certificación o no. Algunas ocasiones los errores de ingreso eran tan simples como subir la versión de depuración o un poco mas complicados como no manejar el Tombstoning adecuadamente. Con el Marketplace Test Kit, el desarrollador es capaz de correr a través de una pila de pruebas para determinar si su aplicación esta lista para certificación andes de ir directamente al proceso de ingreso al Marketplace. Esto ahorra al desarrollador una tremenda cantidad de tiempo y da a tu aplicación un pase mas rápido al Marketplace.</p>
<p>El Marketplace Test Kit esta incluido en el SDK 7.1 de Windows Phone . Puedes acceder al Marketplace Test Kit abriendo la solución de tu aplicación en Visual Studio, resaltando el proyecto que te gustaría probar y abriendo el Marketplace Test Kit del menu Proyecto.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/OpenTestKit.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="OpenTestKit" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/OpenTestKit_thumb.png" width="539" height="387"></a></p>
<p>El Marketplace Test Kit es actualizado al momento de que los requisitos de certificación del Marketplace lleguen a cambiar. Si una actualización esta disponible, serás avisado para aplicar la actualización cuando abras el Marketplace Test Kit. El conjunto de pruebas es aplicado por por proyecto. Si tienes múltiples proyectos Windows Phone en tu solución, necesitarás correr el kit para cada proyectos.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/TestKit1.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="TestKit1" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/TestKit1_thumb.png" width="539" height="387"></a></p>
<p>Una vez que el Marketplace Test Kit este abierto, verás una serie de tablas que definen los detalles de la aplicación y múltiples categorías de prueba. Estas incluyen: Detalles de aplicación, pruebas automatizadas, pruebas monitoreadas y pruebas manuales.</p>
<p>La pestaña de <strong>Application Details</strong> contiene detalles como la ruta al empaquetado de tu aplicación (la ubicación de tu archivo .XAP) también como las imágenes que representan a tu aplicación en el Marketplace (El tile del marketplace y las capturas de pantalla) y en el teléfono (El tile grande de la aplicación y el pequeño de la lista de aplicaciones). Nota que la ruta del paquete de tu aplicación debe estar en la ruta al compilado de tipo Release de tu proyecto. Aquí hay un artículo de <a href="http://msdn.microsoft.com/en-us/library/ff928362%28v=VS.92%29.aspx">MSDN How-to</a> que señala el proceso para crear un compilado de tipo Release para tu proyecto de Windows Phone.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/TestKit2.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="TestKit2" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/TestKit2_thumb.png" width="550" height="395"></a></p>
<p>Una de las pruebas de la pestaña de Pruebas Automáticas es verificar que los tamaños de imagen para tus imágenes sea el adecuado. Una forma trivial de crear el tamaño apropiado para tus imágenes de captura de pantalla es la nueva <a href="http://msdn.microsoft.com/en-us/library/gg442300%28v=VS.92%29.aspx">herramienta de captura de pantalla</a> encontrada en el emulador del <a href="http://create.msdn.com/en-us/home/getting_started">SDK de Windows Phone 7.1</a>.</p>
<p>La pestaña Automated Test evalúa los requerimientos de tamaño de la aplicación, capacidades requeridas para tu aplicación, la iconografía y requisitos de las capturas de pantalla. Presiona el botón “Run Tests” para correr las pruebas.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/TestKit3.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="TestKit3" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/TestKit3_thumb.png" width="550" height="395"></a></p>
<p>Una vez que las pruebas automatizadas están completas, verás si pasaste o no las pruebas en la columna de resultados. Quizá también recibas información adicional en el caso de que la prueba haya fallado para poder ayudarte a resolver el problema, así como información de ayuda tal como las capacidades usadas dentro de tu aplicación. Puedes usar los resultados de la prueba de validación de capacidades usada dentro de tu aplicación <strong>para definir las capacidades requeridas por tu aplicación</strong> en el archivo WMAppManifest.xml.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/TestKit4.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="TestKit4" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/TestKit4_thumb.png" width="550" height="395"></a></p>
<p>La pestaña de <strong>Monitored Test</strong> enlista una serie de pruebas para analizar el rendimiento y confiabilidad de tu aplicación. Cuando presionas el botón “Start Application”, tu aplicación es desplegada a tu dispositivo. Desde aquí vas a correr la funcionalidad de tus aplicaciones mientras las pruebas monitoreadas analizan varios casos de pruebas.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/TestKit6.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="TestKit6" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/TestKit6_thumb.png" width="550" height="395"></a></p>
<p>Cuando hayas terminado de correr a través de la funcionalidad, puedes presionar el botón “Close Application”.&nbsp; La columna de Detalles del Resultado enlista varios mensajes basados en el resultado de la prueba. Es recomendable aquí que ajustes el dispositivo de pruebas a uno real y no al emulador. El rendimiento en el emulador no representa realmente el rendimiento actual de un dispositivo físico. Correr las pruebas en un dispositivo te dará los resultados mas acertados para esas pruebas.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/TestKit7.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="TestKit7" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/TestKit7_thumb.png" width="550" height="395"></a></p>
<p>La pestaña Manual Test enlista un número de casos de pruebas que requieren que corras manualmente a través de su aplicación. De nuevo estas pruebas deberían ser realizadas en un dispositivo real y no en el emulador. Estos casos de prueba ayudan a verificar los diferentes escenario que no pueden ser probados con herramientas automatizadas&nbsp; o scripts. Estas incluyen pruebas como:</p>
<p>* Capacidad de respuesta durante y después de varias condiciones</p>
<p>* Contenido y cambio de temas – si tu aplicación es legible en ambos tipos de temas, claro y oscuro</p>
<p>*Autorización de Toast Notification</p>
<p>* Control de comandos de volumen para aplicaciones que usan audio</p>
<p>* Manejo adecuado de Background Transfers</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/TestKit8.png"><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="TestKit8" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/TestKit8_thumb.png" width="550" height="395"></a></p>
<p>Para cada prueba, sigue los pasos delineados en la columna Test Description. Basado en lo que vayas encontrando, ajusta el resultado para colocarlo en Aprobado o Fallido. Tu aplicación quizá no implementa elementos requeridos por cada una de las pruebas de condición. Para aquellas pruebas particulares puedes ajustar el resultado de Aprobado para mantener la consistencia a través de todos tus casos de prueba, sin embargo, asegúrate de que tu aplicación no implemente ninguno de los elementos para ese caso de prueba. No es la idea arriesgarnos a a fallar en la certificación por una omisión en los procedimientos de prueba.</p>
<p>Una vez que tu proyecto pase todas las pruebas en el Marketplace Test Kit, puedes asegurarte de que tu aplicación esta lista para acelerar el proceso de certificación.</p>
<p><font size="5"><strong>En Resumen</strong></font></p>
<p>El Marketplace Test Kit ahorra al desarrollador bastante tiempo en hacer que su aplicación sea publicada. Con el paso a través de las pruebas automatizadas, monitoreadas y manuales, los desarrolladores Windows Phone pueden esperar un proceso expedito para tener sus aplicaciones en el Marketplace y servir a los clientes de Windows Phone a&nbsp; lo largo del mundo.</p>
<p>Mñana, vamos a meternos con oData y como podemos consumir entradas de oData en nuestras aplicaciones. Estará escrito por el autor invitado Chris Woodruff. Nos vemos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-13-el-test-kit-del-marketplace/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#237;a 12: Pruebas Beta</title>
		<link>http://blogs.ligasilverlight.com/2011/12/da-12-pruebas-beta/</link>
		<comments>http://blogs.ligasilverlight.com/2011/12/da-12-pruebas-beta/#comments</comments>
		<pubDate>Thu, 08 Dec 2011 15:37:28 +0000</pubDate>
		<dc:creator>Amin Espinoza</dc:creator>
				<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://blogs.ligasilverlight.com/2011/12/da-12-pruebas-beta/</guid>
		<description><![CDATA[Este artículo es una traducción de Day 12: Beta testing, puedes encontrarlo aquí en la versión original en inglés. Como desarrolladores, estamos muy orgullosos de las aplicaciones que creamos, es tan natural que queremos compartir nuestro trabajo con otros. Algunas veces, quizá queremos compartir una aplicación en una etapa temprana para obtener algunos consejos y sugerencias de nuestros amigos, familia y compañeros. Cuando lanzamos por primera vez Windows Phone, la única manera que tenías de compartir una aplicación antes de publicarla era compartir el archivo XAP de tu aplicación. Pero compartir el XAP es problemático por varias razones. Primero, los archivos XAP son solo archivos comprimidos, lo cual significa que pueden ser extraídos y examinados. Segundo, los desarrolladores no tenían la habilidad de terminar un trial o hacer a los usuarios actualizarse al producto final cuando estuviera listo. Pero probablemente el mayor problema de usar XAPs para pruebas beta es que requerían al emulador o un dispositivo desbloqueado para poder correr. Esa restricción por sí sola eliminaba a la mayoría de amigos y familias de participar en betas cerradas. Pero ahora, con las actualizaciones recientes de Windows Phone Marketplace, todos esos problemas han sido resueltos. Este artículo se enfocará en [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jeffblankenburg.com/2011/11/12/31-days-of-mango-day-12-beta-distribution/">Este artículo es una traducción de Day 12: Beta testing, puedes encontrarlo aquí en la versión original en inglés.</a></p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia12.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/dia12_thumb.png" alt="dia12" width="604" height="79" border="0" /></a></p>
<p>Como desarrolladores, estamos muy orgullosos de las aplicaciones que creamos, es tan natural que queremos compartir nuestro trabajo con otros. Algunas veces, quizá queremos compartir una aplicación en una etapa temprana para obtener algunos consejos y sugerencias de nuestros amigos, familia y compañeros.</p>
<p>Cuando lanzamos por primera vez Windows Phone, la única manera que tenías de compartir una aplicación antes de publicarla era compartir el archivo XAP de tu aplicación. Pero compartir el XAP es problemático por varias razones. Primero, los archivos XAP son solo archivos comprimidos, lo cual significa que pueden ser extraídos y examinados. Segundo, los desarrolladores no tenían la habilidad de terminar un trial o hacer a los usuarios actualizarse al producto final cuando estuviera listo. Pero probablemente el mayor problema de usar XAPs para pruebas beta es que requerían al emulador o un dispositivo desbloqueado para poder correr. Esa restricción por sí sola eliminaba a la mayoría de amigos y familias de participar en betas cerradas. Pero ahora, con las actualizaciones recientes de Windows Phone Marketplace, todos esos problemas han sido resueltos. Este artículo se enfocará en una nueva distribución de versiones beta y como puede ser usada para ganar consejos de una audiencia mucho mayor a la que tenías acceso antes.</p>
<p>No habrá ningún código en este artículo dado que las betas son manejadas enteramente por el marktplace. Vamos a ver los pasos para subir una aplicación beta, pero antes de comenzar ha unos tips útiles que deberías saber.</p>
<p>* Las betas no cuestan nada y no cuentan dentro de el número total de aplicaciones. Esto quiere decir que puedes correr muchas betas al mismo tiempo sin pagar una multa.</p>
<p>* Dado que las betas son, bueno, betas, los requerimientos del marketplace son significativamente menores y el proceso de verificación sucede mucho mas rápido, eso te da la flexibilidad de obtener consejos de los usuarios, hacer cambios a tu aplicación y crear una nueva beta en un periodo de tiempo mucho menor.</p>
<p>* Las betas expiran automáticamente a los 90 días a partir de cuando fueron aceptadas en el marketplace. Cuando la beta expira, los probadores tienen la opción de desinstalar, dar su opinión de la aplicación o ambos.</p>
<p>* Puedes invitar a cualquier usuario a tu beta mientras sepas el Live ID asociado con su teléfono. Cualquier Windows Phone puede ser utilizado para pruebas beta y los teléfonos NO tienen que estar desbloqueados para desarrollo.</p>
<p>* Puedes invitar hasta a 100 probadores por beta, y la lista de probadores puede ser modificada durante los 90 días.</p>
<p>* Finalmente, y esto es muy importante, el nombre de la beta debe ser único a través de todo el marketplace. Además, es muy importante agregar “Beta” al final del nombre de tu aplicación o alguna forma de distinguir la beta de modo que el nombre no esté reservado cuando estés listo para lanzar el producto final.</p>
<p>Subir una aplicación para beta es simple y comenzamos de la misma forma que subir una aplicación normal. Primero, necesitamos navegar al <a href="http://create.msdn.com/en-US/">AppHub</a> e ingresar. Después, damos clic sobre el ícono grande  de “Submit for Windows Phone” para iniciar el proceso.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/ivktducc.jpg"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/ivktducc_thumb.jpg" alt="ivktducc" width="401" height="239" border="0" /></a></p>
<p>Cuando llenes los detalles de la aplicación, no olvides incluir las palabras “Beta” o agregar algo mas al título de modo que el título “regular” no sea reservado. Además asegurate de cambiar la distribución de “Public Marketplace” a “Private Beta Test”.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/5fup4mog.jpg"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/5fup4mog_thumb.jpg" alt="5fup4mog" width="428" height="370" border="0" /></a></p>
<p>La descripción y requerimientos de imágenes son como en un aplicación regular. Necesitarás estar preparado con el mismo tipo de imágenes y tamaños, pero la versión beta puede incluir marcadores.</p>
<p>Necesitarás al menos lo siguiente:</p>
<p>* Una imagen de 99 x 99 px (Small tile)</p>
<p>* Una imagen de 200 x 200 px (Lage tile)</p>
<p>* Al menos una imagen de 480 x 800 de una captura de pantalla (puedes usar el nuevo emulador de Mango para capturar esta)</p>
<p>Después de que la descripción e imágenes han sido subidos, el asistente omitirá el paso de ponerle un precio a la aplicación y te llevará directo hacia la sección “Test”. Esta sección es donde das una lista de Live IDs (direcciones de correo electrónico) para cada probador, separados por un punto y coma ( ; ). Trata de no incluir espacios.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/byt1lf3q.jpg"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/byt1lf3q_thumb.jpg" alt="byt1lf3q" width="469" height="262" border="0" /></a></p>
<p>Finalmente, cuando hayas completado todos los pasos de arriba y después de que tu beta haya sido aceptada, cada probador recibirá un correo electrónico muy similar a este.</p>
<p><a href="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/IC522476.png"><img style="padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px" src="http://blogs.ligasilverlight.com/wp-content/uploads/2011/12/IC522476_thumb.png" alt="IC522476" width="546" height="567" border="0" /></a></p>
<p>&nbsp;</p>
<p>El [link to your application] puede ser seguido por el usuario y será llevado directamente a una página beta privada en el marketplace. Desde ahí, el usuario podrá instalar evaluar y opinar acerca de la beta de la misma forma que lo haría para con una aplicación normal. Y tu, el desarrollador puede ver esta información como lo harías en una aplicación normal.</p>
<p><strong>Nota importante: </strong>Ten en cuanta que cualquier dirección de correo electrónico puede ser usada como un Live ID válido, pero ten cuidado con las direcciones que no terminen con @hotmail.com o @live.com. Es posible para el usuario que deba <a href="https://accountservices.passport.net/reg.srf?fid=RegCredOnlyEASI&amp;ru=https://accountservices.passport.net/ppnetworkhome.srf%3Fvv%3D1200%26mkt%3DEN-US%26lc%3D1033&amp;cru=https://accountservices.passport.net/ppnetworkhome.srf%3fvv%3d1200%26mkt%3dEN-US%26lc%3d1033&amp;sl=1&amp;lc=1033">seguir estos pasos</a> y asociar un Live ID con cualquier cuenta de correo que quiera, pero la mayoría de personas no saben que pueden hacer eso. Solo permanece atento de que si usas una dirección de correo electrónico que no es un Live ID primario en un teléfono, el usuario quizá reciba el correo, pero no será capaz de seguir el enlace a una aplicación válida.</p>
<p><span style="font-size: large"><strong>En resumen</strong></span></p>
<p>Así que, ahora que conoces el proceso ¿Qué estas esperando? Las distribuciones Beta te permitirán coleccionar consejos temprano y frecuentemente, si estás planeando una nueva idea o dando a los usuarios una prueba temprana de tu siguiente y mas grande lanzamiento. ¿Por qué no darle a las pruebas beta un intento hoy?</p>
<p>Si tu eres nuevo en Windows Phone y no tienes aún las herramientas, puedes obtenerlas <a href="http://create.msdn.com/en-us/home/getting_started">de aquí</a>. Y si tu estás construyendo muchas aplicaciones pero no tienes un dispositivo de pruebas o estás preocupado acerca de las tarifas del Marketplace, <a href="//jbienz@hotmail.com">escríbeme</a>. Quizá pueda ayudarte.</p>
<p>Mañana el autor invitado Dave Bost va a cubrir otro tema que es increiblemente importante para hacer que su aplicación esté en el Windows Phone Marketplace, y es el Marketplace Test Kit. Nos vemos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.ligasilverlight.com/2011/12/da-12-pruebas-beta/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

