tag:blogger.com,1999:blog-84077958278371367172024-02-07T17:33:46.092-08:00Windows Phone, Xamarin, Azure y otras cosasLuis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.comBlogger53125tag:blogger.com,1999:blog-8407795827837136717.post-18212162829085344932017-09-28T11:04:00.003-07:002017-09-28T11:10:02.911-07:00#FuerzaMexico | ¡Ayuda a nuestro país y capacítate en Xamarin!¡Hola! Es de todos conocida la situación por la que pasó nuestro país debido a los terremotos de los días 7 y 9 de Septiembre. A pesar de que hoy es fin de mes, operaciones de rescate y apoyo a nuestros compatriotas siguen realizándose, además de que mucha gente perdió sus viviendas o está pasando por una situación desagradable.<br />
<br />
Sin embargo, es en este tipo de hechos cuando la humanidad que muchos de nosotros tenemos guardada sale a relucir. Mucha gente (no solo mexicanos, sino también extranjeros) han dado seguimiento a lo que acontece en nuestro país, manifestando su apoyo con donaciones, alimentos, ayuda en sitio e incluso apoyo moral, que se necesita tanto hoy en día. Hemos visto en redes sociales cómo la gente se ha unido para ayudar a quien más lo necesita.<br />
<br />
Estar lejos de mi país me hace ver que todos podemos apoyar de alguna manera sin importar la distancia gracias a la tecnología, pues podemos hacer donaciones en línea, depósitos bancarios, incluso colaborar para construir una app móvil que agilice las operaciones de rescate y apoyo.<br />
<br />
Pero esto no terminó la semana pasada. Aún hay labor por realizar, cosas que podemos hacer para que las personas puedan poco a poco volver a una situación normal. Por eso, quiero apoyar de la mejor manera que sé, que es <b>compartiendo mi conocimiento</b>. ¿Te unes a esta labor? Es muy fácil =)<br />
<br />
Te propongo lo siguiente: <b>realiza una donación </b>de la manera que consideres más adecuada. Puede ser:<br />
<br />
<ul>
<li>Una aportación monetaria a la Cruz Roja Mexicana (por ejemplo, en Morelos <b><a href="http://www.cruzrojamorelos.org/donativos.html">http://www.cruzrojamorelos.org/donativos.html</a></b>)</li>
<li>Víveres en centros de acopio</li>
<li>Voluntariado presencial</li>
<li>Descubre varias formas de apoyar visitando el sitio <b><a href="http://comoayudar.mx/">http://comoayudar.mx/</a></b></li>
<li>Una forma innovadora, algo que se te ocurra</li>
</ul>
<div>
<br /></div>
<div>
Después de eso, envíame un comprobante de la forma en que ayudaste (una foto, scan, etc., puedes omitir los datos que desees, como el monto, tu dirección, etc) a mi correo (<b>luis.beltran@itcelaya.edu.mx</b>). A cambio, en los próximos días ofrezco dar <b>3 talleres en línea de Xamarin en vivo </b>y te enviaré el enlace donde podrás estar en la sesión para aprender sobre:</div>
<div>
<br /></div>
<div>
<ul>
<li>Mapas en Xamarin.Forms: Sábado 14/Oct</li>
<li>Twitter en Xamarin.Forms: Sábado 21/Oct</li>
<li>PayPal en Xamarin.Forms: Sábado 28/Oct</li>
</ul>
</div>
<br />
<br />
Las clases serán grabadas y te enviaré a tu correo un enlace donde podrás descargar el video de la sesión el mismo día que se realice. Eso sí, a partir de Noviembre, estos videos estarán públicos en mi canal de YouTube.<br />
<br />
NOTA: Si ya ayudaste previamente y tienes manera de comprobarlo, también sirve :) eso sí, si está en tus posibilidades, una ayuda extra no está de más.<br />
<br />
Todo proceso es perfectible y se aceptan sugerencias sobre temas, maneras de ayudar, etc. (incluso si quieres sumarte a esta iniciativa dando algún tema, ¡adelante, todo esfuerzo suma!) Lo hago con la mejor de las intenciones de ayudar con un granito de arena, tal vez no sea lo mismo que estar físicamente allá ayudando, pero es una manera en que creo que puedo ayudar.<br />
<br />
Otra cosa... ¿me ayudas compartiendo este enlace en tus redes sociales? De esta manera podemos llegar a más personas y aportar en más cantidad.<br />
<br />
¡Gracias!<br />
<br />
- Luis<br />
<br />
#FuerzaMexicoLuis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com1tag:blogger.com,1999:blog-8407795827837136717.post-67466352960800880362017-07-18T02:36:00.001-07:002017-07-18T07:29:15.012-07:00Diplomado gratuito: ¡Xamarin.iOS en español!¡Hola! Les traigo una excelente noticia nuevamente. Después del éxito del <b><a href="https://icebeamwp.blogspot.com/2017/03/xamarin-diplomado-latinoamerica-30.html" target="_blank">XamarinDiplomado Latinoamérica 3.0</a></b>, el aprendizaje no termina y ahora tenemos disponible el registro a la especialidad de Xamarin.iOS, un diplomado impartido por <b>Microsoft</b> y <b>TI Capacitación</b> para toda Latinoamérica (y para todo aquél que hable español también, por supuesto).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8eREhExenKWF7PJp1AjKfMu4yqFfcwVv1KKD45sZZwZdDqTKa5a2pR4wjJQZIpnhqc8ZL4thmtIw1Sio4_WAV50ntw5HpttQBwLcnLNnPP8n_QzaLRwnHfu-Rib3Qt5m_aYSvmCvz68s/s1600/xamarin_ios.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="231" data-original-width="639" height="115" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8eREhExenKWF7PJp1AjKfMu4yqFfcwVv1KKD45sZZwZdDqTKa5a2pR4wjJQZIpnhqc8ZL4thmtIw1Sio4_WAV50ntw5HpttQBwLcnLNnPP8n_QzaLRwnHfu-Rib3Qt5m_aYSvmCvz68s/s320/xamarin_ios.png" width="320" /></a></div>
<br />
<br />
Simplemente da clic en el siguiente enlace: <a href="https://ticapacitacion.com/registro/xamarinios" target="_blank"><b>https://ticapacitacion.com/registro/xamarinios</b></a>.<br />
<br />
El diplomado es <b>gratuito </b>completamente, en español y aunque no se ha publicado el temario del curso, ¡te garantizo que aprenderás muchas cosas! Habrá sesiones teóricas y prácticas (laboratorios). Si realizas todas las actividades, al final del curso obtendrás un diploma a manera de reconocimiento de tu aprendizaje y esfuerzo realizado.<br />
<br />
<b>Importante: El registro sólo se encontrará abierto del 17 de julio al 24 de julio de 2017.</b><br />
<br />
El acceso al aula es totalmente <b>online</b>, disponible 24/7, es decir, tú decides cuándo acceder a los recursos, videos, laboratorios, PDFs, etc. Ocasionalmente habrá sesiones en vivo con los instructores del diplomado.<br />
<br />
También únete a nuestro grupo de Facebook, donde resolvemos dudas acerca del diplomado, compartimos más noticias y conocimiento de Xamarin y nos apoyamos entre todos :) Solicita tu acceso aquí: <b><a href="https://www.facebook.com/groups/xamarindiplomadoitc/">https://www.facebook.com/groups/xamarindiplomadoitc/</a></b><br />
<br />
<br />
<a name='more'></a><br />
<br />
Solo recuerda que debido a los términos de la licencia de Apple, requieres tener acceso a una Mac para realizar la compilación de tus proyectos sí o sí (claro, existe <b><a href="https://www.xamarin.com/live" target="_blank">Xamarin Live Player</a></b> pero como está en Preview, tal vez no sea suficiente para realizar los laboratorios del curso). Hay 2 alternativas legales para poder cumplir este requisito:<br />
<br />
<br />
<ul>
<li>Contar con una Mac física.</li>
<li>Rentar una Mac en la nube, por ejemplo con el servicio de <b><a href="https://macincloud.com/" target="_blank">MacInCloud</a></b>. </li>
</ul>
<div>
<br /></div>
<div>
En los próximos días voy a hacer un video donde explico cómo configurar el servicio de MacInCloud, aunque puedes seguir el <b><a href="https://msmdotnet.wordpress.com/2017/07/17/accediendo-a-servicios-de-mac-en-la-nube/" target="_blank">tutorial</a></b> de <b>Miguel Muñoz Serafín,</b> <b>Microsoft MVP,</b> por lo pronto.</div>
<div>
<br /></div>
<div>
Si decides optar por el servicio de MacInCloud, recuerda que para este diplomado nos concedieron <b>descuentos del 20%</b> por los primeros 3 meses de uso del servicio. Da clic en la opción de tu elección:</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<ul>
<li>Managed: <a data-saferedirecturl="https://www.google.com/url?hl=es&q=https://portal.macincloud.com/select/%23/plans/managed/selection?coupon%3DJul2017LtnXMRN20Prcnt&source=gmail&ust=1500456254497000&usg=AFQjCNFYhvjRJSir4BMHZ5ZGrslGDlUydw" href="https://portal.macincloud.com/select/#/plans/managed/selection?coupon=Jul2017LtnXMRN20Prcnt" rel="noreferrer" style="background-color: white; color: #1155cc; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px;" target="_blank">https://portal.<span class="il">macincloud</span>.com/<wbr></wbr>select/#/plans/managed/<wbr></wbr>selection?coupon=<wbr></wbr>Jul2017LtnXMRN20Prcnt</a></li>
</ul>
</div>
<div>
<ul>
<li>Dedicated: <a data-saferedirecturl="https://www.google.com/url?hl=es&q=https://portal.macincloud.com/select/%23/plans/dedicated/selection?coupon%3DJul2017LtnXMRN20Prcnt&source=gmail&ust=1500456254497000&usg=AFQjCNGtkM-q5ltbb_e70sHCz4Cn05gwfg" href="https://portal.macincloud.com/select/#/plans/dedicated/selection?coupon=Jul2017LtnXMRN20Prcnt" rel="noreferrer" style="background-color: white; color: #1155cc; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px;" target="_blank">https://portal.<span class="il">macincloud</span>.com/<wbr></wbr>select/#/plans/dedicated/<wbr></wbr>selection?coupon=<wbr></wbr>Jul2017LtnXMRN20Prcnt</a></li>
</ul>
</div>
<div>
<br /></div>
<div>
<b>NOTA: ¡Este descuento está disponible únicamente hasta el último día de este mes, así que aprovéchalo cuanto antes! </b></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
El Managed Server debería ser más que suficiente para el desarrollo del curso. Recuerda que debes marcar la opción <b>Enable Remote Build Port (SSH)</b> para que puedas hacer tus compilaciones desde Visual Studio de manera remota correctamente. </div>
<div>
<br /></div>
<div>
Bueno, es todo por lo pronto. Déjame tus dudas o comentarios y trataré de responderte a la brevedad. Te deseo mucho éxito en el diplomado y si esta entrada fue de utilidad, házmelo saber :) también comparte esta información si crees que puede ser de interés para otras personas.</div>
<div>
<br /></div>
<div>
¡Gracias!</div>
Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com0tag:blogger.com,1999:blog-8407795827837136717.post-13352049923757182402017-07-13T16:42:00.001-07:002017-07-13T16:56:44.653-07:00Otro reto para ganarte un AzurePass¡Hola! Bueno pues nuevamente les propongo un reto dado que aún me sobraron pases de Azure.<br />
<br />
Esta entrada es una <b>competencia</b>.<br />
<br />
¿Quieres ganarte un <b>Azure Pass</b>? Un Azure Pass te permite utilizar Azure por cierto tiempo SIN tarjeta de crédito.<br />
<br />
Aprovecha los conocimientos que has adquirido en el <b>#XamarinDiplomado</b> y desarrolla un juego utilizando Xamarin (puede ser Xamarin.Forms o Xamarin en cualquier plataforma -Android, iOS, UWP, Windows Phone, Windows 8)- de entre la siguiente lista:<br />
<br />
<br />
<ul>
<li>El juego del gato (también conocido como 3 en raya o Tic-Tac-Toe). Basta con que sea entre 2 jugadores humanos, pero si quieres implementar la versión de 1 jugador vs el teléfono, adelante.</li>
</ul>
<ul>
<li>Memorama (o juego de memoria). El tablero consta de 10 cuadros que tienen 5 figuras repetidas en pares. El objetivo es descubrir las parejas en el menor tiempo o intentos posibles. Tú eliges si quieres programar temporizador o número de turnos. </li>
</ul>
<ul>
<li><a href="http://www.acanomas.com/Reglamentos-Juegos-de-Dados/012/Boston.htm" target="_blank">El juego de Boston</a> (este está bueno como ejercicio de programación, de igual manera tú decides si haces la versión de 2 jugadores humanos o de 1 humano vs el teléfono)</li>
</ul>
<br />
Requisitos:<br />
<ol>
<li>La app debe estar en español.</li>
<li>La app debe mostrar tu nombre y correo electrónico.</li>
</ol>
<div>
<br />
Sube tu proyecto a GitHub y enviame un correo a la siguiente dirección: <b>luis.beltran@itcelaya.edu.mx</b> con el enlace a tu solución. Si tu app funciona, te enviaré un pase de Azure. En caso de que no funcione, pues te contesto el correo con mis sugerencias.</div>
<div>
<br /></div>
<div>
Como la idea es que aprendan, <b>NO está permitido copiar </b>la solución de otro compañero. Si yo detecto 2 soluciones iguales, a ninguno le otorgaré el Azure Pass. </div>
<div>
<br /></div>
<div>
Solo se vale un pase de Azure por persona. Si ganas un pase en este reto, ya no puedes obtener otro (pero eres libre de participar en futuros retos). Si ya ganaste un pase con anterioridad, no te puedo dar otro, pero eres libre de practicar y resolver el reto por supuesto :)</div>
<div>
<br />
Esta oferta es válida mientras tenga Azure Passes disponibles o antes del 22 de Julio (fecha de expiración de los pases)<br />
<br /></div>
<div>
Si hay dudas, favor de comentar en la publicación.</div>
<div>
<br /></div>
<div>
¡Saludos!</div>
Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com0tag:blogger.com,1999:blog-8407795827837136717.post-78482611112359405632017-06-19T09:16:00.002-07:002017-06-19T09:40:09.593-07:00¡Gánate un Azure Pass desarrollando una app de Xamarin!¡Hola! Después de tiempo sin escribir, les comento que ya me pasaré seguido por aquí, aprovechando que tengo varios ejemplos por compartir y describir :)<br />
<br />
Esta entrada es muy rápida. Es una <b>competencia</b>.<br />
<br />
¿Quieres ganarte un <b>Azure Pass</b>? Un Azure Pass te permite utilizar Azure por cierto tiempo SIN tarjeta de crédito.<br />
<br />
Aprovecha los conocimientos que has adquirido en el <b>#XamarinDiplomado</b> (si no te has inscrito, da clic en el siguiente <b><a href="https://aka.ms/xamarindiplomado30" target="_blank">enlace</a></b>) y desarrolla una aplicación utilizando Xamarin (puede ser Xamarin.Forms o Xamarin en cualquier plataforma -Android, iOS, UWP, Windows Phone, Windows 8)- que cumpla con los siguientes requisitos:<br />
<br />
<br />
<ol>
<li>Cuando la app se abra, debe obtenerse la ubicación del dispositivo muy fácil si usas el siguiente <a href="https://github.com/jamesmontemagno/GeolocatorPlugin" target="_blank"><b>plugin</b></a>)</li>
<li>Con las coordenadas obtenidas, muestra información del país en el que te encuentras: Nombre, Capital, Continente, Extensión Geográfica, Idiomas y Moneda.</li>
<li>La app debe mostrar tu nombre y correo electrónico.</li>
</ol>
<div>
<br /></div>
<div>
Para cumplir el requisito puedes utilizar algún servicio que te devuelva dicha información. Uno de ellos, gratuito, es <a href="http://www.geonames.org/" style="font-weight: bold;" target="_blank">GeoNames</a>. Simplemente crea tu cuenta <b><a href="http://www.geonames.org/login" target="_blank">aquí</a></b> y de la lista de web services disponibles en este <a href="http://www.geonames.org/export/ws-overview.html" target="_blank"><b>enlace</b></a>, utiliza 2 servicios:</div>
<div>
<br /></div>
<div>
<ul>
<li><a href="http://www.geonames.org/export/web-services.html#countrycode" target="_blank"><b>CountryCode</b></a> (pasando como parámetros la latitud y longitud, puedes obtener el código del país)</li>
<li><b><a href="http://www.geonames.org/export/web-services.html#countryInfo" target="_blank">CountryInfo</a></b> (pasando como parámetro el código de un país, puedes obtener información a detalle de un país)</li>
</ul>
</div>
<div>
<br /></div>
<div>
Sube tu proyecto a <b>GitHub</b> y enviame un correo a <b>luis.beltran@itcelaya.edu.mx</b> con el enlace a tu solución. Si tu app funciona, te enviaré un pase de Azure que tiene vigencia hasta el <b>8 de Julio </b>(sé que es poco tiempo, pero algo es algo...). En caso de que no funcione, pues te contesto el correo con mis sugerencias.</div>
<div>
<br /></div>
<div>
Como la idea es que aprendan, <b>NO está permitido copiar </b>la solución de otro compañero. Si yo detecto 2 soluciones iguales, a ninguno le otorgaré el Azure Pass. </div>
<div>
<br /></div>
<div>
Realmente la app es muy sencilla. Si aún me sobran pases, la próxima semana lanzo otro reto. </div>
<div>
<br /></div>
<div>
Solo se vale un pase de Azure por persona. Si ganas un pase en este reto, ya no puedes obtener otro (pero eres libre de participar en futuros retos).</div>
<div>
<br />
Esta oferta es válida mientras tenga Azure Passes disponibles o antes del 8 de Julio o antes de que lance el siguiente reto.<br />
<br /></div>
<div>
Si hay dudas, favor de comentar en la publicación.</div>
<div>
<br /></div>
<div>
¡Saludos!</div>
Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com5tag:blogger.com,1999:blog-8407795827837136717.post-23018113338519553052017-05-09T06:27:00.001-07:002017-05-10T04:49:36.181-07:00Enviar mensaje de WhatsApp via Xamarin.Android<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
¡Hola! Ya sé que tengo pendientes con la serie de WCF y Xamarin jeje, pero este fin de semana probé un código rápido que creo les será de utilidad. Platicando con varios compañeros del <a href="http://aka.ms/xamarindiplomado30"><span style="color: blue;">#XamarinDiplomado</span></a>, uno de los requerimientos más comunes hoy en día en las aplicaciones móviles es la opción de <b>enviar información vía WhatsApp</b>, y si bien no se cuenta con un API oficial, sí es posible integrar esta funcionalidad en nuestras aplicaciones con Xamarin con código específico de platforma.</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
En esta entrega te mostraré lo fácil que es hacerlo usando <b>Xamarin.Android</b> a través de un <b>Intent.</b> En una futura entrega (más tarea para mí xD) lo haré con <b>Xamarin.iOS</b>, pues al parecer tiene más capacidades que en Android. El código es muy sencillo y el mismo sitio de WhatsApp lo menciona desde su FAQ:</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<ul type="disc">
<li class="MsoNormal" style="line-height: normal; text-align: justify;"><b>Para Android: </b><span style="color: windowtext;"><a href="https://www.whatsapp.com/faq/es/android/28000012"><b><span style="color: blue;">Click aquí</span></b></a></span></li>
</ul>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<ul type="disc">
<li class="MsoNormal" style="line-height: normal; text-align: justify;"><b>Para iOS: </b><span style="color: windowtext;"><a href="https://www.whatsapp.com/faq/es/iphone/23559013"><b><span style="color: blue;">Click acá</span></b></a></span></li>
</ul>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
Por cierto: <b>Este código solo puede ser probado en un dispositivo
físico (teléfono) con WhatsApp instalado.</b> Por ahí dicen que es posible instalar Whatsapp usando <a href="http://www.bluestacks.com/es/apps/communication/whatsapp-on-pc.html#gref" target="_blank"><b>Bluestacks</b></a> en un emulador, así que lo dejo a tu consideración en caso de que no cuentes con un teléfono Android.<br />
<br />
El código fuente está disponible en <b><a href="https://github.com/icebeam7/XamarinWhatsapp" target="_blank">mi GitHub</a></b> para quien desee probarlo inmediatamente, pero si quieres realizarlo paso a paso, pues ¡manos a la obra!</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<b>Paso 1. </b>Crea una aplicación de tipo <b>Aplicación en blanco (Android)</b>, que corresponde a <b>Xamarin.Android</b></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIPHJuSZXrvZu8AU9BW_bw75zW9qneRXU0JTOpgBY_JvTY7fXQaidZOx6_PI7D59VUXAjfYmFYaaSE00-i0c2ClZXy_L0VuVeBjK-WaNlwqEoxWhPtiaX8zjCkvFMO4P8wBXmb4nD-ZhY/s1600/01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="242" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIPHJuSZXrvZu8AU9BW_bw75zW9qneRXU0JTOpgBY_JvTY7fXQaidZOx6_PI7D59VUXAjfYmFYaaSE00-i0c2ClZXy_L0VuVeBjK-WaNlwqEoxWhPtiaX8zjCkvFMO4P8wBXmb4nD-ZhY/s400/01.png" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<b>Paso 2. </b>Localiza el archivo Strings.xml en la ruta <b>Resources > values</b> del proyecto y reemplaza su contenido por lo siguiente:</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br />
<pre class="brush:xml;first-line:1"><?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="Mensaje">Mensaje</string>
<string name="ApplicationName">XamarinWhatsapp</string>
<string name="Enviar">Enviar mensaje</string>
</resources>
</pre>
</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<b></b><br />
<a name='more'></a><b><br /></b><br />
<b>Paso 3. </b>Abre el archivo <b>Main.axml</b>, ubicado en la ruta <b>Resources > layout </b>del proyecto. Agrega:</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<ul type="disc">
<li class="MsoNormal" style="line-height: normal; text-align: justify;">Un <b>TextView </b>con el texto de la cadena <b>Mensaje</b> (definida en Strings.xml).</li>
<li class="MsoNormal" style="line-height: normal; text-align: justify;">Un EditText con el id <b>edtMensaje</b>.</li>
<li class="MsoNormal" style="line-height: normal; text-align: justify;">Un botón con el texto de la cadena <b>Enviar</b>, además del identificadr <b>btnMensaje</b>.</li>
</ul>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
El código respectivo es el siguiente:</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br />
<pre class="brush:xml;first-line:1"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="@string/Mensaje"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/edtMensaje"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btnEnviar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/Enviar" />
</LinearLayout></pre>
</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<b>Paso 4. </b>Abre el archivo <b>MainActivity.cs</b>, ubicado en la raiz del proyecto. En este archivo agregaremos el código Android que viene en el FAQ de WhatsApp, es decir, </div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcGMbsGn9YX0CIMJrb2J0rPiT8Rva1a3tz-Q8CuseqJHjsYieZO0sf4hw70ykAsdd_E9MEpDlh0uKpWEHYNcKo-r3AxoX-fQqeCcG578G3u_XQQCq6kA9w9GUnMFiYE7tI_G0pY24_a74/s1600/00.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="115" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcGMbsGn9YX0CIMJrb2J0rPiT8Rva1a3tz-Q8CuseqJHjsYieZO0sf4hw70ykAsdd_E9MEpDlh0uKpWEHYNcKo-r3AxoX-fQqeCcG578G3u_XQQCq6kA9w9GUnMFiYE7tI_G0pY24_a74/s400/00.png" width="400" /></a></div>
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
pero convertido a C#, por supuesto (no es complicado).</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
Aquí tienes el código completo de esta Activity:</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br />
<pre class="brush:csharp;first-line:1">using System;
using Android.App;
using Android.Widget;
using Android.OS;
using Android.Content;
using Android.Content.PM;
namespace XamarinWhatsapp
{
[Activity(Label = "XamarinWhatsapp", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
Button btnEnviar;
EditText edtMensaje;
string whatsapp = "com.whatsapp";
bool VerificarApp(String uri)
{
try
{
ApplicationContext.PackageManager.GetPackageInfo(uri, PackageInfoFlags.Activities);
return true;
}
catch (PackageManager.NameNotFoundException e)
{
return false;
}
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
btnEnviar = FindViewById<button>(Resource.Id.btnEnviar);
edtMensaje = FindViewById<edittext>(Resource.Id.edtMensaje);
btnEnviar.Click += BtnEnviar_Click;
}
private void BtnEnviar_Click(object sender, System.EventArgs e)
{
if (VerificarApp(whatsapp))
{
Intent intent = new Intent();
intent.SetAction(Intent.ActionSend);
intent.PutExtra(Intent.ExtraText, edtMensaje.Text);
intent.SetType("text/plain");
intent.SetPackage(whatsapp);
StartActivity(intent);
}
else
{
Toast.MakeText(this, "WhatsApp no está instalado. No se pudo enviar el mensaje", ToastLength.Long).Show();
}
}
}
}</pre>
</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
En resumen:</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<ul type="disc">
<li class="MsoNormal" style="line-height: normal; text-align: justify;">Se crean referencias para el EditText (<b>edtMensaje</b>) y el Button (<b>btnEnviar</b>)</li>
</ul>
<ul type="disc">
<li class="MsoNormal" style="line-height: normal; text-align: justify;">La cadena <b>whatsapp</b> contiene el identificador del paquete de la aplicación <b>WhatsApp</b>.</li>
</ul>
<ul type="disc">
<li class="MsoNormal" style="line-height: normal; text-align: justify;">Esta cadena se utiliza en el método <b>VerificarApp</b> para comprobar si está instalada o no en el dispositivo donde probaremos la aplicación.</li>
</ul>
<ul type="disc">
<li class="MsoNormal" style="line-height: normal; text-align: justify;">En el método <b>OnCreate</b> se asignan las referencias a los controles y el mánejador de evento del botón.</li>
</ul>
<ul type="disc">
<li class="MsoNormal" style="line-height: normal; text-align: justify;">El manejador de evento <b>BtnEnviar_Click</b> contiene el código de la página de WhatsApp traducido a C# (es bien fácil, ¿no?). Previamente se verifica si la app está instalada para poder enviar el mensaje; en caso de que no esté instalada, se notifica al usuario con un <b>Toast</b>. Además, para indicar directamente que queremos utilizar WhatsApp al momento de ejecutar el Intent incluimos el identificador del paquete con SetPackage.</li>
</ul>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
¡Listo! Compila y ejecuta la aplicación.</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
Primero <b>escribimos</b> el mensaje.</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhB4zhXLZtF22ULKTqxmP2tTX2YYSwViYu5tyPiuXxWOSYaHPNpm9n4ArBVWGErH0-3S2OBmd5NrLP6c8yOx27CXN0XUj1rxJHG2PIaXzczFnh_UD5juIITOcNg4ns6qAgv0IkfdBlRUXQ/s1600/02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhB4zhXLZtF22ULKTqxmP2tTX2YYSwViYu5tyPiuXxWOSYaHPNpm9n4ArBVWGErH0-3S2OBmd5NrLP6c8yOx27CXN0XUj1rxJHG2PIaXzczFnh_UD5juIITOcNg4ns6qAgv0IkfdBlRUXQ/s400/02.png" width="225" /></a></div>
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
Da clic en <b>Enviar mensaje</b> y en ese momento WhatsApp será abierto en caso de estar instalado en el teléfono, mostrando la lista de contactos.</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEis2-0DYga3WE6C5UTMuRIxTfgLFpE7-ivd759Qco9-79gWQ_TiPxo4KW2tIo7UvQTULpt3ich6n5sOmIwPt5MzzHN8Va8k7juqa1-JyueYTT6hBbt0ZwvdtyJwmm6tdmu1Y1YdztCmJ-c/s1600/03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEis2-0DYga3WE6C5UTMuRIxTfgLFpE7-ivd759Qco9-79gWQ_TiPxo4KW2tIo7UvQTULpt3ich6n5sOmIwPt5MzzHN8Va8k7juqa1-JyueYTT6hBbt0ZwvdtyJwmm6tdmu1Y1YdztCmJ-c/s400/03.png" width="225" /></a></div>
</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
Puedes seleccionar uno o más contactos a quienes enviarles el mensaje que acabas de escribir. <b>Si seleccionas uno</b>, al dar clic en <b>Listo (palomita)</b>, pasarás a la pantalla de mensajes con el contacto, y podrás modificar el texto o confirmar el mensaje.</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg330_XlNlmykM1VnHZBSoGkSp6ZI_eec5aalMIS-191wdU9fqeoJ1hyphenhyphenBGF-WWQg59XF_-w30PXBhPWUBX_-BPlDqWm8Q_NTcrF9bd-Hvaw0dcGnezjSRifCsINUovIvykM_5BRUL-qWE8/s1600/04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg330_XlNlmykM1VnHZBSoGkSp6ZI_eec5aalMIS-191wdU9fqeoJ1hyphenhyphenBGF-WWQg59XF_-w30PXBhPWUBX_-BPlDqWm8Q_NTcrF9bd-Hvaw0dcGnezjSRifCsINUovIvykM_5BRUL-qWE8/s400/04.png" width="225" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi00ZLzzwEEC5Lxq2JKdFrLAD79Q193xkiWe8sofQv1bf5TFOyuZSn-D-mejJ2RvBfI1CtUim0sGihSUiQyu21gA9XPB_kHSABuOAl7uwA3eL44IMEybs3tOGq86ZVPRpO0iBelBh5KN24/s1600/05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi00ZLzzwEEC5Lxq2JKdFrLAD79Q193xkiWe8sofQv1bf5TFOyuZSn-D-mejJ2RvBfI1CtUim0sGihSUiQyu21gA9XPB_kHSABuOAl7uwA3eL44IMEybs3tOGq86ZVPRpO0iBelBh5KN24/s400/05.png" width="225" /></a></div>
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
En cambio <b>si seleccionas más de un contacto</b>, el mensaje se enviará a todos los seleccionados automáticamente al dar clic en <b>Listo (la palomita)</b>. Así que eso es una ventaja si deseas enviar mensajes masivos.</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br />
<b>Nota:</b> Tal vez te preguntes si es posible "saltar" la confirmación del mensaje al seleccionar un contacto y hacerlo automático. De momento, por diseño de la plataforma no es posible. Tal vez en un futuro cambie esta situación.<br />
<br />
<b>Nota2:</b> Tal vez también te preguntes si es posible preseleccionar un contacto desde código. Aparentemente sí (introduciendo el número telefónico formando una <b>Android.Net.Uri</b> mediante <b>smsto: </b>) pero por más pruebas que hice no fue posible. Te dejo el <b><a href="http://stackoverflow.com/questions/15462874/sending-message-through-whatsapp" target="_blank">link</a></b> donde vi esta información, si a tí te funciona házmelo saber y actualizo el post, con tu correspondiente mención y crédito por supuesto =)<br />
<br />
<b>Nota3: </b>Sí, también es posible enviar multimedia (imágenes, audio, video, etc) en el Intent. Después lo publicamos, pero la información está <b><a href="https://developer.android.com/training/sharing/send.html" target="_blank">aquí</a> </b>para quien guste irlo revisndo.<br />
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
Finalmente, <b>si WhatsApp no está instalado en el teléfono</b>, la notificación Toast será mostrada en la aplicación.</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI4qJTFhbbIhI6XGkgh1VdnOnjiLGm00s3MUHrnZOty3WU4Bzz-V_Y6ZWpo270IkQ6T29vCIob62yW7PjpWQQADjEVRSYIjqPp_9CD73IAoFRgULUKLa-4V-01Y7waYCPhriyybW5GmK0/s1600/06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI4qJTFhbbIhI6XGkgh1VdnOnjiLGm00s3MUHrnZOty3WU4Bzz-V_Y6ZWpo270IkQ6T29vCIob62yW7PjpWQQADjEVRSYIjqPp_9CD73IAoFRgULUKLa-4V-01Y7waYCPhriyybW5GmK0/s400/06.png" width="225" /></a></div>
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
Como puedes ver, fue realmente sencillo lanzar WhatsApp desde una aplicación en Xamarin.Android. Ahora que conoces cómo hacerlo, intégralo en tu app.</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
Si tienes alguna duda, comentame y con gusto te ayudo. Si esta entrada fue de tu interés, házmelo saber o comparte esta publicación.</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
Gracias por leer el blog. ¡Feliz inicio de semana!</div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<br /></div>
</div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm;">
<div style="text-align: justify;">
<i>PD: Ahora sí ya, la próxima entrega será la tercer parte (tan esperada) de Xamarin y WCF... ¡Gracias por su paciencia!</i></div>
</div>
<div style="text-align: justify;">
<br /></div>
<div class="MsoNormal">
<div style="text-align: justify;">
<br /></div>
</div>
Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com3tag:blogger.com,1999:blog-8407795827837136717.post-5736314085445258652017-05-03T06:48:00.000-07:002017-05-03T06:48:04.812-07:00Reto 6 del Xamarin Championship<div class="" data-block="true" data-editor="btbth" data-offset-key="32ino-0-0" style="background-color: white; color: #1d2129; font-family: Helvetica, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;">
<div class="_1mf _1mj" data-offset-key="32ino-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="32ino-0-0" style="font-family: inherit;">¡Hola! Si estuviste como yo haciendo F5 en el <b><a href="https://github.com/lruval/XamarinChampionship" target="_blank">GitHub</a></b> del <a href="http://xamarinchampionship.azurewebsites.net/" target="_blank"><b>Xamarin Championship</b></a> te habrás dado cuenta que ayer se publicó el <a href="http://xamarinchampionship.azurewebsites.net/reto-seis/" style="font-weight: bold;" target="_blank">Reto 6</a>, en el cual aprendes a incorporar los <b><a href="http://microsoft.com/cognitive" target="_blank">Microsoft Cognitive Services</a></b> en una aplicación de Android con Xamarin (espero haber sido de los 5 primeros xD).</span></div>
<div class="_1mf _1mj" data-offset-key="32ino-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="32ino-2-0" style="font-family: inherit;"><br /></span></div>
<div class="_1mf _1mj" data-offset-key="32ino-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="32ino-2-0" style="font-family: inherit;">Bien, en la guía aprendes a tomar una foto de tu dispositivo mediante la cámara y enviarla al servicio para que devuelva información del estado de ánimo del rostro detectado.</span></div>
<div class="_1mf _1mj" data-offset-key="32ino-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="32ino-2-0" style="font-family: inherit;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU9_u0Ckx3837tohoNYSZIKxhpL0h9GMFuuXq_GkWbeiZpnWjlBBQ2ina8Ovf-zF5OkQT4oCUbjXwZSn7qSjqh44jl5g16N7EhicgRxr3IEu7hDSotT_FxBwgGlHAQKGqw3mweaRRsuxM/s1600/emo00.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU9_u0Ckx3837tohoNYSZIKxhpL0h9GMFuuXq_GkWbeiZpnWjlBBQ2ina8Ovf-zF5OkQT4oCUbjXwZSn7qSjqh44jl5g16N7EhicgRxr3IEu7hDSotT_FxBwgGlHAQKGqw3mweaRRsuxM/s400/emo00.png" width="225" /></a></div>
<div class="_1mf _1mj" data-offset-key="32ino-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="32ino-2-0" style="font-family: inherit;"><br /></span></div>
<div class="_1mf _1mj" data-offset-key="32ino-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="32ino-2-0" style="font-family: inherit;"><br /></span></div>
<div class="_1mf _1mj" data-offset-key="32ino-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="32ino-2-0" style="font-family: inherit;">Sin embargo, si estás usando el emulador, verás que es imposible tomar una foto, pues solo aparece la imagen en movimiento.</span></div>
<div class="_1mf _1mj" data-offset-key="32ino-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="32ino-2-0" style="font-family: inherit;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLru8PDtl1_sAnE1hGxjWDCZOXnx-uM88je5-7ImGP6-bAzAMkHcgTe8fxlf86wk5L-nIHpby2vRzmAL1Mt1S4fYcWcwO1_AbF6vygpMCeP9zl6cellpJQX77UOzMDfufPytJBqSCLBLU/s1600/emo01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLru8PDtl1_sAnE1hGxjWDCZOXnx-uM88je5-7ImGP6-bAzAMkHcgTe8fxlf86wk5L-nIHpby2vRzmAL1Mt1S4fYcWcwO1_AbF6vygpMCeP9zl6cellpJQX77UOzMDfufPytJBqSCLBLU/s400/emo01.png" width="225" /></a></div>
<div class="_1mf _1mj" data-offset-key="32ino-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="32ino-2-0" style="font-family: inherit;"><br /></span></div>
</div>
<div class="" data-block="true" data-editor="btbth" data-offset-key="c0fvl-0-0" style="background-color: white; color: #1d2129; font-family: Helvetica, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;">
<div class="_1mf _1mj" data-offset-key="c0fvl-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="c0fvl-0-0" style="font-family: inherit;"><br data-text="true" /></span></div>
</div>
<div class="" data-block="true" data-editor="btbth" data-offset-key="5hcii-0-0" style="background-color: white; color: #1d2129; font-family: Helvetica, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;">
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;">Una forma de resolver esta situación es diciéndole que seleccione una foto de la galería del emulador, lo cual es muy sencillo. Solo sigue estos pasos.</span></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><br /></span></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><b>Paso 1. </b>Inicia el emulador (no requieres Visual Studio para esto, puedes hacerlo desde el menú de Inicio).</span></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><a name='more'></a><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNiXt_NCaukERtDjbWLjHhzKj9iUPtGizmY3pPNZ7HRJXXy7ppCprlX3X7FcB0ReKbObq8HuYiHz_mhoK_qauTWye0_TXg_PnMFq_CNkgwZRPQLtZ38hW071tAWTBBSZpj-VQXu3z5A4Q/s1600/emo02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNiXt_NCaukERtDjbWLjHhzKj9iUPtGizmY3pPNZ7HRJXXy7ppCprlX3X7FcB0ReKbObq8HuYiHz_mhoK_qauTWye0_TXg_PnMFq_CNkgwZRPQLtZ38hW071tAWTBBSZpj-VQXu3z5A4Q/s400/emo02.png" width="225" /></a></div>
<br />
<b>Paso 2. </b>Abre el <b>Navegador web</b>..<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH_dCVEfKNZBvrcskfo1xxKeMBVa342WSw_2iVxWMcVYCVQit0EqG6MNhV-Z4R96DeZdQCEv39agdA6OzBIX9l0ceWcrrX4BZnIX1uNfx0OmNW27QnSGvMjCZATueEtix88v-4fgGkWLc/s1600/emo03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH_dCVEfKNZBvrcskfo1xxKeMBVa342WSw_2iVxWMcVYCVQit0EqG6MNhV-Z4R96DeZdQCEv39agdA6OzBIX9l0ceWcrrX4BZnIX1uNfx0OmNW27QnSGvMjCZATueEtix88v-4fgGkWLc/s320/emo03.png" width="180" /></a></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><br /></span></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><b>Paso 3. </b>Busca una imagen con rostro.</span></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsrvdpDUSKjU2iS54dLPF-o_rnTF8iAjBlPw9ppwdkaH0B_8FmyR8CA3POvpz2tkWmqGVuTSvLx3hpA3D9vnCmWA6l1sOS77kJyqsjEvhxSTXyAV5b7UwI_Bcr1wBIKz-hqsuvd_QhMT0/s1600/emo04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsrvdpDUSKjU2iS54dLPF-o_rnTF8iAjBlPw9ppwdkaH0B_8FmyR8CA3POvpz2tkWmqGVuTSvLx3hpA3D9vnCmWA6l1sOS77kJyqsjEvhxSTXyAV5b7UwI_Bcr1wBIKz-hqsuvd_QhMT0/s400/emo04.png" width="225" /></a></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><br /></span></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<br /></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><b>Paso 4. Guarda la imagen. </b>Para ello, <b>da clic sostenido sobre la imagen </b>y así aparecerá el menú contextual y puedas guardarla en el dispositivo (no le vayas a hacer como cierta persona que le daba botón derecho y no le salía el menú 😄 si lo lees, es broma jaja) dando clic en <b>Save image</b>.</span></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifxPvE0BOMAypO-8HdRR-VJOH7iMzc3X0guCpL-EpHLyK6B97HdROwKQOsev8h4DXLhStLUc-6A6yWCDrR7rfHVu9HwlXbsQ9GG8WHu5sbvaBwS0M4sddgP3oSyP9GGpk-CpI78HW5Pe0/s1600/emo05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifxPvE0BOMAypO-8HdRR-VJOH7iMzc3X0guCpL-EpHLyK6B97HdROwKQOsev8h4DXLhStLUc-6A6yWCDrR7rfHVu9HwlXbsQ9GG8WHu5sbvaBwS0M4sddgP3oSyP9GGpk-CpI78HW5Pe0/s400/emo05.png" width="225" /></a></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><br /></span></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><br /></span></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><b>Paso 5. </b>Resuelve el Reto 6 pero en el archivo <b>CognitiveActivity </b>modifica la línea <b>file = await ServiceImage.TakePicture(true);</b> que está en el manejador de evento Click de BtnCamara, cambiando el valor a <b>false</b>.</span></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9NaMNBuLQHSnqUo7zHEycvIYjpEwWbOLmv2VzlqZ2Yrr0j0tp7lmKZENx4w9KxU0KRR4Dx8XCVdD0__Yx9go4qoQ1TVpz7oCx_Ja16R5O3C42rHKLrtnMbGdQOZSZldNqofMa3x2rG5U/s1600/emo06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="152" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9NaMNBuLQHSnqUo7zHEycvIYjpEwWbOLmv2VzlqZ2Yrr0j0tp7lmKZENx4w9KxU0KRR4Dx8XCVdD0__Yx9go4qoQ1TVpz7oCx_Ja16R5O3C42rHKLrtnMbGdQOZSZldNqofMa3x2rG5U/s400/emo06.png" width="400" /></a></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><br /></span></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><b>Paso 6.</b> ¡Listo! Ejecuta la app y verás que al presionar el botón se ejecutará el selector de imagen en vez de lanzar la cámara, Selecciona tu imagen y analízala, para verificar las emociones detectadas por el servicio.</span></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj3h8HdEwGTFnZXrcDUgn6istui8hf5xzZ6mfCubZHiy19OSsrNw8D8oVifg86kAoudTNI0sQTckyf-vD8HbmqSDjxvLrI4ZdmYlmHpP7vn-BVGeeKBF0y9wLRSu8GwZOm2JZ2K1LVw60/s1600/emo08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj3h8HdEwGTFnZXrcDUgn6istui8hf5xzZ6mfCubZHiy19OSsrNw8D8oVifg86kAoudTNI0sQTckyf-vD8HbmqSDjxvLrI4ZdmYlmHpP7vn-BVGeeKBF0y9wLRSu8GwZOm2JZ2K1LVw60/s400/emo08.png" width="225" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Click en Siguiente</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlxCROiTdwAA9TsbIoTqZTRXMuC3WiaFKFdr9wdzXnTPNlUKZWfMwqFhaEjGUZl2gVUcBztVlZYkxMIS7w7tq8SrKjAkqzKzYFMPQrw37OYxNcTOlLJm-6er0Iko-NKYHPeWavcCT-GAg/s1600/emo09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlxCROiTdwAA9TsbIoTqZTRXMuC3WiaFKFdr9wdzXnTPNlUKZWfMwqFhaEjGUZl2gVUcBztVlZYkxMIS7w7tq8SrKjAkqzKzYFMPQrw37OYxNcTOlLJm-6er0Iko-NKYHPeWavcCT-GAg/s400/emo09.png" width="225" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Click en Tomar una foto</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1BspvAJvXZTAYDIRi_ZsqdPqVQzCMCrN2LG1SOMFE9PbX7jk7Ls2TpWNtg8iNdD9u300JEYzi60V3wZnUvBCKkOI6Po-mdYCLqGK-KtUVqoeyktSBFSrei4i87uGBQ85zpjno0H2iwRk/s1600/emo10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1BspvAJvXZTAYDIRi_ZsqdPqVQzCMCrN2LG1SOMFE9PbX7jk7Ls2TpWNtg8iNdD9u300JEYzi60V3wZnUvBCKkOI6Po-mdYCLqGK-KtUVqoeyktSBFSrei4i87uGBQ85zpjno0H2iwRk/s400/emo10.png" width="225" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Selecciona la foto de la galería</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4QMXqmt3H9iXd31T2SnQ5-ZRHhN_jDL0-8bT1-zOspAJyCoXcA3GcdEwqQfvwIIwTdcpvPtMrvIr7XhHWYy9JVp2ljdDJrqhj0jK6ycccAoVIkFQjXtrt9cP7PgJYEoaVFsJo_2G_F2Q/s1600/emo11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4QMXqmt3H9iXd31T2SnQ5-ZRHhN_jDL0-8bT1-zOspAJyCoXcA3GcdEwqQfvwIIwTdcpvPtMrvIr7XhHWYy9JVp2ljdDJrqhj0jK6ycccAoVIkFQjXtrt9cP7PgJYEoaVFsJo_2G_F2Q/s400/emo11.png" width="225" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Click en Analizar foto</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIvdoudSReVXDQ7vXQtkEmegIGx-OQbVEvraE3f02mWFdUNXbbimj__MkscO_UbyS0c673yk-roUfqoxflTF_12rHgeLd1NFi8qCRJKq00thr4pZu6fexDgVmS7RJLO7lJ9gt9P8evphE/s1600/emo12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIvdoudSReVXDQ7vXQtkEmegIGx-OQbVEvraE3f02mWFdUNXbbimj__MkscO_UbyS0c673yk-roUfqoxflTF_12rHgeLd1NFi8qCRJKq00thr4pZu6fexDgVmS7RJLO7lJ9gt9P8evphE/s400/emo12.png" width="225" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Espera...</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEht0zB8WYlvz_nMl_2tLaUu3H34vLYsqx1AF-3achCXNGICq_HWn-U3OGC_NF6x77KbPaSdlaz9TBIU3W5Jke1vpfMpafxMxO8aa0WKwv_dU1_lMEQmsBhJt0uVeNihmazEFY3sAkkm06Y/s1600/emo13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEht0zB8WYlvz_nMl_2tLaUu3H34vLYsqx1AF-3achCXNGICq_HWn-U3OGC_NF6x77KbPaSdlaz9TBIU3W5Jke1vpfMpafxMxO8aa0WKwv_dU1_lMEQmsBhJt0uVeNihmazEFY3sAkkm06Y/s400/emo13.png" width="225" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Observa el resultado</div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<br /></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><br /></span></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;">¿Cuál es el truco? La explicación es sencilla. En la clase ServiceImage, el método TakePicture toma un booleano como parámetro. Si está establecido en true, la imagen a analizar será obtenida desde la cámara; en caso contrario (false), la imagen será obtenida desde la galería.</span></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhq-PT_8r2VD5OGHl9fyPhlJBeja-XnqRGg1jX8QXHvu0Vw49cxaAx00cmYpkPVy6z2CuA6_3AYWePCwl2cxzF_GvT6ijcga3SVyT504LpVexhwWEHCspltwpffabd8AWaYaYc77iekKtw/s1600/emo07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhq-PT_8r2VD5OGHl9fyPhlJBeja-XnqRGg1jX8QXHvu0Vw49cxaAx00cmYpkPVy6z2CuA6_3AYWePCwl2cxzF_GvT6ijcga3SVyT504LpVexhwWEHCspltwpffabd8AWaYaYc77iekKtw/s400/emo07.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><br /></span></div>
<div class="_1mf _1mj" data-offset-key="5hcii-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="5hcii-0-0" style="font-family: inherit;"><div style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 14.85px; white-space: normal;">
<span style="font-size: 14.85px;">Espero esta entrada haya sido de utilidad para tí, en caso afirmativo no dudes en compartirla con tus amigos :) También puedes dejarme un comentario para hacerme saber qué te pareció esta publicación o si te interesa que cubra algún tema en el futuro.</span></div>
<div class="post-body entry-content" id="post-body-2041479707122379785" itemprop="description articleBody" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 14.85px; line-height: 1.4; position: relative; white-space: normal; width: 528px;">
<br />¡Saludos y hasta la próxima!</div>
</span></div>
</div>
Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com1tag:blogger.com,1999:blog-8407795827837136717.post-4030274781061243912017-04-26T03:57:00.003-07:002017-04-26T04:59:06.683-07:00Consideraciones a tener en cuenta al descargar un proyecto de Xamarin desde Internet¡Hola! En esta entrada rápidamente les cuento una de las situaciones más comunes al descargar un código fuente de un proyecto de Xamarin de Internet, principalmente desde GitHub. Normalmente al encontrar un proyecto queremos compilarlo y ejecutarlo inmediatamente para probar su funcionamiento. Sin embargo, en muchas ocasiones recibimos una serie de errores que impiden su ejecución y creemos (erróneamente, por lo general) que el proyecto NO funciona y lo descartamos.<br />
<br />
Algunos de los errores (que más que errores son detalles) más comunes al momento de compilar y ejecutar un proyecto descargado de Internet son:<br />
<br />
<br />
<ul>
<li><b>La ruta del proyecto es demasiado larga </b>debido a que lo ejecutamos desde la carpeta Descargas (cuya ruta absoluta por lo general es C:/Usuarios/TuUsuario/Descargas/CarpetaConNombreLargo/CarpetaConNombreLargo/proyecto/</li>
<li>La <b>seguridad </b>de nuestro equipo (firewall, antivirus) <b>impide la ejecución </b>de archivos que proceden desde otros equipos, al ser considerados maliciosos (falsos positivos)</li>
<li>Se mantienen las <b>referencias relativas </b>al equipo de cómputo donde fue creado el <b>proyecto original</b> (generando referencia a carpetas que pueden no existir en nuestro equipo)</li>
<li><b>Configuración incorrecta de la solución en Visual Studio</b>.</li>
<li><b>No está habilitada la compilación o implementación </b>del proyecto de Android/iOS/UWP </li>
</ul>
<div>
<br /></div>
<div>
Todo esto es solucionable. Claro, en ocasiones me he encontrado con proyectos que en versiones actuales de Xamarin ya no funcionan al utilizar código obsoleto o alguna librería que de plano ya no existe o usa dependencias antiguas. Esto es normal, pues la tecnología avanza y se van creando nuevas (y optimizadas) versiones de las librerías disponibles para crear nuestras aplicaciones.</div>
<div>
<br /></div>
<div>
A continuación te presento una breve guía que me ha funcionado para ejecutar la mayoría de proyectos que encuentro en Internet. </div>
<div>
<br /></div>
<div>
<b>1. Descarga tu proyecto. </b>La tendencia actual es que los desarrolladores usamos GitHub para compartir nuestros proyectos, en cuyo caso se usará el botón <b>Clone or download</b> y luego <b>Download ZIP</b> para que se descargue el proyecto en una carpeta comprimida en nuestro equipo de cómputo.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIpyJCaEYlhufVIvZ_qITt2tOfqyTKw5ZDIgnTLTSXb40Onx9f2wVcyDkBrXV-3FHD5w_0-ntfwI8waDsa7gXQ8KHz4nKErgAXcGyfEMP42TzkTt16-g6G0qyT2jMZb8kyQpaBRAEE8vY/s1600/d00.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="190" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIpyJCaEYlhufVIvZ_qITt2tOfqyTKw5ZDIgnTLTSXb40Onx9f2wVcyDkBrXV-3FHD5w_0-ntfwI8waDsa7gXQ8KHz4nKErgAXcGyfEMP42TzkTt16-g6G0qyT2jMZb8kyQpaBRAEE8vY/s400/d00.png" width="400" /></a></div>
<div>
<br /></div>
<div>
<a name='more'></a><br /></div>
<div>
<b>2. Da clic derecho </b>sobre el la carpeta comprimida descargada y selecciona <b>Propiedades</b>.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_QeqqNV2n6nVgx3pm-QNaEUC6cbOFHfOeRX7n-qm0DUdXMJz4gEqphy4efZZQosVz_2zz8fx4q91u5o6SucK5X8HxDUYBNsVk3tTDmatjMn3yraIugIN71mfFdB42JGNJTaBHT3l9Vuo/s1600/d01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="327" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_QeqqNV2n6nVgx3pm-QNaEUC6cbOFHfOeRX7n-qm0DUdXMJz4gEqphy4efZZQosVz_2zz8fx4q91u5o6SucK5X8HxDUYBNsVk3tTDmatjMn3yraIugIN71mfFdB42JGNJTaBHT3l9Vuo/s400/d01.png" width="400" /></a></div>
<br />
<b>3. Selecciona la opción Desbloquear, </b>la cual se encuentra en la sección <b>Seguridad</b>. (Explicación: le decimos a Windows que el contenido de la carpeta procede de una fuente confiable -o al menos es lo que esperamos...-)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw39Lb3Oi_xt4ndAoSleWDjPFjxLVkIMBF-AkboXxygUVMIXSSCmNWYp8Rb_4gPasbue2-T3Nwpcy7vUgAtW1CFK2DTBbLZz9qKcQ-i5XUsTRCHnFf_JD1372-yT8AdgN8hjrhMN3xYoM/s1600/d02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw39Lb3Oi_xt4ndAoSleWDjPFjxLVkIMBF-AkboXxygUVMIXSSCmNWYp8Rb_4gPasbue2-T3Nwpcy7vUgAtW1CFK2DTBbLZz9qKcQ-i5XUsTRCHnFf_JD1372-yT8AdgN8hjrhMN3xYoM/s400/d02.png" width="286" /></a></div>
<br />
<b>4. Descomprime el proyecto en una carpeta con una ruta corta, por ejemplo C:/Xamarin o algo así.</b> (Explicación: Cuando se descargan los paquetes Nuget o se agregan referencias de Android/iOS/UWP en la compilación del proyecto de Xamarin, normalmente estos elementos contienen nombres muy largos. El límite en Windows es de 260 caracteres, aunque de acuerdo a <b><a href="https://mspoweruser.com/ntfs-260-character-windows-10/" target="_blank">este blog</a></b> ya podemos habilitar rutas largas a partir de Windows 10... no lo sabía -<b><a href="https://mspoweruser.com/ntfs-260-character-windows-10/" target="_blank">eso no me lo esperaba</a></b>- xD).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMtpd3fqIK56Rd8XCcpqeMlERLh5crgYyCU7TL71RIj4ZED7v1EkDXpjt8VYinvdPWWNf1z3_nGh-ExDxsx82qKf2Oti7UjHU-iebzLiM2km6qAz8WF3BArKupvjNYrpoYUr6X3lhBRJU/s1600/d03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="245" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMtpd3fqIK56Rd8XCcpqeMlERLh5crgYyCU7TL71RIj4ZED7v1EkDXpjt8VYinvdPWWNf1z3_nGh-ExDxsx82qKf2Oti7UjHU-iebzLiM2km6qAz8WF3BArKupvjNYrpoYUr6X3lhBRJU/s400/d03.png" width="400" /></a></div>
<br />
<b>5. Abre el proyecto en Visual Studio. Una vez cargado el proyecto, selecciona Limpiar solución desde el menú Compilar.</b> (Explicación: Vamos a remover referencias relativas al equipo original donde fue creado el proyecto).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiojHUHPTRzyFb8Mn9xNEL8ytGVeEPQ6ySL4PWT9DkLmzmN9PFmGLI3sRF9nriOD83eMxHL7vSZ8jzxQVWvBDi4B4YxNvBYdwhhsG1WShXjlW2zM2h7-GAwUKBK0OW45LCmwRAlYiShTy0/s1600/d04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="278" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiojHUHPTRzyFb8Mn9xNEL8ytGVeEPQ6ySL4PWT9DkLmzmN9PFmGLI3sRF9nriOD83eMxHL7vSZ8jzxQVWvBDi4B4YxNvBYdwhhsG1WShXjlW2zM2h7-GAwUKBK0OW45LCmwRAlYiShTy0/s400/d04.png" width="400" /></a></div>
<br />
<b>6. Revisa que la operación concluya con éxito.</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkmIataH6z3UhTCQGL3SP3RWPD8k9C1FY9fwZccVLwWb3WSB_0Avlgup2VASnkUF-JKnXV3n3ukXqPHBPp4yO73mAB0Abbib-1JiqtYCYySB4G92HfO7KdSS2Oa1L9sGfn3IVvTw59Us8/s1600/d05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="97" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkmIataH6z3UhTCQGL3SP3RWPD8k9C1FY9fwZccVLwWb3WSB_0Avlgup2VASnkUF-JKnXV3n3ukXqPHBPp4yO73mAB0Abbib-1JiqtYCYySB4G92HfO7KdSS2Oa1L9sGfn3IVvTw59Us8/s400/d05.png" width="400" /></a></div>
<br />
<b>7. Da clic derecho en la solución y selecciona la opción Administrador de configuración.</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh32gmSzqw7gMaU40yrL7JSEEhNlQbYXb20IU7m_u8FiZiHEnJ6ObRWANrXeHp1rSAjuZhuj6R79ZQuW8DR6IUvfWZPj9pwf_wa9CMNTDVdW_ZSX-BeJi_OD1C1p42xjPjsc9aX7vjy108/s1600/d06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="330" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh32gmSzqw7gMaU40yrL7JSEEhNlQbYXb20IU7m_u8FiZiHEnJ6ObRWANrXeHp1rSAjuZhuj6R79ZQuW8DR6IUvfWZPj9pwf_wa9CMNTDVdW_ZSX-BeJi_OD1C1p42xjPjsc9aX7vjy108/s400/d06.png" width="400" /></a></div>
<br />
<b>8. Por cada proyecto, </b>selecciona la <b>Configuración </b>deseada (normalmente Debug, pero puede ser que desees probar Release), <b>Plataforma</b> (de acuerdo al dispositivo/emulador donde probarás la solución, puede ser Any CPU, x86, x64, ARM), marca en <b>Compilación</b> todas las plataformas que quieras que Visual Studio compile (normalmente todas, aunque no tiene mucho caso compilar el proyecto de iOS si no tienes Mac) y en <b>Implementar </b>marca aquellos proyectos en los que vas a probar tu aplicación (aquí normalmente solo se habilitarán aquellas plataformas soportadas por tu equipo, por ejemplo Android, Windows Phone, UWP en un equipo con Windows, mientras que iOS aparecería si tienes una Mac local/en red). Da clic en Cerrar una vez finalizada esta operación.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdt25esMU5yvGP2JvIWkC1El7tgEZu1nE1g2BLWBR8Fofq_e3TtxS5MVEri4Wbk2YRy8cYgoePzVFhsPCgteDacCB1-ESfhbIMWk9g62R62cy6-jEm1G2vM6YQaVjC1jnAyE8h4IJ1L0s/s1600/d07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="251" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdt25esMU5yvGP2JvIWkC1El7tgEZu1nE1g2BLWBR8Fofq_e3TtxS5MVEri4Wbk2YRy8cYgoePzVFhsPCgteDacCB1-ESfhbIMWk9g62R62cy6-jEm1G2vM6YQaVjC1jnAyE8h4IJ1L0s/s400/d07.png" width="400" /></a></div>
<br />
<b>9. Nuevamente dando clic derecho en la solución, selecciona la opción Restaurar paquetes de Nuget si está habilitada. </b>Esto descargará todos los paquetes necesarios para que la aplicación funcione correctamente de acuerdo al contenido del archivo packages.config. Si bien este paso es opcional, pues de todas formas se descargarán los paquetes al compilar el proyecto en caso de que no hayan sido agregados aún, es recomendable hacerlo ahora para que no se muestren errores en el código fuente por falta de librerías.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrLtUC_u3-agBBaPz2Mqg98SGotV5Sr5Pku4gmhZ1ENV5e7oyHcdKJwBdAAmrsH116Ho4TEik0pOF275WDlU_6gaIW1CHHv6rYVN2kqyzrAHZnWZ1h8nWCIJOz-pxjREp1osZilO-xULg/s1600/d09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrLtUC_u3-agBBaPz2Mqg98SGotV5Sr5Pku4gmhZ1ENV5e7oyHcdKJwBdAAmrsH116Ho4TEik0pOF275WDlU_6gaIW1CHHv6rYVN2kqyzrAHZnWZ1h8nWCIJOz-pxjREp1osZilO-xULg/s320/d09.png" width="320" /></a></div>
<br />
<b>NOTA: </b>En ocasiones las instrucciones del proyecto te dirán que actualices o uses una versión específica de un paquete Nuget o tal vez que debes realizar pasos adicionales de configuración del proyecto. Solamente sigue los pasos mencionados y no deberías tener complicaciones =)<br />
<br />
<b>10. Una vez agregados los paquetes, selecciona el proyecto que vas a establecer como proyecto de inicio</b> (por ejemplo el de Android, iOS o UWP) dando clic derecho sobre el proyecto y seleccionando dicha opción.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVt0MDqGLKm3uVS0FL2l9c0uDKZYSjo2jmtY7i85u7Ol3Gcpa7YKB_UEVgpuMX80mD-ix5vGNJhSWKhXg4iKQfcjBc34BIRXAXR0YBmL4EblEIvKwEZERJDHpPN8tOkNhYuVpLlo4BJeM/s1600/d08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="351" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVt0MDqGLKm3uVS0FL2l9c0uDKZYSjo2jmtY7i85u7Ol3Gcpa7YKB_UEVgpuMX80mD-ix5vGNJhSWKhXg4iKQfcjBc34BIRXAXR0YBmL4EblEIvKwEZERJDHpPN8tOkNhYuVpLlo4BJeM/s400/d08.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b>11. Si las instrucciones del proyecto no indican que debas modificar el código fuente o configurar alguna opción, entonces compila y ejecuta la aplicación. Si no hay errores, podrás ver que tu app funciona correctamente.</b></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6XycHEJszCYWFWMVanoUgy4LTduZ2k0iQhoF6VCVR-OvJqKV9hyphenhyphenJastPRnwNW307nwJh_Xk9ouLj402jbRr0kNiYvncWGK04w_6ktmXbwooDZ0EFYraVuyhJ2pote5Z5OqwTapJLvTZc/s1600/d09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6XycHEJszCYWFWMVanoUgy4LTduZ2k0iQhoF6VCVR-OvJqKV9hyphenhyphenJastPRnwNW307nwJh_Xk9ouLj402jbRr0kNiYvncWGK04w_6ktmXbwooDZ0EFYraVuyhJ2pote5Z5OqwTapJLvTZc/s400/d09.png" width="225" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
¡Listo! Si bien esta guía es genérica, es algo que me ha funcionado en el 95% de los casos. Como dije, habrá proyectos (ese 5%) que tendrán alguna cuestión que haga imposible su ejecución (por ejemplo que solo funcione para una versión específica -nueva u obsoleta- de Android/Xamarin, que requiera algunos componentes adicionales instalados)...</div>
<div>
<br /></div>
<div>
¿Fácil, no? <span style="font-size: 14.85px;">Espero esta entrada haya sido de utilidad para tí, en caso afirmativo no dudes en compartirla con tus amigos :) También puedes dejarme un comentario para hacerme saber qué te pareció esta publicación o si te interesa que cubra algún tema en el futuro.</span></div>
<div class="post-body entry-content" id="post-body-2041479707122379785" itemprop="description articleBody" style="font-size: 14.85px; line-height: 1.4; position: relative; width: 528px;">
<br />
¡Saludos y hasta la próxima!</div>
Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com0tag:blogger.com,1999:blog-8407795827837136717.post-20414797071223797852017-04-24T15:29:00.002-07:002017-04-24T15:35:10.500-07:00Instalación de Xamarin en Visual Studio 2017¡Hola! Hago una pausa de la serie de <a href="http://icebeamwp.blogspot.cz/search/label/Xamarin-WCF-SP-EF" style="font-weight: bold;" target="_blank">Xamarin, WCF, Stored Procedures y Entity Framework</a> y les comparto una entrada rápida aprovechando que se reinician las actividades del #XamarinDiplomado, al cual te puedes inscribir dando clic <a href="http://bit.ly/diplomadoxamarin" target="_blank">aquí</a>, si aún no lo has hecho.<br />
<br />
Precisamente al respecto del diplomado, se mencionó que ahora puedes utilizar <b>Visual Studio 2015 o Visual Studio 2017 (Community Edition</b> en ambos casos<b>) </b>para realizarlo. En esta entrada vamos a ver qué necesitas para instalar Xamarin junto con Visual Studio 2017 desde una instalación nueva, pues el asistente de instalación de VS2017 cambió con respecto a la versión anterior.<br />
<br />
Aclaro el siguiente punto: <b>Puedes tener instalado tanto VS2015 como VS2017 en tu mismo entorno de trabajo sin problemas</b>. Sin embargo, por cuestiones de poco espacio disponible en disco duro, yo decidí primero desinstalar completamente VS2015 y luego instalar VS2017.<br />
<br />
También les comento otra cosa: Primero instalé VS2017 en Windows 8.1 Professional y nunca pude crear ni mucho menos ejecutar los proyectos de Windows 10, así que primero tuve que actualizar a Windows 10 mi equipo de cómputo y luego reinstalar VS2017. En resumen: <b>Se recomienda instalar VS2017 en Windows 10 Pro</b> (si tienes la versión Home, en lugar de usar los emuladores de Visual Studio -basados en Hyper-V- ocuparás otros como Genymotion o Xamarin Android Player).<br />
<br />
(Y en caso de que desees utilizar la versión 2015 de Visual Studio, <b><a href="https://msmdotnet.wordpress.com/2016/10/19/hello-xamarin-hands-on-lab/" target="_blank">aquí</a></b> te dejo una guía de instalación de Xamarin muy buena creada por <b>Miguel Muñoz Serafín, MVP de Microsoft</b>).<br />
<br />
¡Manos a la obra! Observa lo sencillo que es instalar Xamarin:<br />
<br />
Primero que nada, el instalador de Visual Studio 2017 introduce el concepto de <i>workloads </i>(cargas de trabajo), las cuales básicamente son grupos de componentes relacionados entre sí para crear tipos de proyectos similares. Entonces, al ejecutar el instalador de Visual Studio, en primer lugar busca el workload <b>Windows</b> y marca tanto <b>Desarrollo de Universal Windows Platform</b> y <b>Desarrollo de escritorio .NET</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi51NiZ6ZZGPLG_8_VgOISo63_giYlZAxAkSg0PC7Ty83SXpGIDmqJGykv7CO5HFfAQOd6z4XqYlxAta14nL9zjJDTHbyZDroCQuIkx7ErAKl5XYwV30VgrtfingD43B-Z2SvCMdieGHAc/s1600/workload-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="125" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi51NiZ6ZZGPLG_8_VgOISo63_giYlZAxAkSg0PC7Ty83SXpGIDmqJGykv7CO5HFfAQOd6z4XqYlxAta14nL9zjJDTHbyZDroCQuIkx7ErAKl5XYwV30VgrtfingD43B-Z2SvCMdieGHAc/s400/workload-1.png" width="400" /></a></div>
<br />
<a name='more'></a><br />
<br />
A continuación, busca el workload <b>Movíl y Juegos</b>, seleccionando <b>Desarrollo de aplicaciones móviles con .NET</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRxpLfhX_fU-mB8oBtIhKhEy2ZV0TxLrj1bRxLVrFbqhJuRU51tneIy1Kz_-o_AhVfZwUI514NEpBYBrM0uW7qxiFd2Hjr5L0PZFi9U5-92KctSuDQjRBkpePF2b8-SeBkVscrTwHJ_a8/s1600/workload-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="165" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRxpLfhX_fU-mB8oBtIhKhEy2ZV0TxLrj1bRxLVrFbqhJuRU51tneIy1Kz_-o_AhVfZwUI514NEpBYBrM0uW7qxiFd2Hjr5L0PZFi9U5-92KctSuDQjRBkpePF2b8-SeBkVscrTwHJ_a8/s400/workload-2.png" width="400" /></a></div>
<br />
El tercer paso es ir a la pestaña <b>Componentes iniciales</b> y seleccionar los siguientes elementos: <b>Emulador de Android para Visual Studio</b> y <b>Emulador de Windows 10 Mobile</b> (el que aparezca, puede ser el de la Edición de Aniversario). También deberían aparecer seleccionados el <b>Emulador de Google Android (API Level xx)</b> y el <b>HAXM</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYonXDuYlqCzFsws2bx6v4EicIAfr4IDNo3X6jpyiIOtCM4mhidCEhmqYrtrNRHnUSlcyC3GDSvtr_k13LcQy_KvkHvC5yuh_DBC9FHpuJYncgRzBE3_TGuJcvvoLasG4-kTBVrGX5VoA/s1600/workload-3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="158" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYonXDuYlqCzFsws2bx6v4EicIAfr4IDNo3X6jpyiIOtCM4mhidCEhmqYrtrNRHnUSlcyC3GDSvtr_k13LcQy_KvkHvC5yuh_DBC9FHpuJYncgRzBE3_TGuJcvvoLasG4-kTBVrGX5VoA/s400/workload-3.png" width="400" /></a></div>
<br />
¡Y listo! El instalador comenzará la descarga de los componentes necesarios. Ve por un café (o 2, o 3, porque va a tardar).<br />
<br />
En teoría esto es todo lo que necesitas para instalar Xamarin desde VS2017. Si tienes algún problema con la instalación, déjame un comentario y lo resolvemos.<br />
<br />
También puedes unirte a la conversación en nuestro <b><a href="https://www.facebook.com/groups/xamarindiplomadoitc/" target="_blank">grupo de Facebook</a></b>, donde una comunidad de más de 2600 desarrolladores podrá ayudarte.<br />
<br />
Espero esta entrada haya sido de utilidad para tí, en caso afirmativo no dudes en compartirla con tus amigos :)<br />
<br />
¡Saludos y hasta la próxima!Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com6tag:blogger.com,1999:blog-8407795827837136717.post-27020772657989220442017-04-19T04:07:00.000-07:002017-04-19T11:08:59.800-07:00Xamarin, WCF, Stored Procedures y Entity Framework (Parte 2)¡Hola! Bienvenido a la parte 2 de la serie <b><a href="http://icebeamwp.blogspot.cz/search/label/Xamarin-WCF-SP-EF" target="_blank">Xamarin, WCF, Stored Procedures y Entity Framework</a> </b>en la que crearemos un servicio WCF que combinará las tecnologías de Entity Framework y JSON a fin de recuperar la información de una base de datos.<br />
<br />
En la parte 1 (disponible <a href="http://icebeamwp.blogspot.cz/2017/04/xamarin-wcf-sp-ef-parte1.html" target="_blank"><b>aquí</b></a>) creamos una base de datos con información de Artistas, Canciones y Conciertos (así como su detalle) junto con los procedimientos almacenados a fin de realizar las operaciones CRUD.<br />
<br />
Antes de comenzar con el tema de hoy, <b>quiero agradecer enormemente a todos los que se tomaron la molestia de leer la primer entrega 😃.</b> Es motivante saber que la respuesta ha sido muy grata e incluso he recibido sugerencias y comentarios que permitirán mejorar futuras sesiones :) Los comentarios han sido positivos y la retroalimentación muy buena. Por ejemplo, en uno de los grupos de Facebook me solicitaron hablar de <b>WebApi</b>, otra sugerencia fue hablar de seguridad con <b>JWT</b> y finalmente, hacer la versión en <b>video</b> de estas sesiones. Dado que son muy buenas ideas, <b>SÍ</b> las voy a tener en cuenta, esperen su implementación en próximas entregas... <b>Lo prometo</b> ✋<br />
<br />
Espero que estas sesiones, aunque son algo largas, sean de utilidad para sus proyectos. Por otra parte, disculpen si me extiendo en ocasiones jeje, pero es que hay tanto de qué hablar que quiero compartir lo más que se pueda. Así que gracias por sus mensajes y sigan comentando de qué otros temas quisieran que hablara en el blog, así aprendemos entre todos 😀<br />
<br />
Continuamos entonces. El repositorio de GitHub donde actualizaré el proyecto poco a poco se encuentra <b><a href="https://github.com/icebeam7/xamarin-wcf-sp-ef" target="_blank">aquí</a> </b>(ya incluye la parte 2, por supuesto :) )<br />
<br />
Consideraciones si descargas y quieres ejecutar la solución inmediatamente:<br />
<br />
<ul>
<li>Debes haber realizado la práctica 1, es decir, que los procedimientos almacenados estén en la base de datos.</li>
<li>Debes modificar la cadena de conexión en Web.config para incluir los datos de tu servidor, usuario y contraseña.</li>
<li>Se recomienda limpiar la solución en Visual Studio (Build --> Clean Solution)</li>
<li>Debes restaurar los paquetes Nuget del proyecto (se debería realizar al compilar y ejecutar la aplicación).</li>
</ul>
<br />
<a name='more'></a><br />
En cambio, si quieres iniciar el proyecto desde cero (lo recomendable, para que aprendas, jeje), ¡pues continuamos donde nos quedamos!<br />
<div>
<br />
Para esta sesión utilizaremos <b>Visual Studio</b>. Cualquier versión (2012, 2015, 2017) te va a servir. En este caso, yo lo hice con la versión <b>Community 2017</b>.</div>
<div>
<br />
A lo largo de esta sesión analizaremos varios conceptos, a saber:<br />
<br />
<ul>
<li>Servicios WCF</li>
<li>EntityFramework</li>
<li>Serialización JSON</li>
</ul>
<br />
Comenzamos describiendo el primer concepto. Un <b>Servicio WCF</b> <b>(Windows Communication Foundation)</b> es un framework de Microsoft que permite crear un servicio que expone un web endpoint (extremo) para enviar datos en algún formato de salida (típicamente JSON, pero existen otros, como XML, TXT, CSV...) hacia otro extremo, que normalmente es una aplicación que consume dicho servicio. Por lo general, este servicio es hospedado en un servidor (local o en la nube) para que esté disponible para su consumo por parte de una o varias aplicaciones. Algunas ventajas de este servicio WCF son:<br />
<br />
<br />
<ul>
<li>Seguridad: Toda la información de conexión a la fuente de información se queda en el servidor donde esté alojado el servicio, por lo que no se expone riesgo de seguridad alguno al distribuir las aplicaciones cliente que consumen el servicio. Para maximiza la seguridad, es posible encriptar los datos que viajan por la red <i><b>(¡luego lo hacemos en una futura entrada si quieren!)</b></i>, así como autentificar a los usuarios para que solo aquellos autorizados accedan a la información, pero esto depende del nivel de seguridad que deseemos implementar. </li>
</ul>
<div>
<br /></div>
<ul>
<li>Diversidad: Prácticamente cualquier tipo de aplicación puede consumir el servicio: aplicaciones de consola, IoT, móviles, web, de escritorio...</li>
</ul>
<div>
<br /></div>
<ul>
<li>Independencia de lenguaje: No importa el lenguaje de programación en que estén desarrolladas las aplicaciones cliente que consumen el servicio (por ejemplo, el servicio WCF puede estar creado en C#/VB .NET y la aplicación cliente desarrollada en PHP, Java o incluso C#).</li>
</ul>
<div>
<br /></div>
<ul>
<li>Independencia de plataforma: Si bien WCF es un modelo propio creado por Microsoft, esto no significa que las aplicaciones cliente que consuman el servicio tengan que serlo. Se puede escribir una aplicación en Java/Android/PHP/iOS que perfectamente puede obtener los datos del servicio.</li>
</ul>
<br />
Por el momento, dejamos la teoría ahí y vamos a Visual Studio para comenzar con el proyecto.</div>
<div>
<br />
Crea un Nuevo proyecto de tipo <b>Aplicación de Servicios WCF</b> (en la categoría <b>WCF</b>) llamado <b>ServicioMusicaWCF</b>.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOlc-RymE4GiNnJ2m1XznlR1FRzQmnWwSgKqHyheNTjLEF87m0ZtzJMKb9SiZtKxqwNjdF81E5qcmukb0bvKVYIsQdYI4e2w7osCUYA8wwQ0zF8Nrf-9hDhUTHdqEDKQLfzEY4QrhyhCc/s1600/01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOlc-RymE4GiNnJ2m1XznlR1FRzQmnWwSgKqHyheNTjLEF87m0ZtzJMKb9SiZtKxqwNjdF81E5qcmukb0bvKVYIsQdYI4e2w7osCUYA8wwQ0zF8Nrf-9hDhUTHdqEDKQLfzEY4QrhyhCc/s400/01.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
Por defecto, un proyecto de servicio WCF consta de varios elementos:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRt8YyERta6M9kzzZ2O17UENyt2pRHIXUOVcnGnzIH5GPREcpXuRjUouW-WxBD4-4Grmeg7Y8qh4qLpXU5mncsUBWq5_fa2_L3j9pKB1ovXA1LBn3mXOPzeJoBQfIYeldqcLTa3YtYqmE/s1600/00.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRt8YyERta6M9kzzZ2O17UENyt2pRHIXUOVcnGnzIH5GPREcpXuRjUouW-WxBD4-4Grmeg7Y8qh4qLpXU5mncsUBWq5_fa2_L3j9pKB1ovXA1LBn3mXOPzeJoBQfIYeldqcLTa3YtYqmE/s1600/00.png" /></a></div>
<br />
<br />
<ul>
<li><b>IService1.cs </b>es una interfaz que define la estructura del servicio</li>
<li><b>Service1.svc </b>es el servicio en sí y contiene una clase que implementa la interfaz con su funcionalidad</li>
<li><b>Web.config </b>es el archivo de configuración típico de proyectos web </li>
</ul>
<br />
Por medio del Explorador de Soluciones, <b>elimina </b>tanto la interfaz<b> IService1.cs </b>como el servicio <b>Service1.svc</b>. Ahora agrega al proyecto un <b>ServicioWCF</b> llamado <b>ServicioMusica </b>(en la categoría <b>Web</b>).<b> </b>Esto creará una interfaz llamada<b> IServicioMusica.cs</b> y el servicio <b>ServicioMusica.svc</b> con su clase.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgj_r-n3rYsIngZ3dZNoS650d-iEVvr_eEo4o6oV3RBmL6BfAt_gl-bthV4rCwG39uIv2veYyS1D6O-WK_79CVyJTBm09lrqd4Gshp8Tt8l9SmpCKgYCNSMbiwHS1UmI6hpCt_mvoxfwqY/s1600/20.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgj_r-n3rYsIngZ3dZNoS650d-iEVvr_eEo4o6oV3RBmL6BfAt_gl-bthV4rCwG39uIv2veYyS1D6O-WK_79CVyJTBm09lrqd4Gshp8Tt8l9SmpCKgYCNSMbiwHS1UmI6hpCt_mvoxfwqY/s400/20.png" width="400" /></a></div>
<br />
Vamos a comenzar codificando la interfaz. Recuerda que una interfaz es un "contrato", ¿y qué pasa con los contratos?</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiJBq3c-5KL9ymy9GPTM0Dl9DkKamQDgCIjccKQj6qMpPuuWIaHRSVqFTb8tTxKwrFDLS2yivIIaZozUhTk4ew2k0d_OuPalxcfmoUOxu_SoOHw5LzKjhtYYUj1BZm8E2bKSdPdWW6rhg/s1600/03.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="380" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiJBq3c-5KL9ymy9GPTM0Dl9DkKamQDgCIjccKQj6qMpPuuWIaHRSVqFTb8tTxKwrFDLS2yivIIaZozUhTk4ew2k0d_OuPalxcfmoUOxu_SoOHw5LzKjhtYYUj1BZm8E2bKSdPdWW6rhg/s400/03.jpg" width="400" /></a></div>
<div>
<br /></div>
<div>
Pues eso. <b>Si una clase implementa una interfaz, todos los métodos que se definan en la interfaz deberán ser incluidos (y codificados) en la clase siguiendo las reglas establecidas (definición).</b> Entonces, en la interfaz <b>IServicioMusica</b> definiremos los métodos que nuestro servicio <b>ServicioMusica</b> va a implementar posteriormente. Básicamente, estos métodos llaman a los 19 procedimientos almacenados definidos en la parte 1. El código es el siguiente:</div>
<div>
<br />
<pre class="brush:csharp;first-line:1">using System;
using System.ServiceModel;
namespace ServicioMusicaWCF
{
[ServiceContract]
public interface IServicioMusica
{
[OperationContract]
string ObtenerArtistas();
[OperationContract]
string BuscarArtista(int id);
[OperationContract]
string AgregarArtista(string nombre, string pais);
[OperationContract]
string ModificarArtista(int id, string nombre, string pais);
[OperationContract]
string EliminarArtista(int id);
[OperationContract]
string ObtenerCanciones();
[OperationContract]
string BuscarCancion(int id);
[OperationContract]
string AgregarCancion(string titulo, string duracion);
[OperationContract]
string ModificarCancion(int id, string titulo, string duracion);
[OperationContract]
string EliminarCancion(int id);
[OperationContract]
string ObtenerConciertos();
[OperationContract]
string BuscarConcierto(int id);
[OperationContract]
string AgregarConcierto(int idArtista, string lugar, DateTime fecha);
[OperationContract]
string ModificarConcierto(int id, int idArtista, string lugar, DateTime fecha);
[OperationContract]
string EliminarConcierto(int id);
[OperationContract]
string ObtenerDetallesConcierto(int idConcierto);
[OperationContract]
string AgregarDetalleConcierto(int idConcierto, int idCancion, int orden);
[OperationContract]
string ModificarDetalleConcierto(int idConcierto, int idCancion, int orden);
[OperationContract]
string EliminarDetalleConcierto(int idConcierto, int idCancion);
}
}</pre>
<br /></div>
<div>
<br />
Observamos lo siguiente:<br />
<ul>
<li>Cada método contiene el atributo <b>OperationContract</b>, que significa que estará disponible para ser consumido por una aplicación externa (es decir, que aparecerá listado en el servicio). Si no lo tuviera, no aparecería en la definición del servicio.</li>
</ul>
<div>
<br /></div>
<ul>
<li>Cada método se define exactamente igual que la llamada a su procedimiento almacenado respectivo (por ejemplo, el método <b>BuscarArtista</b> recibe de parámetro un entero e implementará el procedimiento almacenado <b>Procedimiento_BuscarArtista</b>, que también recibe un entero. La única diferencia es que aquí <b>no necesitamos el parámetro de salida mensaje</b>, más bien ése lo agregaremos nosotros en la implementación.</li>
</ul>
<div>
<br /></div>
<ul>
<li>Cada método devuelve un <b>string</b> porque en la implementación convertiremos los resultados devueltos por el procedimiento almacenado al formato de salida <b>JSON</b>, que es muy utilizado hoy en día en aplicaciones web, móviles y demás debido a que es ligero, independiente de plataforma y sencillo de serializar/deserializar.</li>
</ul>
</div>
<div>
<br />
Antes de implementar el servicio, vamos a definir cómo nos vamos a conectar al origen de datos. Una forma sería a través del espacio de nombres System.Data (similar a como lo expliqué <a href="http://icebeamwp.blogspot.cz/2016/09/conectando-una-app-de-xamarin-con-sql.html" style="font-weight: bold;" target="_blank">aquí</a>, utilizando DataSets, DataTables, SQLConnections...) pero esa forma ya ha quedado un poco obsoleta. Una alternativa muy popular hoy en día es a través de <b>EntityFramework</b>, que es el segundo concepto que vamos a explicar en esta sesión.<br />
<br />
EntityFramework es un ORM (Object-Relational Mapping) para la plataforma .NET que permite (como el tipo lo sugiere) mapear los tipos (Tablas/campos) de una base de datos a tipos definidos en un lenguaje de programación orientado a objetos (Clases/propiedades), maximizando la portabilidad y manteniendo la lógica entre la fuente de datos y la aplicación.<br />
<br />
Por ejemplo, la tabla Artistas con los campos Id (int), Nombre (varchar) y Pais (varchar) se puede mapear a una clase (en EF típicamente la conocemos como Entidad) Artistas con las propiedades Id (int), Nombre (string) y Pais (string).<br />
<br />
Pero el mapeo realizado por EF va más allá de una tabla/clase. También se crean los elementos necesarios para modelar llaves primarias, relaciones entre tablas (por medio de las llaves foráneas), procedimientos almacenados y más elementos.<br />
<br />
El modelado (mapeo) es automatizado después de realizar ciertos pasos, que son los que vamos a realizar a continuación.<br />
<br />
Agregamos un nuevo elemento a nuestro proyecto de tipo <b>ADO .NET Entity Data Model</b> (se encuentra en la categoría <b>Datos</b>) y lo llamaremos <b>ModeloMusica</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDt1rT18M05DJIoyivoRbj8_zLhCi736LvkRKQ535qDY0tSbZG5ZcZfX5nObCQX5Ub3nBVlelSHELYuWut860Rdk7-uOhSj1ACZDoji7mIS8knYXqoUNP0sOOuUxNVloYkZGK5MC3qthw/s1600/04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDt1rT18M05DJIoyivoRbj8_zLhCi736LvkRKQ535qDY0tSbZG5ZcZfX5nObCQX5Ub3nBVlelSHELYuWut860Rdk7-uOhSj1ACZDoji7mIS8knYXqoUNP0sOOuUxNVloYkZGK5MC3qthw/s400/04.png" width="400" /></a></div>
<br />
Esto inicializará un asistente (wizard). En primer lugar, selecciona EF Designer desde base de datos y da clic en Siguiente.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixCCvpmnmW1iRYlH4IqFcISuaOPtgu3pNdsaT9PGe_MczKnT_Hut8I8jabTYU6s6TPisZE734S-mqA19JDjg4EL7UeH8-mufSSJnF78B9x-b-jwwafjOMqSEJGVqoR8sknHLOuIYARf2o/s1600/05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="361" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixCCvpmnmW1iRYlH4IqFcISuaOPtgu3pNdsaT9PGe_MczKnT_Hut8I8jabTYU6s6TPisZE734S-mqA19JDjg4EL7UeH8-mufSSJnF78B9x-b-jwwafjOMqSEJGVqoR8sknHLOuIYARf2o/s400/05.png" width="400" /></a></div>
<br />
Da clic en <b>Nueva conexion</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUJRk6SImg5QwTkQMeQgm9NjdHE9hLtPt4OvZPeDaLY3986Xv1c2eox7u10_osBOk_dhr7lEzL3CH4F8fgBOSfbP_NxfZzB2H5PmkOM6mHomSDHLPKUao1bEgt2PMSsBbJL-BlywjVKKU/s1600/06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="362" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUJRk6SImg5QwTkQMeQgm9NjdHE9hLtPt4OvZPeDaLY3986Xv1c2eox7u10_osBOk_dhr7lEzL3CH4F8fgBOSfbP_NxfZzB2H5PmkOM6mHomSDHLPKUao1bEgt2PMSsBbJL-BlywjVKKU/s400/06.png" width="400" /></a></div>
<br />
<br />
Ahora selecciona <b>Microsoft SQL Server</b> en el Origen de datos y da clic en <b>Aceptar</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNgjMKF6kgbQBO3Lj6Ikf45ndISK84GH_nURB0MBUScUNYwsmzhUD4MjV-685GAZiGeDaGTL5pAt_W34iNWHeUfz6Wuu7UBHxbU_bz20_hSKQB1K5Z45L2mu55g6e8iqPS0KrUOLPlr0I/s1600/07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="231" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNgjMKF6kgbQBO3Lj6Ikf45ndISK84GH_nURB0MBUScUNYwsmzhUD4MjV-685GAZiGeDaGTL5pAt_W34iNWHeUfz6Wuu7UBHxbU_bz20_hSKQB1K5Z45L2mu55g6e8iqPS0KrUOLPlr0I/s400/07.png" width="400" /></a></div>
<br />
<br />
En <b>Propiedades de la conexión </b>debes especificar varios datos en el siguiente orden:<br />
<br />
<br />
<ul>
<li>Primero, el <b>nombre del servidor</b> (esto lo obtienes de tu conexión a SQL Server), que típicamente es el nombre de tu equipo. Si estás usando SQL Server Express, seguramente tendrás que agregar la instancia (por ejemplo equipo\SQLExpress).</li>
</ul>
<div>
<br /></div>
<ul>
<li>A continuación, selecciona <b>Autenticación de SQL Server</b> (eso significa que debes tener un usuario en SQL Server).</li>
</ul>
<div>
<br /></div>
<ul>
<li>Introduce el nombre de <b>usuario</b> y <b>contraseña</b> de tu usuario y marca la opción <b>Guardar mi contraseña</b>.</li>
</ul>
<div>
<br /></div>
<ul>
<li>Selecciona la base de datos <b>Musica</b>.</li>
</ul>
<div>
<br /></div>
<ul>
<li>Verifica que la conexión se puede realizar dando clic en el botón <b>Probar conexión</b>. Si funciona, da clic en Aceptar.</li>
</ul>
<div>
<br /></div>
<ul>
<li>Resumen:</li>
</ul>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKLhjYaAl0igWXy3ti7VLHQC1nD7wcbuGOvEt5UYH3-7ibMTsWlLZSAXsEfGndxUBUILjBTrfJ8AYOEfCKr-WXhKo-lj0QLMk7Tr-mn7O3L2Nu-wUdkRq42e-ElHVMuSAzFOwwf4mowzM/s1600/08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKLhjYaAl0igWXy3ti7VLHQC1nD7wcbuGOvEt5UYH3-7ibMTsWlLZSAXsEfGndxUBUILjBTrfJ8AYOEfCKr-WXhKo-lj0QLMk7Tr-mn7O3L2Nu-wUdkRq42e-ElHVMuSAzFOwwf4mowzM/s400/08.png" width="338" /></a></div>
<br />
Ahora selecciona la opción <b>Si, incluir datos confidenciales en la cadena de conexión</b>. Además, marca la casilla de <b>Guardar configuración en Web.Config</b> y coloca el nombre <b>MusicaEntidades</b>. Da clic en <b>Siguiente</b>.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2ilUyzl3xHLgPnf8b5wB_47XD4kD3FMVbthMRPLd4ixvRBsUtQ2063bnJaG9fBWMmyT_eHqTND7f8shhjMYeWQ-BB0v1Ugb1aD0gbCduVl3pFrbnNM8H7hqTXzKX86JjIRc6f-RAhmpI/s1600/10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="358" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2ilUyzl3xHLgPnf8b5wB_47XD4kD3FMVbthMRPLd4ixvRBsUtQ2063bnJaG9fBWMmyT_eHqTND7f8shhjMYeWQ-BB0v1Ugb1aD0gbCduVl3pFrbnNM8H7hqTXzKX86JjIRc6f-RAhmpI/s400/10.png" width="400" /></a></div>
<br />
Selecciona la versión <b>EntityFramework 6.x</b> y da clic en <b>Siguiente</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh04HZ6lVue_9gWY1uh0AfDFXQE9XWJOewNLapK3NTzRNn4SH_prYaSKgGseT_os2q7A13bHADxrdsHcaUxSCrOJ7y4Hu2N5CMCurTGo4E7fBZpI9JJTTdVITWvbwx7RGRX0EuJ0OnzsaY/s1600/11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="357" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh04HZ6lVue_9gWY1uh0AfDFXQE9XWJOewNLapK3NTzRNn4SH_prYaSKgGseT_os2q7A13bHADxrdsHcaUxSCrOJ7y4Hu2N5CMCurTGo4E7fBZpI9JJTTdVITWvbwx7RGRX0EuJ0OnzsaY/s400/11.png" width="400" /></a></div>
<br />
<br />
Ahora <b>selecciona las tablas y procedimientos almacenados </b>que se obtienen al realizar la conexión a la base de datos. Verifica que <b>solo las 4 tablas y los 19 procedimientos almacenados </b>creados estén seleccionados. Marca las opciones <b>Incluir columnas de clave externa </b>e <b>Importar procedimientos almacenados y funciones seleccionados</b> (pero <b>NO</b> marques la opción de Poner en plural o singular los nombres de objeto). El nombre del espacio de nombres será <b>MusicaModelo</b>. Da clic en <b>Finalizar</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCW7bVo8JpROgFWYHE8JvQsfxkVZVq72F-rlc4j7qM7_iX7IGhC6ljvDIf8PDZ9GzSA_cozHulgGkfX6R00KJ4aigQPRSxUBzYgKfg45WdHwnLKuPO19xpempaS-h_LWMCFQ9BjKo2Tpg/s1600/12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCW7bVo8JpROgFWYHE8JvQsfxkVZVq72F-rlc4j7qM7_iX7IGhC6ljvDIf8PDZ9GzSA_cozHulgGkfX6R00KJ4aigQPRSxUBzYgKfg45WdHwnLKuPO19xpempaS-h_LWMCFQ9BjKo2Tpg/s400/12.png" width="338" /></a></div>
<br />
Si te aparece una advertencia de ejecución de una plantilla de texto, selecciona la opción <b>No mostrar este mensaje de nuevo</b> y da clic en <b>Aceptar</b>. Descuida, todo lo que estamos realizando es una operación segura.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2FsrlJ529hooFN5rvqFoQeZIMFYs387jg7aYbZV12-W5z-p-zz8I287ezGze74LfDk_Tr5xfvTL6ekTT7kJYqgsPdeJ2IdI3WmPfMxNS3SMxox4cBvLJGHjrcYLShbAIN6zVeszIgBug/s1600/13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="147" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2FsrlJ529hooFN5rvqFoQeZIMFYs387jg7aYbZV12-W5z-p-zz8I287ezGze74LfDk_Tr5xfvTL6ekTT7kJYqgsPdeJ2IdI3WmPfMxNS3SMxox4cBvLJGHjrcYLShbAIN6zVeszIgBug/s400/13.png" width="400" /></a></div>
<br />
<br />
Una vez concluida la importación de elementos se habrá creado un elemento llamado <b>ModeloMusica.edmx</b>, el cual muestra el modelo generado a partir de tu base de datos, es decir, se ha creado un mapeado a entidades (clases) dentro del proyecto.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicDdUx09rFoeAE0qg5Z4Lh5a2e4NPIX2x0trQB5rfxWG11jFMSbTT3jaucXE2EB9QcenOTRS_BJEytWRhM6ovELqh4m3foooyx1K4kh68vX0B4O9HMQuSmodbFE-fgPvh_RsXsYJhpOuM/s1600/14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="281" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicDdUx09rFoeAE0qg5Z4Lh5a2e4NPIX2x0trQB5rfxWG11jFMSbTT3jaucXE2EB9QcenOTRS_BJEytWRhM6ovELqh4m3foooyx1K4kh68vX0B4O9HMQuSmodbFE-fgPvh_RsXsYJhpOuM/s400/14.png" width="400" /></a></div>
<br />
<br />
Compara el diagrama de este modelo con el diagrama de tu base de datos que generamos en la sesión anterior:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJAhUy8SKoHaOm2o5FAfcLfXXMlsTBw8dxYq2cB3fFwiVRr9DK2COdKEPCM4QdEMF4T5gOPq6Yo0PN7zVh5K2FfwWFDiOVyX10pgLliheA2FlPIHtmJHCgqbEVfskQGKbKeYSG51DBCSo/s1600/15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="356" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJAhUy8SKoHaOm2o5FAfcLfXXMlsTBw8dxYq2cB3fFwiVRr9DK2COdKEPCM4QdEMF4T5gOPq6Yo0PN7zVh5K2FfwWFDiOVyX10pgLliheA2FlPIHtmJHCgqbEVfskQGKbKeYSG51DBCSo/s400/15.png" width="400" /></a></div>
<br />
<br />
¡Es igualito! Observa como cada tabla está incluida como una entidad, como cada campo es ahora una propiedad y cómo también se han incluido las relaciones entre tablas y su cardinalidad (ejemplo: Un Artista puede aparecer en muchos Conciertos).<br />
<br />
<b>Un punto importante. </b>Si recuerdas en uno de los pasos aceptamos que la cadena de conexión fuera almacenada en <b>Web.config</b>. Bien, pues si abrimos dicho archivo, nos vamos a encontrar con lo siguiente:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0R-c49Kme9U-a8Z24ZVVOypS_o91cH_guU2ph-DroKGlpGoeW-IqTXS42wNxQSW0u1Lv62m9mt-D18Df_M6R1uO6-OOdYnn7MgF0ZO05yEGiLLFL_GIqd05VlBGhR6RiKQ59ExtytxvQ/s1600/27.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="165" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0R-c49Kme9U-a8Z24ZVVOypS_o91cH_guU2ph-DroKGlpGoeW-IqTXS42wNxQSW0u1Lv62m9mt-D18Df_M6R1uO6-OOdYnn7MgF0ZO05yEGiLLFL_GIqd05VlBGhR6RiKQ59ExtytxvQ/s400/27.png" width="400" /></a></div>
<br />
EntityFramework agrega un nuevo elemento en la sección <b>connectionStrings</b>, además de la configuración del propio EF, indicando el proveedor de datos (SQL Server). Si avanzamos un poco más a la derecha en la conexión <b>MusicaEntidades</b>, encontraremos la información específica de la cadena de conexión: <b>Data Source, Initial Catalog, User Id y Password</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipWQ65JdzfF9W6pg_CVgOPNshzJqTAfIwZATLkOzWQbHUoHNrIpHKlL9AoacDfcvO7k4Aua_CsCAL8tD5iti7h1l4zSwAdoMtQ-GBHKLh3u2mfMTikjTzGW0qY5DsaAgdBQqY53pQrI_A/s1600/28.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="35" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipWQ65JdzfF9W6pg_CVgOPNshzJqTAfIwZATLkOzWQbHUoHNrIpHKlL9AoacDfcvO7k4Aua_CsCAL8tD5iti7h1l4zSwAdoMtQ-GBHKLh3u2mfMTikjTzGW0qY5DsaAgdBQqY53pQrI_A/s640/28.png" width="640" /></a></div>
<br />
<b>Recuerda que si descargaste el proyecto </b>para que tu aplicación funcione tienes que editar esta cadena de conexión, modificando los valores:<br />
<br />
<ul>
<li>Data Source (en vez de icebeam, el nombre de tu servidor/equipo)</li>
<li>Initial Catalog (solo si tu base de datos se llamara diferente)</li>
<li>User Id (coloca tu usuario)</li>
<li>Password (coloca su password)</li>
</ul>
<br />
(Todo esto asumiendo que hiciste la práctica 1 y que ya tienes los procedimientos almacenados en tu base de datos).<br />
<br />
Otro elemento muy importante y del cual hablaremos posteriormente son las propiedades de navegación, pues permite obtener un acceso rápido a elementos relacionados por llave foránea. Por ejemplo, la entidad Concierto contiene Id, IdArtista, Lugar, Fecha y también un objeto Artista, lo cual permitirá obtener el Nombre y Pais del Artista de un Concierto específico (tal como si hubiéramos hecho una consulta Join en SQL). Luego detallaremos este punto, pues es esencialmente útil en LINQ al simplificar la manera de escribir las consultas.<br />
<br />
El archivo ModeloMusica.edmx es en realidad un archivo XML que contiene 3 elementos:<br />
<br />
<ul>
<li>CSDL (El modelo conceptual)</li>
<li>SSDL (El modelo lógico)</li>
<li>MSL (El mapeo o asignaciones entre ambos modelos)</li>
</ul>
<div>
<br /></div>
<div>
Abre el archivo ModeloMusica.edmx y da clic en el menú <b>Ver --> Otras ventanas --> Explorador de Entity Data Model</b>. Observa que en la sección Tipos de Entidad aparecen las tablas (si las abres, verás las propiedades que contienen).</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJReSuZ5FCWOUqYnT5rz-on33AroQtsrOzcOPw8rZzzF-onBhL8mc7qZzZEap8tMJoTYdQPKrPoBCPkiheIj2Z14u7SUoLAQZ6gjHR2tA-BBlZadCer6pueeABYas4Ju4bDNASmXeGD3A/s1600/16.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJReSuZ5FCWOUqYnT5rz-on33AroQtsrOzcOPw8rZzzF-onBhL8mc7qZzZEap8tMJoTYdQPKrPoBCPkiheIj2Z14u7SUoLAQZ6gjHR2tA-BBlZadCer6pueeABYas4Ju4bDNASmXeGD3A/s400/16.png" width="360" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
¿Y dónde quedaron los procedimientos almacenados? Pues se encuentran en la sección <b>Importación de funciones</b>. Observa que también es posible abrir cada procedimiento para ver los parámetros de cada uno.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI1OpKMtCDml00mnmhNmsHvKTxwe2GIgyG4MRP7plC9PZIS_vo80OE8nqj0q0e9lLuQlvRj1_MoG1BH8-mgsZCwIF61PAXuv6iQlevyHnHdudbaJjnnKV4ykWVvc10Z1m3fZxyLFJzUi8/s1600/17.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI1OpKMtCDml00mnmhNmsHvKTxwe2GIgyG4MRP7plC9PZIS_vo80OE8nqj0q0e9lLuQlvRj1_MoG1BH8-mgsZCwIF61PAXuv6iQlevyHnHdudbaJjnnKV4ykWVvc10Z1m3fZxyLFJzUi8/s400/17.png" width="256" /></a></div>
<div>
<br /></div>
<div>
Cuando los procedimientos almacenados fueron mapeados al EntityFramework, se crearon entidades adicionales que pueden ser optimizadas a fin de tener un modelo más ligero. Este paso hay que hacerlo por cada procedimiento almacenado de búsqueda u obtener mapeado (7 en total), pero es sencillo.<br />
<br />
Da doble clic en <b>Procedimiento_BuscarArtista</b> (o clic derecho sobre el procedimiento y seleccionando <b>Editar</b>). En la sección <b>Devuelve una colección de</b> selecciona <b>Entidades </b>y luego elige <b>Artistas</b> (por defecto aparece seleccionado el tipo Complejo con Procedimiento_BuscarArtista_Result, el cual es idéntico a Artistas, por lo que no necesitamos crear este tipo adicional a fin de optimizar el modelo). Da clic en Aceptar.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj25iUFnX3l8LcIEBVRIoBxaE1ejMBSMI2g0BD1o_KA8XtEtWQGIq1lr-WbQeDV37woH3oLNHxqNNPYr4H4EaHn28ClDJpMlBHgd3mCowtHlIN6DMQSCH9tXHs5rY-Xgpduk6WJhxZgY3s/s1600/18.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj25iUFnX3l8LcIEBVRIoBxaE1ejMBSMI2g0BD1o_KA8XtEtWQGIq1lr-WbQeDV37woH3oLNHxqNNPYr4H4EaHn28ClDJpMlBHgd3mCowtHlIN6DMQSCH9tXHs5rY-Xgpduk6WJhxZgY3s/s400/18.png" width="332" /></a></div>
<br />
Repite este paso para los siguientes procedimientos y tipos:<br />
<br />
<br />
<ul>
<li>Procedimiento_BuscarCanciones --> Entidades --> Canciones.</li>
<li>Procedimiento_BuscarConciertos --> Entidades --> Conciertos.</li>
<li>Procedimiento_BuscarDetallesConcierto --> Entidades --> DetallesConcierto.</li>
<li>Procedimiento_ObtenerArtistas --> Entidades --> Artistas</li>
<li>Procedimiento_ObtenerCanciones --> Entidades --> Canciones.</li>
<li>Procedimiento_ObtenerConciertos --> Entidades --> Conciertos.</li>
</ul>
<br />
Para el resto de los procedimientos (Agregar, Modificar y Eliminar) no hay que cambiar nada pero sí vamos a crear una clase que incluya un entero y una cadena y almacenaremos su valor ahí. Si recuerdas, estos procedimientos almacenados devuelven un 1 o 0 en caso de éxito/fracaso respectivamente, además de un mensaje (cadena de texto) indicando lo mismo.<br />
<br />
<b>No olvides guardar el modelo.</b><br />
<br />
Agrega al proyecto una nueva clase llamada <b>ResultadoSQL</b>, que define 2 propiedades: <b>Valor </b>y <b>Mensaje</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlV1gfB-lUWf4d4-kbLXwZAHDbv6VUt0poImU13dQQ9Bpg4tRdkkBM2a528mWCPlrFH9L-_xjEKM_OjJwIEfxNI8qx36SZXK0KqlB5gr6NiSe0BkLAlPOwbE9IHMr4C6fLInJaz14-6Rk/s1600/19.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlV1gfB-lUWf4d4-kbLXwZAHDbv6VUt0poImU13dQQ9Bpg4tRdkkBM2a528mWCPlrFH9L-_xjEKM_OjJwIEfxNI8qx36SZXK0KqlB5gr6NiSe0BkLAlPOwbE9IHMr4C6fLInJaz14-6Rk/s400/19.png" width="400" /></a></div>
<br /></div>
<br />
<pre class="brush:csharp;first-line:1">namespace ServicioMusicaWCF
{
public class ResultadoSQL
{
public int Valor { get; set; }
public string Mensaje { get; set; }
}
}</pre>
<br /></div>
<div>
<br />
Como necesitamos una salida en formato JSON, vamos a hacer uso de un paquete muy popular, poderoso y sencillo de utilizar en el mundo de C#: <b>Newtonsoft.Json</b>. Da clic derecho sobre el proyecto, selecciona <b>Administrar paquetes Nuget</b> y agrega dicho paquete (en este caso estoy usando la versión <b>10.0.2</b>).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkq-FWtv3iNW2bQzTlijv2s0AcoNt3U3WBc1y5Ym_c2uKdZQm-vv4mbRl_YtgCsTgGKhtImV47-SgohAQJtymQetEAxsRxweRpfQi7m9BvnQMcE7AW4EF4wQqPcwvo3feMyw-7pkd3OJY/s1600/21.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="186" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkq-FWtv3iNW2bQzTlijv2s0AcoNt3U3WBc1y5Ym_c2uKdZQm-vv4mbRl_YtgCsTgGKhtImV47-SgohAQJtymQetEAxsRxweRpfQi7m9BvnQMcE7AW4EF4wQqPcwvo3feMyw-7pkd3OJY/s320/21.png" width="320" /></a></div>
<br />
Debido a que vamos a serializar en formato <b>JSON</b>, necesitamos hacer una "ligera" modificación en nuestro Modelo (EntityFramework). En el <b>Explorador de Soluciones</b> expande <b>ModeloMusica.edmx</b>; a continuación, expande <b>ModeloMusica.tt</b> y abre los 4 archivos que se refieren a las entidades: <b>Artistas.cs</b>, <b>Canciones.cs</b>, <b>Conciertos.cs</b> y <b>DetallesConciertos.cs</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3TiVCCci21ND5RXNa7XwoRv1m6r1q_RxrAmYG710HlkjtfKmK2kN3VtYXkBUJZebKH8P0PoLQfbHeTXnjtjljNXSz3l4IjolezlDnQPqkOUpfjqk1pprKmXcAJDoIdmgF4Y5H1SoH8lI/s1600/22.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3TiVCCci21ND5RXNa7XwoRv1m6r1q_RxrAmYG710HlkjtfKmK2kN3VtYXkBUJZebKH8P0PoLQfbHeTXnjtjljNXSz3l4IjolezlDnQPqkOUpfjqk1pprKmXcAJDoIdmgF4Y5H1SoH8lI/s400/22.png" width="256" /></a></div>
<br />
Lo que tenemos que hacer es agregar el atributo <b>Serializable</b> a cada Entidad, para que pueda ser convertida a otro formato y enviarla por la red. Además, necesitamos agregar el atributo <b>JsonIgnore</b> a todos aquellos elementos que NO pertenecen a la tabla (los elementos marcados como virtuales e ICollection). Observa las imágenes de cómo debe quedar cada entidad:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPYd06MFz09YjBhr9RLs3Qzid0O4gVD5z2M1op6qU37I6T6xM5i-5PdsyKEq-DeEntW_Kt9hUm4FGRPEiQ3u43a7xhjaNDdS029d3n0vvuWDaD80n94h-2zTKNvF14avWe0KdDHdSx5jQ/s1600/23.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPYd06MFz09YjBhr9RLs3Qzid0O4gVD5z2M1op6qU37I6T6xM5i-5PdsyKEq-DeEntW_Kt9hUm4FGRPEiQ3u43a7xhjaNDdS029d3n0vvuWDaD80n94h-2zTKNvF14avWe0KdDHdSx5jQ/s400/23.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Serializable arriba de la clase Artistas y JsonIgnore arriba de la colección Conciertos.</div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRubJPk0IjYHy8rd8Y-xvoGpJoTmMdFGmXD2qDVEvpPxcgX76etMj56c4EsURs2mhTncZxzOo7zQjC5tTkr1F5l-weB4ftw2uwuZJuq4TBR5ma3rYYbO6821ut51d0wONoNjBirndXVsM/s1600/24.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="237" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRubJPk0IjYHy8rd8Y-xvoGpJoTmMdFGmXD2qDVEvpPxcgX76etMj56c4EsURs2mhTncZxzOo7zQjC5tTkr1F5l-weB4ftw2uwuZJuq4TBR5ma3rYYbO6821ut51d0wONoNjBirndXVsM/s400/24.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Serializable arriba de la clase Canciones y JsonIgnore arriba de la colección DetallesConcierto.</div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvREU0x48Se1UYzi0Z_DogA1vI1JZ2ktwDU2lWYwJiOJkJb-gHqwaKKY2VLKRkFpjia1B0r9_XRYmSI829UGS9l6IUDF6YRZdxac81j_NC5xBO0l54M7yQuT9IAOM6hA4Tkpa2pplOgDc/s1600/25.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="205" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvREU0x48Se1UYzi0Z_DogA1vI1JZ2ktwDU2lWYwJiOJkJb-gHqwaKKY2VLKRkFpjia1B0r9_XRYmSI829UGS9l6IUDF6YRZdxac81j_NC5xBO0l54M7yQuT9IAOM6hA4Tkpa2pplOgDc/s400/25.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Serializable arriba de la clase Conciertos y JsonIgnore arriba de las colecciones Artistas y DetallesConciertos.</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMbSHOI7CXlxuxd7CRZ3oN86dYOGJh1HpZjd-RMKlyR0m_quNShcy7L-AfT0vsaJBT32ru08nA_s2TMqFDHczwyoU46L06jRojkRzViJCsVGp4SMec9Ny4rPUQ2KjS8xXJMJgwaq0EYx8/s1600/26.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="341" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMbSHOI7CXlxuxd7CRZ3oN86dYOGJh1HpZjd-RMKlyR0m_quNShcy7L-AfT0vsaJBT32ru08nA_s2TMqFDHczwyoU46L06jRojkRzViJCsVGp4SMec9Ny4rPUQ2KjS8xXJMJgwaq0EYx8/s400/26.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Serializable arriba de la clase DetallesConcierto y JsonIgnore arriba de las colecciones Conciertos y Canciones.</div>
<br />
<b>NOTA: </b>En caso de modificar el modelo, las 4 entidades se generarán automáticamente y desafortuadamente tendrás que rehacer este paso de agregar los atributos nuevamente. Pero si en teoría no modificamos nuestro modelo de datos, no tendríamos por qué modificar las entidades nuevamente.<br />
<br />
¿Por qué agregamos la propiedad <b>JsonIgnore</b> a las colecciones virtuales? Porque el paquete <b>Newtonsoft.Json</b> detecta que hay referencias circulares entre las entidades (por ejemplo, un Artista tiene la propiedad Conciertos y a su vez un Concierto tiene un Artista, a esto en EntityFramework se le conoce como <b>Propiedades de Navegación</b>), por lo que la serialización no se puede realizar. De esta manera, marcando las propiedades que deben ignorarse, evitamos conflictos al momento de serializar. Es un paso adicional que debemos hacer si queremos aprovechar este paquete junto con EntityFramework.<br />
<br />
Ahora vamos a modificar el servicio que vamos a exponer para que las aplicaciones interactúen con la base de datos a través de la implementación de métodos. Para ello, abrimos <b>ServicioMusica.svc</b>, la cual implementará la interfaz <b>IServicioMusica</b> que definimos previamente, es decir, codificaremos cada uno de los 19 métodos. Explicaré 3 de ellos, pues el resto son similares. </div>
<div>
<br /></div>
<div>
Primero, veamos el código del método <b>AgregarArtista</b>:</div>
<div>
<br /></div>
<div>
<pre class="brush:csharp;first-line:1">public string AgregarArtista(string nombre, string pais)
{
int valor;
var mensaje = new ObjectParameter("mensaje", typeof(string));
using (var conexion = new MusicaEntidades())
{
valor = conexion.Procedimiento_AgregarArtista(nombre, pais, mensaje);
return JsonConvert.SerializeObject(new ResultadoSQL() { Valor = valor, Mensaje = mensaje.Value.ToString() });
}
}
</pre>
<br /></div>
<div>
<ul>
<li><b>Línea 1: </b>La definición del método AgregarArtista (idéntica a como se definió en la interfaz).</li>
<li><b>Línea 3: </b>La variable valor almacenará <b>el id del registro insertado</b> (lo devuelve el procedimiento almacenado, ¿recuerdas?)</li>
<li><b>Línea 4: </b>El procedimiento almacenado requiere un parámetro de salida (Output). Para ello, en EntityFramework se declara un <b>System.Data.Entity.Core.Objects.ObjectParameter</b> con el nombre del parámetro (mensaje) y el tipo de dato (string).</li>
<li><b>Línea 6: </b>El <b>contexto de datos</b> (la conexión, en otras palabras). Siempre es bueno colocar las conexiones y acceso a datos (por ejemplo, apertura de archivos) en una sentencia using, pues se asegura que las conexiones a recursos solicitados (conexiones, archivos, flujos, etc) serán cerradas una vez que ya no se necesiten (es decir, cuando el programa salga del método), ocasionando un mejor uso de la memoria y evitando que sean bloqueados (maximizando concurrencia).</li>
<li><b>Línea 8: </b>Se manda llamar el procedimiento almacenado respectivo, pasando los parámetros y almacenando el resultado en valor</li>
<li><b>Línea 9: </b>Se crea un objeto <b>ResultadoSQL</b> que se devuelve a la llamada del método del servicio. Se asignan los valores de las propiedades <b>Valor</b> y <b>Mensaje</b>. Finalmente, este objeto es serializado (convertido) a una cadena Json, la cual es devuelta como resultado de la llamada al procedimiento. La serialización es posible a través del método <b>SerializeObject</b>, disponible en la clase estática <b>JsonConvert</b> de <b>Newtonsoft.Json</b>.</li>
</ul>
<br />
Los métodos Modificar y Eliminar son parecidos, por lo que no los explicaré (pero su código se incluye un poco más adelante).<br />
<br />
Ahora veamos el método <b>ObtenerArtistas</b>:<br />
<br />
<pre class="brush:csharp;first-line:1">public string ObtenerArtistas()
{
using (var conexion = new MusicaEntidades())
{
return JsonConvert.SerializeObject(conexion.Procedimiento_ObtenerArtistas().ToList());
}
}
</pre>
<br />
Este método devuelve toda la tabla <b>Artistas</b> en una cadena JSON a través del procedimiento almacenado <b>Procedimiento_ObtenerArtistas.</b><br />
<br />
Finalmente, el método <b>BuscarArtista</b> se muestra continuación:<br />
<br />
<pre class="brush:csharp;first-line:1">public string BuscarArtista(int id)
{
using (var conexion = new MusicaEntidades())
{
return JsonConvert.SerializeObject(conexion.Procedimiento_BuscarArtista(id).FirstOrDefault());
}
}
</pre>
<br /></div>
<div>
Sencillo, ¿no? Simplemente hay que crear una conexión, llamar al procedimiento almacenado <b>Procedimiento_BuscarArtista</b> pasando el id respectivo y devolver el resultado con <b>FirstOrDefault</b>, el cual devolverá un objeto de la entidad <b>Artistas</b>, que será <b>serializado </b>a una cadena en formato<b> JSON.</b></div>
<div>
<b><br /></b></div>
<div>
El código completo del servicio es el siguiente:<br />
<br />
<br />
<pre class="brush:csharp;first-line:1">using System;
using System.Linq;
using System.Data.Entity.Core.Objects;
using Newtonsoft.Json;
namespace ServicioMusicaWCF
{
public class ServicioMusica : IServicioMusica
{
public string AgregarArtista(string nombre, string pais)
{
int valor;
var mensaje = new ObjectParameter("mensaje", typeof(string));
using (var conexion = new MusicaEntidades())
{
valor = conexion.Procedimiento_AgregarArtista(nombre, pais, mensaje);
return JsonConvert.SerializeObject(new ResultadoSQL() { Valor = valor, Mensaje = mensaje.Value.ToString() });
}
}
public string AgregarCancion(string titulo, string duracion)
{
int valor;
var mensaje = new ObjectParameter("mensaje", typeof(string));
using (var conexion = new MusicaEntidades())
{
valor = conexion.Procedimiento_AgregarCancion(titulo, duracion, mensaje);
return JsonConvert.SerializeObject(new ResultadoSQL() { Valor = valor, Mensaje = mensaje.Value.ToString() });
}
}
public string AgregarConcierto(int idArtista, string lugar, DateTime fecha)
{
int valor;
var mensaje = new ObjectParameter("mensaje", typeof(string));
using (var conexion = new MusicaEntidades())
{
valor = conexion.Procedimiento_AgregarConcierto(idArtista, lugar, fecha, mensaje);
return JsonConvert.SerializeObject(new ResultadoSQL() { Valor = valor, Mensaje = mensaje.Value.ToString() });
}
}
public string AgregarDetalleConcierto(int idConcierto, int idCancion, int orden)
{
int valor;
var mensaje = new ObjectParameter("mensaje", typeof(string));
using (var conexion = new MusicaEntidades())
{
valor = conexion.Procedimiento_AgregarDetalleConcierto(idConcierto, idCancion, orden, mensaje);
return JsonConvert.SerializeObject(new ResultadoSQL() { Valor = valor, Mensaje = mensaje.Value.ToString() });
}
}
public string BuscarArtista(int id)
{
using (var conexion = new MusicaEntidades())
{
return JsonConvert.SerializeObject(conexion.Procedimiento_BuscarArtista(id).FirstOrDefault());
}
}
public string BuscarCancion(int id)
{
using (var conexion = new MusicaEntidades())
{
return JsonConvert.SerializeObject(conexion.Procedimiento_BuscarCancion(id).FirstOrDefault());
}
}
public string BuscarConcierto(int id)
{
using (var conexion = new MusicaEntidades())
{
return JsonConvert.SerializeObject(conexion.Procedimiento_BuscarConcierto(id).FirstOrDefault());
}
}
public string EliminarArtista(int id)
{
int valor;
var mensaje = new ObjectParameter("mensaje", typeof(string));
using (var conexion = new MusicaEntidades())
{
valor = conexion.Procedimiento_EliminarArtista(id, mensaje);
return JsonConvert.SerializeObject(new ResultadoSQL() { Valor = valor, Mensaje = mensaje.Value.ToString() });
}
}
public string EliminarCancion(int id)
{
int valor;
var mensaje = new ObjectParameter("mensaje", typeof(string));
using (var conexion = new MusicaEntidades())
{
valor = conexion.Procedimiento_EliminarCancion(id, mensaje);
return JsonConvert.SerializeObject(new ResultadoSQL() { Valor = valor, Mensaje = mensaje.Value.ToString() });
}
}
public string EliminarConcierto(int id)
{
int valor;
var mensaje = new ObjectParameter("mensaje", typeof(string));
using (var conexion = new MusicaEntidades())
{
valor = conexion.Procedimiento_EliminarConcierto(id, mensaje);
return JsonConvert.SerializeObject(new ResultadoSQL() { Valor = valor, Mensaje = mensaje.Value.ToString() });
}
}
public string EliminarDetalleConcierto(int idConcierto, int idCancion)
{
int valor;
var mensaje = new ObjectParameter("mensaje", typeof(string));
using (var conexion = new MusicaEntidades())
{
valor = conexion.Procedimiento_EliminarDetalleConcierto(idConcierto, idCancion, mensaje);
return JsonConvert.SerializeObject(new ResultadoSQL() { Valor = valor, Mensaje = mensaje.Value.ToString() });
}
}
public string ModificarArtista(int id, string nombre, string pais)
{
int valor;
var mensaje = new ObjectParameter("mensaje", typeof(string));
using (var conexion = new MusicaEntidades())
{
valor = conexion.Procedimiento_ModificarArtista(id, nombre, pais, mensaje);
return JsonConvert.SerializeObject(new ResultadoSQL() { Valor = valor, Mensaje = mensaje.Value.ToString() });
}
}
public string ModificarCancion(int id, string titulo, string duracion)
{
int valor;
var mensaje = new ObjectParameter("mensaje", typeof(string));
using (var conexion = new MusicaEntidades())
{
valor = conexion.Procedimiento_ModificarCancion(id, titulo, duracion, mensaje);
return JsonConvert.SerializeObject(new ResultadoSQL() { Valor = valor, Mensaje = mensaje.Value.ToString() });
}
}
public string ModificarConcierto(int id, int idArtista, string lugar, DateTime fecha)
{
int valor;
var mensaje = new ObjectParameter("mensaje", typeof(string));
using (var conexion = new MusicaEntidades())
{
valor = conexion.Procedimiento_ModificarConcierto(id, idArtista, lugar, fecha, mensaje);
return JsonConvert.SerializeObject(new ResultadoSQL() { Valor = valor, Mensaje = mensaje.Value.ToString() });
}
}
public string ModificarDetalleConcierto(int idConcierto, int idCancion, int orden)
{
int valor;
var mensaje = new ObjectParameter("mensaje", typeof(string));
using (var conexion = new MusicaEntidades())
{
valor = conexion.Procedimiento_ModificarDetalleConcierto(idConcierto, idCancion, orden, mensaje);
return JsonConvert.SerializeObject(new ResultadoSQL() { Valor = valor, Mensaje = mensaje.Value.ToString() });
}
}
public string ObtenerArtistas()
{
using (var conexion = new MusicaEntidades())
{
return JsonConvert.SerializeObject(conexion.Procedimiento_ObtenerArtistas().ToList());
}
}
public string ObtenerCanciones()
{
using (var conexion = new MusicaEntidades())
{
return JsonConvert.SerializeObject(conexion.Procedimiento_ObtenerCanciones().ToList());
}
}
public string ObtenerConciertos()
{
using (var conexion = new MusicaEntidades())
{
return JsonConvert.SerializeObject(conexion.Procedimiento_ObtenerConciertos().ToList());
}
}
public string ObtenerDetallesConcierto(int idConcierto)
{
using (var conexion = new MusicaEntidades())
{
return JsonConvert.SerializeObject(conexion.Procedimiento_ObtenerDetallesConcierto(idConcierto).ToList());
}
}
}
}</pre>
</div>
<div>
<br />
<br />
Por si te lo estás preguntando, sí, ya terminamos. Ya solo falta probar el servicio. Presiona F5 para compilar y ejecutar el proyecto. Esto inicializará la herramienta <b>svcutil</b> <b>(Cliente de prueba WCF)</b>, la cual nos permite conectarnos a un servicio par utilizar sus métodos. Esto es lo que aparecerá una vez implementado el proyecto en IIS (que es el servidor donde se montará este servicio).<br />
<br />
<b>Importante: Si recibes un error de que no se pudo implementar o ejecutar el proyecto, cierra Visual Studio y vuélvelo a abrir, pero ejecútalo como Administrador</b><br />
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJbhaqkzOxXCpzItdWK1HEFFQKEGUWvplT91u0TOODSRQk87MC02pUnm2QtrcGo6m4KisWPShQKT2k2RDmhjs6NqWOCRx9ylk3QUozW3lFNWHZeSBssfxynFC3PwQTBZzMnURrJzeVPFg/s1600/30.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="253" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJbhaqkzOxXCpzItdWK1HEFFQKEGUWvplT91u0TOODSRQk87MC02pUnm2QtrcGo6m4KisWPShQKT2k2RDmhjs6NqWOCRx9ylk3QUozW3lFNWHZeSBssfxynFC3PwQTBZzMnURrJzeVPFg/s400/30.png" width="400" /></a></div>
<br />
Como puedes ver, los 19 métodos expuestos en el servicio aparecen en esta pantalla. También aparecen métodos asíncronos, los cuales no podemos probar con esta herramienta, pero serán de utilidad al crear una aplicación cliente que consuma el servicio.<br />
<br />
Vamos a probar un servicio. Da doble clic en el método <b>ObtenerArtistas</b> y da clic en <b>Invocar</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsypXsP4P9LRifIW39rI41EtZA37aRuErGVm-QzETVu50mMHVe-2zbzdBYv6EjbRJKG26QwpI36QwZ5KoAe4qbZ2k59NZhZb7HOnHYWxVv5VGbgYJ6sTOE_jURNLD3j-AvJOj-iQPNtRM/s1600/31.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="252" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsypXsP4P9LRifIW39rI41EtZA37aRuErGVm-QzETVu50mMHVe-2zbzdBYv6EjbRJKG26QwpI36QwZ5KoAe4qbZ2k59NZhZb7HOnHYWxVv5VGbgYJ6sTOE_jURNLD3j-AvJOj-iQPNtRM/s400/31.png" width="400" /></a></div>
<br />
Si te aparece una <b>Advertencia de seguridad</b>, marca la opción <b>No volver a mostrar este mensaje</b> y da clic en <b>Aceptar</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpJOBKFG7AjM1k0bkKSo356Sv2eRwn1iOywOTqnPr9OC8hOos2O5sGgCnpeM-USWEYXKK0gtIhePhgEeifidFYPSwfSAf5Jig8fJ5D5mGXb3TX5EWkORprAbxql-gEXdYUMX3rUCR6Ku8/s1600/32.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="171" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpJOBKFG7AjM1k0bkKSo356Sv2eRwn1iOywOTqnPr9OC8hOos2O5sGgCnpeM-USWEYXKK0gtIhePhgEeifidFYPSwfSAf5Jig8fJ5D5mGXb3TX5EWkORprAbxql-gEXdYUMX3rUCR6Ku8/s400/32.png" width="400" /></a></div>
<br />
Y entonces se invocará el servicio y se devolverá su resultado en el panel inferior. Como puedes ver, se devuelve la información de los artistas en formato JSON.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdd3c2TAWE2ziV2sSDNn-peHbotWHzz8SshAp7igsKSCA60CbMBch2qQpU8e3YpWq6AaJEHGkZYJPBORQbe85mOoYZwuyQlxes_woRhmxdyKsENvVi_6VLBVJH3ZcfG7fmP2BkRkohVp4/s1600/33.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="253" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdd3c2TAWE2ziV2sSDNn-peHbotWHzz8SshAp7igsKSCA60CbMBch2qQpU8e3YpWq6AaJEHGkZYJPBORQbe85mOoYZwuyQlxes_woRhmxdyKsENvVi_6VLBVJH3ZcfG7fmP2BkRkohVp4/s400/33.png" width="400" /></a></div>
<br />
Si quieres copiar el resultado, simplemente da clic en la pestaña <b>XML</b> que aparece debajo y selecciona el valor devuelto.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgASINFhxLUIGaHfureYENKlb8fYhedtUqqdKwbjDnelh4XhgeF7BSKO2B7EQE1lMwLvXo8f5GjNP_ePuaJDZ0zBOzCOSOHePi2IF5yjuSh3aS1G6XLPVD4UKyOW9Y2zrRh-9TJW8d6dpo/s1600/34.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgASINFhxLUIGaHfureYENKlb8fYhedtUqqdKwbjDnelh4XhgeF7BSKO2B7EQE1lMwLvXo8f5GjNP_ePuaJDZ0zBOzCOSOHePi2IF5yjuSh3aS1G6XLPVD4UKyOW9Y2zrRh-9TJW8d6dpo/s320/34.png" width="320" /></a></div>
<br />
Aquí tienes el resultado, un arreglo en formato JSON:<br />
<br />
[<br />
{<br />
"Id":1,<br />
"Nombre":"Katie Melua",<br />
"Pais":"Gran Bretaña"<br />
},<br />
{<br />
"Id":4,<br />
"Nombre":"Michael Buble",<br />
"Pais":"Canada"<br />
},<br />
{<br />
"Id":3,<br />
"Nombre":"The Corrs",<br />
"Pais":"Irlanda"<br />
}<br />
]<br />
<br />
<br />
Ahora revisemos el método <b>BuscarCancion</b>. Damos doble clic, escribimos un valor para el parámetro <b>Id</b> e <b>invocamos</b> el servicio, revisando que el resultado sea correcto y en formato <b>JSON</b>:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjptd0KksZmA_lE6tdw0SaXQhNC-g0QdpMeHpTnm_lHnoDHrNe0WFIPmH-rItyLZ7reExjYXLg5oYvaoSsaIqYYdPmDs794vLU0gv_NSE6UtWidUp3gWMh-pnfc_PhTLlQstxJdbIbo_lM/s1600/35.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="251" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjptd0KksZmA_lE6tdw0SaXQhNC-g0QdpMeHpTnm_lHnoDHrNe0WFIPmH-rItyLZ7reExjYXLg5oYvaoSsaIqYYdPmDs794vLU0gv_NSE6UtWidUp3gWMh-pnfc_PhTLlQstxJdbIbo_lM/s400/35.png" width="400" /></a></div>
<br />
También podemos comprobar el funcionamiento de los métodos que modifican la información de la base de datos. Por ejemplo, el método <b>AgregarArtista</b>. Escribimos valores e invocamos el servicio, verificando que se devuelve un valor y mensaje.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXEyss-SXIm8jQtSdhNF6-5DtS9HGRusW8sqMmPV48qWd-BFA8y-hMqS8If1kfLoo0ui7pwtiljrubVsP0m7HbeIXQB-BKaPXqs_P6LnJ8iLQD_tO1dj1UUQ-AqMh8-7XWETTR-DSY6z8/s1600/36.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="252" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXEyss-SXIm8jQtSdhNF6-5DtS9HGRusW8sqMmPV48qWd-BFA8y-hMqS8If1kfLoo0ui7pwtiljrubVsP0m7HbeIXQB-BKaPXqs_P6LnJ8iLQD_tO1dj1UUQ-AqMh8-7XWETTR-DSY6z8/s400/36.png" width="400" /></a></div>
<br />
<b>Nota Importante: </b>Por algún motivo siempre devuelve -1 en lugar del ID del último registro insertado. Voy a verificar qué es lo que está sucediendo y en la siguiente entrega haré la modificación respectiva (de momento, dejémoslo así, ¿sale? :) )<br />
<br />
¡Listo! Hemos terminado. Sé que ha sido una entrega algo larga (por eso me tarde un poco más de un día jeje) pero espero que hayas podido seguirla sin problemas. Recuerda que el esfuerzo realizado el día de hoy tendrá su recompensa el día de mañana, así que aunque esta sesión haya sido algo larga, espero te haya sido de utilidad y el aprendizaje adquirido haya sido bastante.<br />
<br />
Te recuerdo que el código completo del script lo puedes obtener desde <b><a href="https://github.com/icebeam7/xamarin-wcf-sp-ef" target="_blank">el repositorio de GitHub</a></b> creado para este proyecto.<br />
<div>
<br /></div>
Con esto concluimos con la segunda parte del demo, donde creamos <b>un servicio WCF</b> que hace uso de los <b>procedimientos almacenados </b>creados en la primer entrega. En la próxima sesión crearemos <b>un cliente en Xamarin.Forms</b> que consumirá el servicio generado.<br />
<br />
Pero antes, realizaré en video la demostración de estas 2 primeras partes de la serie. Espéralo muy pronto, la actualización la publicaré aquí en el blog, pero también puedes suscribirte a <a href="https://www.youtube.com/channel/UCaswGLsFFj_ayngaVOTf7Hw" target="_blank">mi canal de YouTube</a>, donde los voy a subir.<br />
<br />
Te recuerdo que la experiencia de aprendizaje continúa con el #XamarinDiplomado. Únete a nuestro <a href="https://www.facebook.com/groups/xamarindiplomadoitc/" target="_blank">grupo de estudio en Facebook</a>, donde además de hablar del diplomado de Xamarin 3.0 impartido por Microsoft, también comentamos sobre otras oportunidades de aprendizaje, trabajo, resolvemos dudas y compartimos el conocimiento.<br />
<br />
Si tienes alguna sugerencia, recomendación, comentario o algún paso no te funcionó, házmelo saber y con gusto te atenderé :) déjame un comentario y aquí lo revisamos.<br />
<br />
Espero esta entrada te haya sido de utilidad, y si fue así, no dudes en compartirla :)<br />
<br />
¡Saludos y hasta pronto!<br />
<div>
<br /></div>
</div>
<div>
-Luis</div>
Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com16tag:blogger.com,1999:blog-8407795827837136717.post-27144633882012390912017-04-16T19:41:00.002-07:002017-04-19T06:01:57.005-07:00Xamarin, WCF, Stored Procedures y Entity Framework (Parte 1)¡Hola! En días anteriores en el grupo de Facebook de <b><a href="https://www.facebook.com/groups/xamarindiplomadoitc/" target="_blank">Xamarin Diplomado ITC</a></b> me hicieron una consulta sobre el uso de Xamarin con SQL, lo cual ya había publicado con anterioridad <b><a href="http://icebeamwp.blogspot.cz/2016/09/conectando-una-app-de-xamarin-con-sql.html" target="_blank">aquí</a></b>. Como bien sabemos, lo ideal es <b>NO </b>hacer la conexión directa entre la app móvil y la base de datos, pues la cadena de conexión queda expuesta al ser incluida en la applicación, lo cual implica un alto riesgo a la seguridad de nuestra información.<br />
<br />
Dado que la conversación siguió hasta tratar el tema de procedimientos almacenados (para las operaciones CRUD) y servicios WCF (para el acceso a la información) y en vista de que una actualización de la publicación de SQL era necesaria, pues he decidido hacer una serie titulada <b><a href="http://icebeamwp.blogspot.cz/search/label/Xamarin-WCF-SP-EF" target="_blank">Xamarin, WCF, Stored Procedures y Entity Framework</a></b>, la cual constará de 3 a 5 partes en la que construiremos una aplicación móvil que obtiene información de un servidor (primero local con IIS, luego lo montaremos a Azure) utilizando un servicio web.<br />
<br />
El repositorio de GitHub donde actualizaré el proyecto poco a poco se encuentra <b><a href="https://github.com/icebeam7/xamarin-wcf-sp-ef" target="_blank">aquí</a></b>.<br />
<br />
Consideraciones si descargas y quieres ejecutar la solución inmediatamente:<br />
<br />
<ul>
<li>Ninguna, solo ejecuta el script de la base de datos :)</li>
</ul>
<br />
<br />
En cada parte trataremos un punto específico de la aplicación. ¿Listos? ¡Pues comenzamos!<br />
<br />
En esta primer parte trabajaremos con algo sencillo: <b>la base de datos</b>. Solo necesitas tener <b>SQL Server</b> instalado, así como <b>SQL Server Management Studio</b>, desde donde escribiremos y ejecutaremos el script. Cualquier versión te sirve (2008, 2012, 2016... yo lo hice con <b>2012</b>).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjqJLf6WfyTEuIx7jqNiaj76wq-wkAMjGwQR7itmyODtYPGAZwaw6_KnAjTF5DAZY3vaxnCwJZ9VlMOFVWoHOkH6lO8Rc2yEAtg2uSrn5VezZLGOu7F0tCKCDFUd62eAopzWVzIyPRUZU/s1600/03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="356" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjqJLf6WfyTEuIx7jqNiaj76wq-wkAMjGwQR7itmyODtYPGAZwaw6_KnAjTF5DAZY3vaxnCwJZ9VlMOFVWoHOkH6lO8Rc2yEAtg2uSrn5VezZLGOu7F0tCKCDFUd62eAopzWVzIyPRUZU/s400/03.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
El script completo lo puedes bajar desde <a href="https://github.com/icebeam7/xamarin-wcf-sp-ef" style="font-weight: bold;" target="_blank">GitHub</a>. Se encuentra ubicado en la carpeta BaseDatos. Simplemente descárgalo y ejecútalo por completo en SQL Server Management Studio.</div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<a name='more'></a><br />
<br />
<div class="separator" style="clear: both; text-align: left;">
Para este ejemplo definiremos una base de datos llamada <b>Musica</b>, la cual contiene 4 tablas muy sencillas: </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<ul>
<li><b>Artistas</b> (Se define el nombre y nacionalidad)</li>
<li><b>Canciones</b> (Consta de título y duración)</li>
<li><b>Conciertos</b> (Contiene el artista, lugar y fecha del evento)</li>
<li><b>DetallesConcierto</b> (Incluye la canción, el concierto y el orden de la canción en el evento)</li>
</ul>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
Además, definiremos para este proyecto las siguientes especificaciones (las cuales puedes determinar a partir del diagrama anterior):<br />
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<ul>
<li><b>Un artista</b> participa en <b>N conciertos</b> y <b>un concierto </b>incluye solo a <b>un artista</b> <b>(Por tanto la relación es 1 a N)</b>.</li>
<li><b>Un concierto </b>incluye <b>N canciones</b> y <b>una canción </b>puede ser interpretada en <b>M conciertos</b> (por tanto, existe una <b>relación N a M</b>, la cual crea la <b>tabla asociativa DetallesConcierto</b>).</li>
<li>No me gustan los nulos (xD), así que cada campo de las tablas <b>NO admite nulos </b>(obviamente en una implementación real dependerá de las reglas de negocio, tal vez un valor sí debe admitir nulos por alguna razón)</li>
</ul>
<br />
<i>(Se dan clases de Bases de Datos por si algo no se comprendió, pregunte aquí jajaja)</i><br />
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Bien. Si se comprendieron las reglas anteriores, el script que permite definir la base de datos, las tablas y las relaciones anteriores se muestra a continuación:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<pre class="brush:sql;first-line:1">/* Creación y uso de la base de datos Musica */
CREATE DATABASE Musica
GO
USE Musica
GO
/* Parte 1. Tablas */
CREATE TABLE Artistas(
Id INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
Nombre VARCHAR(100) NOT NULL,
Pais VARCHAR(100) NOT NULL
)
CREATE TABLE Canciones(
Id INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
Titulo VARCHAR(200) NOT NULL,
Duracion VARCHAR(10) NOT NULL
)
CREATE TABLE Conciertos(
Id INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
IdArtista INT NOT NULL,
Lugar VARCHAR(100) NOT NULL,
Fecha SMALLDATETIME NOT NULL,
CONSTRAINT FK_Artista FOREIGN KEY (IdArtista) REFERENCES Artistas(Id) ON DELETE CASCADE
)
CREATE TABLE DetallesConcierto(
IdConcierto INT NOT NULL,
IdCancion INT NOT NULL,
Orden INT NOT NULL,
CONSTRAINT FK_Concierto FOREIGN KEY (IdConcierto) REFERENCES Conciertos(Id) ON DELETE CASCADE,
CONSTRAINT FK_Cancion FOREIGN KEY (IdCancion) REFERENCES Canciones(Id) ON DELETE CASCADE,
CONSTRAINT PK_DetalleConcierto PRIMARY KEY (IdConcierto, IdCancion)
)
GO
</pre>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Notas del script anterior:</div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<ul>
<li><b>Cada tabla</b> (excepto DetallesConcierto) contiene un <b>identificador autoincremental entero</b> (lo definimos a partir del <b>IDENTITY</b> que servirá de <b>llave primaria</b>. Si bien es un esquema aceptado, en muchas ocasiones se sugiere el uso de Unique identifiers (GUID) secuenciales (SQL Azure lo maneja así). Para mantener la simplicidad en esta serie, lo dejaremos así con IDENTITY y en una futura publicación hablaré de estos identificadores GUID.</li>
</ul>
<div>
<br /></div>
<ul>
<li>Las llaves foráneas han sido definidas como una <b>CONSTRAINT</b> que incluye el borrado en cascada (<b>ON DELETE CASCADE</b>). Esto quiere decir que si por ejemplo se elimina un Artista de la tabla, automáticamente se eliminarán los conciertos en los que haya sido registrado.</li>
</ul>
<br />
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Ahora que las tablas han sido definidas, vamos a lo bueno de esta publicación. Para realizar las operaciones CRUD (Create, Read, Update y Delete) sobre las tablas, definiremos <b>Procedimientos Almacenados (Stored Procedures)</b>, los cuales permiten definir operaciones parametrizadas a realizar sobre las tablas en el gestor de base de datos. Esto permite que en las llamadas a las operaciones, solo se envíen los valores (parámetros) en lugar de una instrucción SQL (es inseguro enviar la consulta como cadena porque puede ser interceptada, mejor enviamos la llamada a un procedimiento almacenado).</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Sin embargo, vamos a complicarlo un poquito jeje, pues fue uno de los requerimientos que me preguntaron :)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
¿Podemos definir un procedimiento almacenado que devuelva 2 cosas al mismo tiempo? </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<ul>
<li>Primero, un valor 1 o 0 en caso de éxito o fracaso en la operación, respectivamente.</li>
<li>Y segundo, un mensaje que indique lo mismo, que la operación se realizó correctamente o con error.</li>
</ul>
<div>
<br />
La respuesta es que si se puede. Para el primer caso utilizaremos la instrucción <b>RETURN</b>, mientras que para el segundo definiremos un parámetro <b>OUTPUT</b> (de salida) en la definición del procedimiento almacenado. Va la explicación:</div>
<div>
<br /></div>
<div>
<ul>
<li>Cuando llamamos un procedimiento almacenado, normalmente se devuelve el resultado de una consulta o un valor utilizando la instrucción <b>RETURN</b>. Esto es como en programación, cuando un metodo retorna un valor entero, cadena, objeto, etc.</li>
</ul>
<div>
<br /></div>
<ul>
<li>Todo mundo conoce los parámetros de entrada al llamara una función o procedimiento almacenado. Son los valores que se están enviando al método para realizar algo. Sin embargo, existen también los <b>parámetros de salida</b> (OUTPUT) que funcionan en dos sentidos: cumplen la función de parámetro de entrada (es decir, envían algo al método) pero al finalizar su ejecución, su valor también podrá ser recuperado en la llamada al método.</li>
</ul>
<div>
<br /></div>
</div>
<div>
Expliquémoslo mejor con el siguiente script que agrega un nuevo artista a la tabla: </div>
<div>
<br /></div>
<div>
<pre class="brush:sql;first-line:1">CREATE PROCEDURE Procedimiento_AgregarArtista (@Nombre VARCHAR(100), @Pais VARCHAR(100), @mensaje VARCHAR(MAX) OUTPUT)
AS
SET NOCOUNT ON
BEGIN TRANSACTION
INSERT INTO Artistas VALUES (@Nombre, @Pais)
IF @@error = 0
BEGIN
SELECT @mensaje = 'Correcto'
END
ELSE
BEGIN
SELECT @mensaje = 'Error al insertar'
ROLLBACK TRANSACTION
RETURN 0
END
COMMIT TRANSACTION
RETURN SCOPE_IDENTITY()
GO
</pre>
<br /></div>
<br />
<ul>
<li><b>Línea 1: </b>Se define el procedimiento almacenado con 2 parámetros de entrada (Nombre y Pais) y 1 de salida (mensaje)</li>
<li><b>Línea 3: </b>Se indica al gestor que no muestre la salida de contador de resultados <i>(ése que luego dice 5 registros afectados)</i>.</li>
<li><b>Línea 4: </b>Comienza la transacción. Si la operación es exitosa se confirma la transacción haciendo Commit (<b>línea 16</b>) y en caso de error, se deshacen los cambios mediante un Rollback (<b>línea 13</b>)</li>
<li><b>Línea 5: </b>Se indica la operación a realizar: Es un Insert sobre la tabla Artistas indicando el nombre y nacionalidad a registrar.</li>
<li><b>Línea 6: </b>La variable @@error indica si la operación anterior fue un éxito (contiene cero) o fracaso (contiene un valor distinto de cero), por lo que es necesario comprobar su valor mediante la sentencia IF.</li>
<li><b>Líneas 8 y 12: </b>Se establece el valor de la variable de salida @mensaje, pasando una cadena de texto de acuerdo al resultado de la operación.</li>
<li><b>Líneas 13 y 14: </b>Si el insert falló, se hace rollback en la transacción y se retorna 0 (fracaso).</li>
<li><b>Líneas 16 y 17: </b>Si el insert fue exitoso, se hace commit de la operación y se retorna el ID del registro insertado mediante la instrucción Scope_Identity, lo cual es útil cuando se quiere agregar más información del registro recién insertado.</li>
</ul>
<div>
<br /></div>
<div>
Vamos a demostrar su funcionamiento. Para ello, pues ejecutamos el siguiente script:</div>
<div>
<br /></div>
<div>
<pre class="brush:sql;first-line:1">DECLARE @Id INT
DECLARE @Nombre VARCHAR(100)
DECLARE @Pais VARCHAR(100)
DECLARE @mensaje VARCHAR(MAX)
SET @Nombre = 'Katie Melua'
SET @Pais = 'Georgia'
EXEC @Id = Procedimiento_AgregarArtista @Nombre, @Pais, @mensaje OUTPUT
SELECT @Id AS ID, @mensaje AS Mensaje
GO
</pre>
<br /></div>
<div>
<br />
<ul>
<li><b>Línea 1: </b>Se define la variable Id para recuperar el valor del registro insertado</li>
<li><b>Líneas 2 y 3: </b>Se definen las variables Nombre y Pais, que se pasarán al procedimiento almacenado</li>
<li><b>Línea 4: </b>Se define la variable mensaje, que se pasará al procedimiento almacenado y al finalizar su llamada tendrá un valor indicando si la operación funcionó o no.</li>
<li><b>Líneas 6 y 7:</b> Se establecen los valores de Nombre y Pais</li>
<li><b>Línea 8:</b> Previo a hacer la llamada (EXEC) del procedimiento almacenado, se asigna a la variable Id el valor de retorno. Además, se envían los parámetros Nombre, Pais y mensaje, pero a éste último se le agrega el modificador OUTPUT para indicar que es de salida y contendrá un valor al final.</li>
<li><b>Línea 10: </b>Se muestra en pantalla los valores de las variables Id y mensaje. </li>
</ul>
</div>
<div>
El resultado de la ejecución lo puedes ver a continuación, indicando éxito en la operación:</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi54oEljEavfGkFBCYgfUlSyWv8nytuzRa2M7J7f7ylMB5pmF1NnOg1o8V7n0Km2O80PARLhvp9v2DnzYsKtLxUVH3U1Pc0SI8A74EsVw6IpJXQzOguj-tjp74mzf903AfwmkblJnJOw8I/s1600/05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="261" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi54oEljEavfGkFBCYgfUlSyWv8nytuzRa2M7J7f7ylMB5pmF1NnOg1o8V7n0Km2O80PARLhvp9v2DnzYsKtLxUVH3U1Pc0SI8A74EsVw6IpJXQzOguj-tjp74mzf903AfwmkblJnJOw8I/s400/05.png" width="400" /></a></div>
<br />
A continuación te presento el script completo de los procedimientos almacenados, los cuales incluyen su demostración al finalizar, considerando que se definen los siguientes procedimientos almacenados:<br />
<br />
<br />
<ul>
<li><b>Procedimiento_Obtener[Tabla]</b>. Es un simple Select * From que devuelve toda la información de la tabla respectiva ordenada por un campo específico.</li>
<li><b>Procedimiento_Buscar[Tabla]</b>. Devuelve un registro específico, determinado por el parámetro Id</li>
<li><b>Procedimiento_Agregar[Tabla]</b>. Define la operación Insert sobre la tabla específica.</li>
<li><b>Procedimiento_Modificar[Tabla]</b>. Define la operación Update sobre la tabla específica.</li>
<li><b>Procedimiento_Eliminar[Tabla]</b>. Define la operación Delete sobre la tabla específica.</li>
</ul>
<br />
En total, crearemos 19 procedimientos almacenados.<br />
<br />
El código completo de los procedimientos almacenados se muestra a continuación:<br />
<br />
<pre class="brush:sql;first-line:1">CREATE PROCEDURE Procedimiento_ObtenerArtistas
AS
SELECT * FROM Artistas ORDER BY Nombre
GO
CREATE PROCEDURE Procedimiento_BuscarArtista (@Id INT)
AS
SELECT * FROM Artistas WHERE Id = @Id
GO
CREATE PROCEDURE Procedimiento_AgregarArtista (@Nombre VARCHAR(100), @Pais VARCHAR(100), @mensaje VARCHAR(MAX) OUTPUT)
AS
SET NOCOUNT ON
BEGIN TRANSACTION
INSERT INTO Artistas VALUES (@Nombre, @Pais)
IF @@error = 0
BEGIN
SELECT @mensaje = 'Correcto'
END
ELSE
BEGIN
SELECT @mensaje = 'Error al insertar'
ROLLBACK TRANSACTION
RETURN 0
END
COMMIT TRANSACTION
RETURN SCOPE_IDENTITY()
GO
CREATE PROCEDURE Procedimiento_ModificarArtista (@Id INT, @Nombre VARCHAR(100), @Pais VARCHAR(100), @mensaje VARCHAR(MAX) OUTPUT)
AS
SET NOCOUNT ON
BEGIN TRANSACTION
UPDATE Artistas SET Nombre = @Nombre, Pais = @Pais WHERE Id = @Id
IF @@ERROR = 0 AND @@ROWCOUNT <> 0
BEGIN
SELECT @mensaje = 'Correcto'
END
ELSE
BEGIN
SELECT @mensaje = 'Error al modificar'
ROLLBACK TRANSACTION
RETURN 0
END
COMMIT TRANSACTION
RETURN 1
GO
CREATE PROCEDURE Procedimiento_EliminarArtista (@Id INT, @mensaje VARCHAR(MAX) OUTPUT)
AS
SET NOCOUNT ON
BEGIN TRANSACTION
DELETE FROM Artistas WHERE Id = @Id
IF @@ERROR = 0
BEGIN
SELECT @mensaje = 'Registro eliminado correctamente'
END
ELSE
BEGIN
SELECT @mensaje = 'Error al eliminar'
ROLLBACK TRANSACTION
RETURN 0
END
COMMIT TRANSACTION
RETURN 1
GO
/* b. Tabla Canciones */
CREATE PROCEDURE Procedimiento_ObtenerCanciones
AS
SELECT * FROM Canciones ORDER BY Titulo
GO
CREATE PROCEDURE Procedimiento_BuscarCancion (@Id INT)
AS
SELECT * FROM Canciones WHERE Id = @Id
GO
CREATE PROCEDURE Procedimiento_AgregarCancion (@Titulo VARCHAR(200), @Duracion VARCHAR(10), @mensaje VARCHAR(MAX) OUTPUT)
AS
SET NOCOUNT ON
BEGIN TRANSACTION
INSERT INTO Canciones VALUES (@Titulo, @Duracion)
IF @@error = 0
BEGIN
SELECT @mensaje = 'Correcto'
END
ELSE
BEGIN
SELECT @mensaje = 'Error al insertar'
ROLLBACK TRANSACTION
RETURN 0
END
COMMIT TRANSACTION
RETURN SCOPE_IDENTITY()
GO
CREATE PROCEDURE Procedimiento_ModificarCancion (@Id INT, @Titulo VARCHAR(200), @Duracion VARCHAR(10), @mensaje VARCHAR(MAX) OUTPUT)
AS
SET NOCOUNT ON
BEGIN TRANSACTION
UPDATE Canciones SET Titulo = @Titulo, Duracion = @Duracion WHERE Id = @Id
IF @@ERROR = 0 AND @@ROWCOUNT <> 0
BEGIN
SELECT @mensaje = 'Correcto'
END
ELSE
BEGIN
SELECT @mensaje = 'Error al modificar'
ROLLBACK TRANSACTION
RETURN 0
END
COMMIT TRANSACTION
RETURN 1
GO
CREATE PROCEDURE Procedimiento_EliminarCancion (@Id INT, @mensaje VARCHAR(MAX) OUTPUT)
AS
SET NOCOUNT ON
BEGIN TRANSACTION
DELETE FROM Canciones WHERE Id = @Id
IF @@ERROR = 0
BEGIN
SELECT @mensaje = 'Registro eliminado correctamente'
END
ELSE
BEGIN
SELECT @mensaje = 'Error al eliminar'
ROLLBACK TRANSACTION
RETURN 0
END
COMMIT TRANSACTION
RETURN 1
GO
/* c. Tabla Conciertos */
CREATE PROCEDURE Procedimiento_ObtenerConciertos
AS
SELECT * FROM Conciertos ORDER BY Fecha
GO
CREATE PROCEDURE Procedimiento_BuscarConcierto (@Id INT)
AS
SELECT * FROM Conciertos WHERE Id = @Id
GO
CREATE PROCEDURE Procedimiento_AgregarConcierto (@IdArtista INT, @Lugar VARCHAR(100), @Fecha SMALLDATETIME, @mensaje VARCHAR(MAX) OUTPUT)
AS
SET NOCOUNT ON
BEGIN TRANSACTION
INSERT INTO Conciertos VALUES (@IdArtista, @Lugar, @Fecha)
IF @@error = 0
BEGIN
SELECT @mensaje = 'Correcto'
END
ELSE
BEGIN
SELECT @mensaje = 'Error al insertar'
ROLLBACK TRANSACTION
RETURN 0
END
COMMIT TRANSACTION
RETURN SCOPE_IDENTITY()
GO
CREATE PROCEDURE Procedimiento_ModificarConcierto (@Id INT, @IdArtista INT, @Lugar VARCHAR(100), @Fecha SMALLDATETIME, @mensaje VARCHAR(MAX) OUTPUT)
AS
SET NOCOUNT ON
BEGIN TRANSACTION
UPDATE Conciertos SET IdArtista = @IdArtista, Lugar = @Lugar, Fecha = @Fecha WHERE Id = @Id
IF @@ERROR = 0 AND @@ROWCOUNT <> 0
BEGIN
SELECT @mensaje = 'Correcto'
END
ELSE
BEGIN
SELECT @mensaje = 'Error al modificar'
ROLLBACK TRANSACTION
RETURN 0
END
COMMIT TRANSACTION
RETURN 1
GO
CREATE PROCEDURE Procedimiento_EliminarConcierto (@Id INT, @mensaje VARCHAR(MAX) OUTPUT)
AS
SET NOCOUNT ON
BEGIN TRANSACTION
DELETE FROM Conciertos WHERE Id = @Id
IF @@ERROR = 0
BEGIN
SELECT @mensaje = 'Registro eliminado correctamente'
END
ELSE
BEGIN
SELECT @mensaje = 'Error al eliminar'
ROLLBACK TRANSACTION
RETURN 0
END
COMMIT TRANSACTION
RETURN 1
GO
/* d. Tabla DetallesConcierto */
CREATE PROCEDURE Procedimiento_ObtenerDetallesConcierto (@IdConcierto INT)
AS
SELECT * FROM DetallesConcierto WHERE IdConcierto = @IdConcierto ORDER BY Orden
GO
CREATE PROCEDURE Procedimiento_AgregarDetalleConcierto (@IdConcierto INT, @IdCancion INT, @Orden INT, @mensaje VARCHAR(MAX) OUTPUT)
AS
SET NOCOUNT ON
BEGIN TRANSACTION
INSERT INTO DetallesConcierto VALUES (@IdConcierto, @IdCancion, @Orden)
IF @@error = 0
BEGIN
SELECT @mensaje = 'Correcto'
END
ELSE
BEGIN
SELECT @mensaje = 'Error al insertar'
ROLLBACK TRANSACTION
RETURN 0
END
COMMIT TRANSACTION
RETURN 1
GO
CREATE PROCEDURE Procedimiento_ModificarDetalleConcierto (@IdConcierto INT, @IdCancion INT, @Orden INT, @mensaje VARCHAR(MAX) OUTPUT)
AS
SET NOCOUNT ON
BEGIN TRANSACTION
UPDATE DetallesConcierto SET Orden = @Orden WHERE IdConcierto = @IdConcierto AND IdCancion = @IdCancion
IF @@ERROR = 0 AND @@ROWCOUNT <> 0
BEGIN
SELECT @mensaje = 'Correcto'
END
ELSE
BEGIN
SELECT @mensaje = 'Error al modificar'
ROLLBACK TRANSACTION
RETURN 0
END
COMMIT TRANSACTION
RETURN 1
GO
CREATE PROCEDURE Procedimiento_EliminarDetalleConcierto (@IdConcierto INT, @IdCancion INT, @mensaje VARCHAR(MAX) OUTPUT)
AS
SET NOCOUNT ON
BEGIN TRANSACTION
DELETE FROM DetallesConcierto WHERE IdConcierto = @IdConcierto AND IdCancion = @IdCancion
IF @@ERROR = 0
BEGIN
SELECT @mensaje = 'Registro eliminado correctamente'
END
ELSE
BEGIN
SELECT @mensaje = 'Error al eliminar'
ROLLBACK TRANSACTION
RETURN 0
END
COMMIT TRANSACTION
RETURN 1
GO
</pre>
<br />
Código completo de las demostraciones.<br />
<br />
<pre class="brush:sql;first-line:1">/* Parte 3. Probar procedimientos almacenados */
/* a. Procedimientos de Tabla Artista */
DECLARE @Id INT
DECLARE @Nombre VARCHAR(100)
DECLARE @Pais VARCHAR(100)
DECLARE @mensaje VARCHAR(MAX)
SET @Nombre = 'Katie Melua'
SET @Pais = 'Georgia'
EXEC @Id = Procedimiento_AgregarArtista @Nombre, @Pais, @mensaje OUTPUT
SELECT @Id AS ID, @mensaje AS Mensaje
GO
DECLARE @Id INT
DECLARE @Nombre VARCHAR(100)
DECLARE @Pais VARCHAR(100)
DECLARE @mensaje VARCHAR(MAX)
SET @Nombre = 'The Corrs'
SET @Pais = 'Irlanda'
EXEC @Id = Procedimiento_AgregarArtista @Nombre, @Pais, @mensaje OUTPUT
SELECT @Id AS ID, @mensaje AS Mensaje
GO
EXEC Procedimiento_ObtenerArtistas
GO
DECLARE @Id INT
DECLARE @Nombre VARCHAR(100)
DECLARE @Pais VARCHAR(100)
DECLARE @mensaje VARCHAR(MAX)
DECLARE @resultado INT
SET @Nombre = 'Katie Melua'
SET @Pais = 'Gran Bretaña'
SET @Id = 1
EXEC @resultado = Procedimiento_ModificarArtista @Id, @Nombre, @Pais, @mensaje OUTPUT
SELECT @resultado AS Resultado, @mensaje AS Mensaje
EXEC Procedimiento_BuscarArtista @Id
GO
DECLARE @Id INT
DECLARE @mensaje VARCHAR(MAX)
DECLARE @resultado INT
SET @Id = 2
EXEC @resultado = Procedimiento_EliminarArtista @Id, @mensaje OUTPUT
SELECT @resultado AS Resultado, @mensaje AS Mensaje
EXEC Procedimiento_BuscarArtista @Id
GO
DECLARE @mensaje VARCHAR(MAX)
EXEC Procedimiento_AgregarArtista 'The Corrs', 'Irlanda', @mensaje OUTPUT
EXEC Procedimiento_AgregarArtista 'Michael Buble', 'Canada', @mensaje OUTPUT
EXEC Procedimiento_ObtenerArtistas
GO
/* b. Procedimientos de Tabla Canciones */
DECLARE @mensaje VARCHAR(MAX)
EXEC Procedimiento_AgregarCancion 'Better than a dream', '03:16', @mensaje OUTPUT
EXEC Procedimiento_AgregarCancion 'The bit that I don''t get', '03:06', @mensaje OUTPUT
EXEC Procedimiento_AgregarCancion 'What I miss about you', '03:47', @mensaje OUTPUT
EXEC Procedimiento_AgregarCancion 'Nine million bicycles', '03:14', @mensaje OUTPUT
EXEC Procedimiento_AgregarCancion 'I Cried for you', '03:42', @mensaje OUTPUT
EXEC Procedimiento_AgregarCancion 'Only when I sleep', '03:51', @mensaje OUTPUT
EXEC Procedimiento_AgregarCancion 'Somebody for someone', '04:06', @mensaje OUTPUT
EXEC Procedimiento_AgregarCancion 'Radio', '04:15', @mensaje OUTPUT
EXEC Procedimiento_AgregarCancion 'Song for you', '04:06', @mensaje OUTPUT
EXEC Procedimiento_AgregarCancion 'Everything', '03:33', @mensaje OUTPUT
EXEC Procedimiento_ObtenerCanciones
GO
/* c. Procedimientos de Tabla Conciertos */
DECLARE @mensaje VARCHAR(MAX)
EXEC Procedimiento_AgregarConcierto 1, 'Londres', '08-Nov-2008', @mensaje OUTPUT
EXEC Procedimiento_AgregarConcierto 1, 'Utretcht', '01-Nov-2016', @mensaje OUTPUT
EXEC Procedimiento_AgregarConcierto 3, 'Dublín', '12-Nov-1999', @mensaje OUTPUT
EXEC Procedimiento_AgregarConcierto 3, 'Dublín', '06-Nov-2001', @mensaje OUTPUT
EXEC Procedimiento_AgregarConcierto 4, 'Nueva York', '15-Jun-2009', @mensaje OUTPUT
EXEC Procedimiento_ObtenerConciertos
GO
/* d. Procedimientos de Tabla DetallesConcierto */
DECLARE @mensaje VARCHAR(MAX)
EXEC Procedimiento_AgregarDetalleConcierto 1, 4, 16, @mensaje OUTPUT
EXEC Procedimiento_AgregarDetalleConcierto 1, 5, 19, @mensaje OUTPUT
EXEC Procedimiento_AgregarDetalleConcierto 2, 1, 1, @mensaje OUTPUT
EXEC Procedimiento_AgregarDetalleConcierto 2, 2, 2, @mensaje OUTPUT
EXEC Procedimiento_AgregarDetalleConcierto 2, 3, 3, @mensaje OUTPUT
EXEC Procedimiento_AgregarDetalleConcierto 3, 6, 1, @mensaje OUTPUT
EXEC Procedimiento_AgregarDetalleConcierto 3, 8, 3, @mensaje OUTPUT
EXEC Procedimiento_AgregarDetalleConcierto 4, 6, 1, @mensaje OUTPUT
EXEC Procedimiento_AgregarDetalleConcierto 4, 7, 8, @mensaje OUTPUT
EXEC Procedimiento_AgregarDetalleConcierto 5, 9, 10, @mensaje OUTPUT
EXEC Procedimiento_AgregarDetalleConcierto 5, 10, 8, @mensaje OUTPUT
EXEC Procedimiento_ObtenerDetallesConcierto 1
EXEC Procedimiento_ObtenerDetallesConcierto 2
EXEC Procedimiento_ObtenerDetallesConcierto 3
EXEC Procedimiento_ObtenerDetallesConcierto 4
EXEC Procedimiento_ObtenerDetallesConcierto 5
GO</pre>
<br />
En imágenes:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaTMSeAJ3msshm0tyhHO5GVZc8z04As5hArAXl1fnoAYBHWSGGLml4S06plh7fghJM5N1mcmbK76cxxYQvfMytthwSSXmRiUZLurUVbatzv1mDxXe-lZC0-kyu2jhNHEAtROJrPKtAR7k/s1600/06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaTMSeAJ3msshm0tyhHO5GVZc8z04As5hArAXl1fnoAYBHWSGGLml4S06plh7fghJM5N1mcmbK76cxxYQvfMytthwSSXmRiUZLurUVbatzv1mDxXe-lZC0-kyu2jhNHEAtROJrPKtAR7k/s400/06.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Agregando un artista</div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeTlx0ZO_MtQy9tLp_xJjJjXm75KZE57BdabdTBraC7qBiypmluDeoUbe-IGapZduI8j6-PJWmLOSgym8XVB5r5pW2IEOJHVoJzBk5gLk9tyHNHVBTt7-cQZWH63DGJhjJiS4FPQWKNoU/s1600/07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="254" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeTlx0ZO_MtQy9tLp_xJjJjXm75KZE57BdabdTBraC7qBiypmluDeoUbe-IGapZduI8j6-PJWmLOSgym8XVB5r5pW2IEOJHVoJzBk5gLk9tyHNHVBTt7-cQZWH63DGJhjJiS4FPQWKNoU/s400/07.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Obteniendo la lista de artistas registrados</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPzoclTOYjN8f9u8WRcJDbnS45iJlv3VD7_Q3DH2YzMvyV0OmhfwtWx0k8ocPFI6w32tsMqgzOiHAWlpgLhzTe0CrXw2sCAnPGC-9T0rqZZToKfRZsuQ8bdDTgoQ2hxzu3_ss-O-NxyrE/s1600/08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPzoclTOYjN8f9u8WRcJDbnS45iJlv3VD7_Q3DH2YzMvyV0OmhfwtWx0k8ocPFI6w32tsMqgzOiHAWlpgLhzTe0CrXw2sCAnPGC-9T0rqZZToKfRZsuQ8bdDTgoQ2hxzu3_ss-O-NxyrE/s400/08.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Actualizando la información de un artista y mostrando el valor modificado</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj694BGDaKMkLnWjIqebZp82QVjo5crI-p-Joz-Ti4Vm4fao5M7n9iugq8UTuBLRasIs2YtCehZ3YAxgmjxp_EG8ww_SvDygpk1Kq_yLmaKONGCuNHGuOIrWU6090-wMH-f8bGIhZgb2AY/s1600/09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="355" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj694BGDaKMkLnWjIqebZp82QVjo5crI-p-Joz-Ti4Vm4fao5M7n9iugq8UTuBLRasIs2YtCehZ3YAxgmjxp_EG8ww_SvDygpk1Kq_yLmaKONGCuNHGuOIrWU6090-wMH-f8bGIhZgb2AY/s400/09.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Eliminando un artista y mostrando que ya no existe</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2N99HcGbSPHm1Kvy75jY20sZk5NzuGlveqSmUAfYYLaXnEJPa7Aoz14erdzZfJFC-TniALEOd7TuAJJtT2qYvii7bqkeEOAxyXbRFcQwOf3DOvlSMXwW5Ey620Nn6GWJ2hVJLEMDkavY/s1600/10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="151" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2N99HcGbSPHm1Kvy75jY20sZk5NzuGlveqSmUAfYYLaXnEJPa7Aoz14erdzZfJFC-TniALEOd7TuAJJtT2qYvii7bqkeEOAxyXbRFcQwOf3DOvlSMXwW5Ey620Nn6GWJ2hVJLEMDkavY/s400/10.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Agregando más artistas y mostrando los datos de la tabla</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3sSqcizOS9wdnxtacckV3laAPn4jPzvm5Oh_ylUK7_uBF5hkZyqA5X_7dOpR9B6f7LXGI_Inza-OS-HhdlCgDNq_PVQYDfcPoItAo7cFpt7CE1vlIyBqqz4IbewJ2fBvzb23NbLtnSC8/s1600/11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="308" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3sSqcizOS9wdnxtacckV3laAPn4jPzvm5Oh_ylUK7_uBF5hkZyqA5X_7dOpR9B6f7LXGI_Inza-OS-HhdlCgDNq_PVQYDfcPoItAo7cFpt7CE1vlIyBqqz4IbewJ2fBvzb23NbLtnSC8/s400/11.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Agregando canciones y mostrando los datos de la tabla</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhLcOtSS3Dl5nVsMGCTkmM0ZXLOS7EK6d0LvTQgf1EZVHC-JZCAHOICBI2O9hj2xKKDlW4A9OQ40ETRkxatKlVUEOoiLDtXGALMAHZjYCYRKtPyXy7sNyXTRcrGEqGpFQ0vPBiRDF7nZI/s1600/12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhLcOtSS3Dl5nVsMGCTkmM0ZXLOS7EK6d0LvTQgf1EZVHC-JZCAHOICBI2O9hj2xKKDlW4A9OQ40ETRkxatKlVUEOoiLDtXGALMAHZjYCYRKtPyXy7sNyXTRcrGEqGpFQ0vPBiRDF7nZI/s400/12.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Agregando conciertos y mostrando los datos de la tabla</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgA-h8h_gUCOBMU7shNw7-VhLNrmQYoIXz0o7yOqxhpGL7YdNER72xxsE-rt8kKID6HgQDMJn1cBZNAk-gMlaX7UC1951YlMDPHGokOcEjOafPvXyjSK_TaRbHg8mn1KDY0sELgl2-TAB4/s1600/13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgA-h8h_gUCOBMU7shNw7-VhLNrmQYoIXz0o7yOqxhpGL7YdNER72xxsE-rt8kKID6HgQDMJn1cBZNAk-gMlaX7UC1951YlMDPHGokOcEjOafPvXyjSK_TaRbHg8mn1KDY0sELgl2-TAB4/s400/13.png" width="301" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Agregando detalles de concierto y mostrando los datos de la tabla</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
Recuerda que el código completo del script lo puedes obtener desde <b><a href="https://github.com/icebeam7/xamarin-wcf-sp-ef" target="_blank">el repositorio de GitHub</a></b> creado para este proyecto.<br />
<br />
Con esto concluimos con la primer parte del demo. El día de mañana crearemos el servicio WCF que actuará de intermediario entre las aplicaciones y la base de datos.<br />
<br />
Si tienes alguna sugerencia, recomendación, comentario o algún paso no te funcionó, házmelo saber y con gusto te atenderé :) déjame un comentario y aquí lo revisamos.<br />
<br />
Espero esta entrada te haya sido de utilidad, y si fue así, no dudes en compartirla :)<br />
<br />
Te recuerdo que la experiencia de aprendizaje continúa con el #XamarinDiplomado. Únete a nuestro <a href="https://www.facebook.com/groups/xamarindiplomadoitc/" target="_blank">grupo de estudio en Facebook</a>, donde además de hablar del diplomado de Xamarin 3.0 impartido por Microsoft, también comentamos sobre otras oportunidades de aprendizaje, trabajo, resolvemos dudas y compartimos el conocimiento.<br />
<br />
¡Saludos y hasta pronto!Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com11tag:blogger.com,1999:blog-8407795827837136717.post-54224859577240164282017-04-11T03:08:00.001-07:002017-04-11T03:09:32.398-07:00SGVirtual 11a edición¡Hola! El próximo <b>24 de Mayo</b> tendrá lugar el <b><a href="https://sg.com.mx/sgvirtual" target="_blank">SG Virtual Conference 11a. Edición</a></b>, un evento de un día de duración con conferencias gratuitas online cuyo propósito es promover la participación de entusiastas y expertos tecnológicos en la difusión de temas de interés entre los profesionistas de software.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivktFZCBB0Z3BUVcnQrvladesUrYvQkE5U3gLU84PbMdXmU3bnCO1PqcGMuNuOQW4dGZ0tPItzNoFRojA7-7ZF0FBcZtXTmS0g0d6hI7OpcV3y3lriKAq8TiKsxmUgb_Q4kXgY3qDiOfE/s1600/sg.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivktFZCBB0Z3BUVcnQrvladesUrYvQkE5U3gLU84PbMdXmU3bnCO1PqcGMuNuOQW4dGZ0tPItzNoFRojA7-7ZF0FBcZtXTmS0g0d6hI7OpcV3y3lriKAq8TiKsxmUgb_Q4kXgY3qDiOfE/s1600/sg.png" /></a></div>
<br />
Ya está abierta la <b><a href="https://sg.com.mx/sgvirtual/convocatoria#.WOyl_dJ96Uk" target="_blank">convocatoria de ponencias</a></b> (hasta el 30 de abril), por si deseas participar como expositor con un tema que quieras presentar durante una hora. En mi caso, yo he propuesto participar con el tema <b>Apps móviles inteligentes con Xamarin y Microsoft Cognitive Services</b>, en el que a grandes rasgos mostraré los principios básicos del desarrollo de aplicaciones móviles (en Xamarin) con los servicios de inteligencia artificial creados por Microsoft, los Microsoft Cognitive Services, para darle inteligencia a tus aplicaciones; también presentaré 3 demos (con su código fuente en GitHub, por supuesto). Mostraré cómo puedes crear una aplicación móvil capaz de identificar emociones en una fotografía, reconocer usuarios autorizados mediante comandos de voz y cómo construir un sistema recomendador de productos a través de datos históricos.<br />
<br />
Para más información de mi propuesta, visita <b><a href="https://sg.com.mx/sgvirtual/12/sesion/apps-m-viles-inteligentes-xamarin-y-microsoft-cognitive-services#.WOyjZ9J96Uk">https://sg.com.mx/sgvirtual/12/sesion/apps-m-viles-inteligentes-xamarin-y-microsoft-cognitive-services#.WOyjZ9J96Uk</a></b><br />
<br />
Si crees que mi propuesta es interesante y vale la pena presentarla durante el evento, vota por ella compartiéndola utilizando alguno de los botones de redes sociales que aparecen en la página de SGVirtual debajo del título de la ponencia, es decir:<br />
<br />
<a name='more'></a><br /><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheYaYMgFt8wwMklZeGErv4qXPj6-IEDQXAMsJD6fwVPDsH2o51fsMT94BkJatRvIVby_2xI25OBz14ea7y3LG3eNY7ZBhkUOQJA7UXLTsMSdGsJfZHJGajCjzttplCxC0fvFoACWPsw4k/s1600/vota.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheYaYMgFt8wwMklZeGErv4qXPj6-IEDQXAMsJD6fwVPDsH2o51fsMT94BkJatRvIVby_2xI25OBz14ea7y3LG3eNY7ZBhkUOQJA7UXLTsMSdGsJfZHJGajCjzttplCxC0fvFoACWPsw4k/s400/vota.png" width="400" /></a></div>
<br />
<br />
Las propuestas con más votos (difusión en redes sociales) normalmente son las seleccionadas para ser presentadas durante el evento. Si una sesión no consigue los suficientes votos pero es interesante, también tiene oportunidad de ser seleccionada.<br />
<br />
Enlaces de interés:<br />
<br />
<br />
<ul>
<li><b><a href="https://sg.com.mx/sgvirtual" target="_blank">Sitio oficial de SGVirtual</a></b></li>
<li><b><a href="https://sg.com.mx/sgvirtual/propuestas" target="_blank">Lista de propuestas recibidas</a></b> (¡Vota por aquellas que consideres interesantes y quieras ver en el evento!) </li>
<li>¿Quieres participar como ponente? <b><a href="https://sg.com.mx/sgvirtual/agregar-propuesta" target="_blank">Envía tu propuesta</a></b></li>
<li>¿Te interesa que varios compañeros, amigos, estudiantes, etc. atiendan las sesiones en conjunto? <b><a href="https://sg.com.mx/sgvirtual/que-es-una-sede-virtual#.WOypzdJ96Uk" target="_blank">Participa como sede virtual</a></b>.</li>
</ul>
<div>
<br /></div>
<div>
<div>
Espero esta entrada te haya sido de utilidad, y si fue así, no dudes en compartirla :)</div>
<div>
<br /></div>
<div>
¡Saludos y hasta pronto!</div>
</div>
<br />
<br />Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com0tag:blogger.com,1999:blog-8407795827837136717.post-58234790974202071612017-04-10T05:25:00.001-07:002017-04-10T05:35:50.828-07:00Xamarin Challenge¿Estás listo para participar en otro reto de Xamarin? ¿Qué tal te vendría ganar una Microsoft Surface Studio? Si te interesa aprender a desarrollar aplicaciones móviles multiplataforma o ya sabes y quieres demostrar tus conocimientos, te invito a participar en el <a href="https://xamarinchallenge.thurrott.com/" style="font-weight: bold;" target="_blank">Xamarin Challenge</a>, una iniciativa de <a href="https://thurrott.com/" target="_blank">Paul Thurrot</a> y <a href="http://xamarin.com/" target="_blank">Xamarin</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjP25glY1RDiNsdmAQkWK4-wTsu7zNBhu9t7PAph6pmhPyqkm19Hb7qmqByjJyePQzcMoxpGOTzzFnzEYWITLOrtC_VCJsiZ83kz58FS_ji8AVVg3ydFWLqdVweRnh2bNXiqsVwJbf32ZE/s1600/xc.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjP25glY1RDiNsdmAQkWK4-wTsu7zNBhu9t7PAph6pmhPyqkm19Hb7qmqByjJyePQzcMoxpGOTzzFnzEYWITLOrtC_VCJsiZ83kz58FS_ji8AVVg3ydFWLqdVweRnh2bNXiqsVwJbf32ZE/s400/xc.jpg" width="400" /></a></div>
<br />
<br />
El <b>Xamarin Challenge</b> consiste en desarrollar e implementar una aplicación móvil multiplataforma con Xamarin totalmente funcional siguiendo 3 etapas (o pasos). Realmente es muy sencillo porque solo tienes que seguir las instrucciones que se presentan en cada etapa. La desventaja es que al completar una etapa tendrás que esperar <b>72 horas</b>, por lo que este reto también es de paciencia, jeje.<br />
<br />
Si has participado en los Diplomados de Xamarin Latinoamérica, ¡cuentas con una gran ventaja, pues muchos de los conocimientos necesarios para superar los retos ya los tienes, solo es cosa de implementarlos siguiendo las instrucciones!<br />
<br />
<br />
<a name='more'></a><br />
<br />
<br />
Lo primero es registrarse en el sitio oficial: <a href="https://xamarinchallenge.thurrott.com/" target="_blank">https://xamarinchallenge.thurrott.com/</a> <b>¡Pero házlo cuanto antes, pues el reto concluye el 30 de abril (y debes registrarte antes del 23 de abril, para tener tiempo entre cada etapa)!</b> Completa el formulario y en unos minutos recibirás en tu correo un mensaje de bienvenida al concurso que incluye dos elementos principales: El primero es el enlace con las instrucciones del Paso 1. Lo segundo es un código (<b>challenge code</b>) que deberás introducir en uno de los pasos de la primer etapa, con el cual se validará que has completado cada parte del reto.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAFu2-JH8YWdIIU91KE_FcVcaX_tNoPY97HPSf8yBmOCe-4oLrg1DpMey7pXNBBVKwDYzUflDEDje-FRQ7k44YKCJP7fkWM2Ofdvlj7sY7tAkXWFaBAfZq7r6wcGg6GdM-IoxP3VBeUQw/s1600/xc2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAFu2-JH8YWdIIU91KE_FcVcaX_tNoPY97HPSf8yBmOCe-4oLrg1DpMey7pXNBBVKwDYzUflDEDje-FRQ7k44YKCJP7fkWM2Ofdvlj7sY7tAkXWFaBAfZq7r6wcGg6GdM-IoxP3VBeUQw/s400/xc2.png" width="308" /></a></div>
<br />
Cada vez que completas un Step, recibirás un correo de confirmación en aproximadamente 24 horas donde te informan que se recibió tu entrada, además de que te envían un enlace con el siguiente Step (sin embargo, no podrás descargar la información sino hasta que concluya la espera de 72 horas, un temporizador te indicará cuánto tiempo falta). Una vez pasadas las 72 horas, entra al enlace de nuevo y podrás descargar la información<br />
<b><br /></b>
<b>Nota 1: Cabe aclarar que en mi caso yo tuve que esperar 4 horas más, es decir, pasaron las 72 horas y el enlace seguía deshabilitado, para que tengan algo de paciencia)</b>.<br />
<br />
<b>Nota 2: También dicen que te envían un correo cuando el Step esté disponible (es decir, que hayan transcurrido las 72 horas) pero en mi caso no me llegó, por ello tuve que dar clic en el correo anterior para acceder a la información del Step.</b><br />
<br />
<b>Paso 1.</b><br />
Consiste en realizar varias actividades: instalar las herramientas de desarrollo (VS2017, aunque honestamente puedes completar con VS2015 los pasos), crear una solución de Xamarin.Forms, agregar imágenes, paquetes Nuget, editar las propiedades de los proyectos y comunicarte con un servicio de información del clima. Al finalizar, tu aplicación mostrará el clima actual de una ciudad seleccionada:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKfQz8tOcxvWwPL1yfFgjVhmLg42TBm8_JE__gf7vV0jG5wyjCVBYWmdc9WOFulokeh9adotwwy_gNaht1GPoD6BCyWEH64yTIiWmfGtl-hps14NTOSgYCKZAzRO0JKjD5m-BwHtNHmdo/s1600/st1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKfQz8tOcxvWwPL1yfFgjVhmLg42TBm8_JE__gf7vV0jG5wyjCVBYWmdc9WOFulokeh9adotwwy_gNaht1GPoD6BCyWEH64yTIiWmfGtl-hps14NTOSgYCKZAzRO0JKjD5m-BwHtNHmdo/s320/st1.png" width="180" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJPxVeE-o3_Yd4C68PHu8gJ8WUBVio5B1gxQNIzrIJ7C5C4_MZA9ADwCWmt1f2T7MTus00r3qeLJ2IeykPLeo9NDVa6F583RI_ioJUWAB0EDiSqPqQtLqx8zcXAlVQN9JswrnHse-vv3c/s1600/st2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJPxVeE-o3_Yd4C68PHu8gJ8WUBVio5B1gxQNIzrIJ7C5C4_MZA9ADwCWmt1f2T7MTus00r3qeLJ2IeykPLeo9NDVa6F583RI_ioJUWAB0EDiSqPqQtLqx8zcXAlVQN9JswrnHse-vv3c/s320/st2.png" width="180" /></a></div>
<br />
<b>Paso 2.</b><br />
En esta fase, agregarás geolocalización, pestañas (TabbedPages) y una barra de navegación a tu aplicación. La geolocalización permitirá obtener la información del clima de tu ciudad actual, además de agregar un servicio de predicción del clima en horas y días posteriores.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFtItGZjou8kStUpou2HUDSgy-bKwhOquO4BwWt21_DEaQUviWgncpSztoN6W4C-i2UHqJrL7Tz7SIBdSR5DtvVisJCFERH9o7Em4L8Ba2wBXEBqd4QvkqoWWho_QOw-C9jSaHvARBDeM/s1600/st3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFtItGZjou8kStUpou2HUDSgy-bKwhOquO4BwWt21_DEaQUviWgncpSztoN6W4C-i2UHqJrL7Tz7SIBdSR5DtvVisJCFERH9o7Em4L8Ba2wBXEBqd4QvkqoWWho_QOw-C9jSaHvARBDeM/s320/st3.png" width="180" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZMLHtQuoGol1_qULsZt9iLBQwMbWWSi6LcnKhTak6koShE3gcJZogvo5_myRiW_xtM8sbnn9v4B_Kz9ETNFYfRA1io0pHFjikjpDHt1uKDh4CwZk4dowLkdNYL7mK390paVLIar5bHYc/s1600/st4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZMLHtQuoGol1_qULsZt9iLBQwMbWWSi6LcnKhTak6koShE3gcJZogvo5_myRiW_xtM8sbnn9v4B_Kz9ETNFYfRA1io0pHFjikjpDHt1uKDh4CwZk4dowLkdNYL7mK390paVLIar5bHYc/s320/st4.png" width="180" /></a></div>
<br />
<b>Paso 3.</b><br />
Para concluir con el reto, incorporarás HockeyApp y Visual Studio Mobile Center para monitorear el estado de salud de tu aplicación móvil, agregando servicios de soporte y análisis, de manera que cada vez que tu app <i>crashee</i> (genere una excepción), puedas ser informado al respecto con gran detalle, pues puedes conocer el tipo de dispositivo que generó la excepción, en qué parte de la aplicación, el mensaje enviado y más datos que te permitirán tomar las medidas necesarias en tu app. Una vez concluido el reto, ejecutarás la app implementando un botón que te permitirá enviar tu solicitud de Reto Completado y participar por los 2 premios (Microsoft Surface Studio).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi02exL5qmd8HJyQPrPejyRYhH5KOkrmYPt6qt5gD61Hu2DJD17hA3MeehNbYSIggtgeRm_qKKlewKMJhj4KOooZED-prrX_zmeIkYzzznuSk1Tb5n3ioMW2quhSIwnt0GaK97fIBTl4Ps/s1600/st5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="43" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi02exL5qmd8HJyQPrPejyRYhH5KOkrmYPt6qt5gD61Hu2DJD17hA3MeehNbYSIggtgeRm_qKKlewKMJhj4KOooZED-prrX_zmeIkYzzznuSk1Tb5n3ioMW2quhSIwnt0GaK97fIBTl4Ps/s320/st5.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixykdkLOdzUZQGjRs655lJ1mYiybIUYMMttoCBzPoEply8gqluIjcaASY1We3rG4ytt6zXGXG-AmB46eDWaDiSV_xoWxffLw2PNr-W8EUPygfK450Wl7db9wjgwQdiQ5HAtT1xMOZpRMo/s1600/st6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixykdkLOdzUZQGjRs655lJ1mYiybIUYMMttoCBzPoEply8gqluIjcaASY1We3rG4ytt6zXGXG-AmB46eDWaDiSV_xoWxffLw2PNr-W8EUPygfK450Wl7db9wjgwQdiQ5HAtT1xMOZpRMo/s320/st6.png" width="180" /></a></div>
<br />
<b>Recuerda registrarte antes del 23 de abril para que tengas tiempo suficiente de concluir los retos antes de la fecha límite (30 de abril), pues entre cada paso debes esperar 72 horas.</b><br />
<br />
Y bien, ¿qué te parece la idea? ¿Nos unimos al reto? Si tu respuesta es sí, ¡pues comencemos! Yo realizaré un reto cada día, para mantener la emoción del momento jeje. <b><a href="https://twitter.com/darkicebeam" target="_blank">Sígueme en Twitter</a></b> y compárteme tus avances. Recuerda que también tenemos un <b><a href="https://www.facebook.com/groups/xamarindiplomadoitc/" target="_blank">grupo de apoyo de Xamarin en Facebook </a></b>en el que una comunidad en español de más de 2000 miembros nos apoyamos resolviendo dudas, compartiendo conocimiento y oportunidades. Únete dando clic <a href="https://www.facebook.com/groups/xamarindiplomadoitc/" target="_blank"><b>aquí</b></a>.<br />
<br />
Si tienes alguna duda o simplemente compartir tu participación en el reto (me dará gusto saberlo), también déjame un comentario y haré lo posible por ayudarte :) o mándame un tweet, correo o mensaje en el grupo de Facebook.<br />
<br />
¡No pierdas la oportunidad de seguir aprendiendo acerca de Xamarin y demostrando tus conocimientos!<br />
<div>
<br /></div>
<div>
Espero esta entrada te haya sido de utilidad, y si fue así, no dudes en compartirla :)<br />
<br />
¡Saludos y hasta pronto!<br />
<br />
PD: También te recuerdo que hay otro reto de Xamarin vigente. Más información, <b><a href="http://icebeamwp.blogspot.com/2017/04/xamarin-alliance-challenge.html" target="_blank">aquí</a></b>.</div>
Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com1tag:blogger.com,1999:blog-8407795827837136717.post-11087462069055012292017-04-10T03:46:00.000-07:002017-04-10T05:35:38.769-07:00Xamarin Alliance Challenge¡Hola! En esta entrada les comparto la información sobre <b><a href="http://www.xamarinalliance.com/" target="_blank">Xamarin Alliance</a></b>, el cual consiste en una serie de 5 retos quincenales en los que desarrollarás una aplicación multiplataforma usando Xamarin y que puedes implementar en Android, iOS y Windows 10.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiuRH9UvdkrX7Fw7fPPNzOvK0km-UuP9X9op5VEpQjjE-BJfcMa4AE4RLxjodbbEn6gkojSLACQPZRFeJalHy9ZHcd9PnDknsDdhtiptj9GwM3ns9TywBpr742UlMvhAi7rNaOBx4t2z0/s1600/logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiuRH9UvdkrX7Fw7fPPNzOvK0km-UuP9X9op5VEpQjjE-BJfcMa4AE4RLxjodbbEn6gkojSLACQPZRFeJalHy9ZHcd9PnDknsDdhtiptj9GwM3ns9TywBpr742UlMvhAi7rNaOBx4t2z0/s400/logo.png" width="400" /></a></div>
<br />
Xamarin Alliance es una iniciativa de Microsoft Belux (Bélgica y Luxemburgo) que te motiva a desarrollar tu primer aplicación de Xamarin de una manera ágil, sencilla e intuitiva con instrucciones que facilitarán tu entrada en el desarrollo de aplicaciones multiplataforma combinadas con el cómputo en la nube de Microsoft Azure.<br />
<br />
Esta es una iniciativa internacional, por lo que está abierta a todo público interesado. Al completar los 5 retos deberás enviar tu aplicación final para revisión. Si es aprobada, ¡te harás acreedor a un diploma con el se reconocerán tus logros como Xamarin Developer!<br />
<br />
Si has participado en los Diplomados de Xamarin Latinoamérica, ¡cuentas con una gran ventaja, pues muchos de los conocimientos necesarios para superar los retos ya los tienes, solo es cosa de implementarlos siguiendo las instrucciones!<br />
<br />
No hay página de registro, simplemente comienza con el primer reto y continúa con tu aplicación siguiendo las instrucciones mostradas en cada uno de ellos.<br />
<br />
<a name='more'></a><br />
<br />
¿En qué consisten los 5 retos? Al momento de publicar esta entrada, 4 de los retos ya han sido publicados:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKG7-kW6iU8ejwSBKdPWA9gro6yS418Jx8h5PB6pKPlkN47C2nTQl7uB8A7Vhq9k47dN3X62BtKUH3Xg3GH0-2Uxpobu8ao-wEktGwOfk_K0daR-dfhGRkO9rYNGRtAvF6r5ggAV-U6-M/s1600/retos.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="78" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKG7-kW6iU8ejwSBKdPWA9gro6yS418Jx8h5PB6pKPlkN47C2nTQl7uB8A7Vhq9k47dN3X62BtKUH3Xg3GH0-2Uxpobu8ao-wEktGwOfk_K0daR-dfhGRkO9rYNGRtAvF6r5ggAV-U6-M/s400/retos.png" width="400" /></a></div>
<br />
Cada reto incorpora un escenario específico que debes resolver:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBCM6aNblLPHqJm6JunEX0KYu4n5yVNLRVGuxROrPB34JVVtwmNjphEasu3gi9Hyy4WiGuIZSs8XKqGF3TK9WPRjIqeRvzrGgn79Oa6xvoAxNu40biGCgpeSRzSN37l8DM2H5i62nXVuc/s1600/1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBCM6aNblLPHqJm6JunEX0KYu4n5yVNLRVGuxROrPB34JVVtwmNjphEasu3gi9Hyy4WiGuIZSs8XKqGF3TK9WPRjIqeRvzrGgn79Oa6xvoAxNu40biGCgpeSRzSN37l8DM2H5i62nXVuc/s200/1.png" width="200" /></a></div>
<b><a href="http://www.xamarinalliance.com/challenge-1/" target="_blank">Reto 1. Get locked and loaded</a></b><br />
El primer reto consiste en instalar las herramientas que utilizarás (VS2015 o VS2017, a tu elección), así como descargar un template (aplicación base), modificarlo a tu gusto y probar su funcionamiento.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6oRhSfqN-vESDu5i8LRrf5-D3Ma4h77XVDcLMLUOee1EQMwuHHrHOrb486QANOqGAI84ffrimFhAQVZFciRePg8U_n_KX4T6_H6tb_Oc_DcscX8qZWjndpdS0izQUdhrFDENr9TRy0HY/s1600/2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6oRhSfqN-vESDu5i8LRrf5-D3Ma4h77XVDcLMLUOee1EQMwuHHrHOrb486QANOqGAI84ffrimFhAQVZFciRePg8U_n_KX4T6_H6tb_Oc_DcscX8qZWjndpdS0izQUdhrFDENr9TRy0HY/s200/2.png" width="200" /></a></div>
<b><a href="http://www.xamarinalliance.com/challenge-2/" target="_blank">Reto 2. Build </a></b><br />
Agrega múltiples páginas e implementa navegación en tu aplicación: desde páginas jerárquicas hasta páginas maestro-detalle.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ14rSoQ_f5F0rEActhY2db4s2LYxpMhqYL3XT2pdsJhyphenhyphenpvBOGzYSoVlUkzMbvuq3EkVgTE7O0NhhRKUSBYGXZQFC1UIYSIrFvpyp6MnzyzQAyHZiDW3WC1qo96-P9XD1b9QT8Sw8gNKk/s1600/3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ14rSoQ_f5F0rEActhY2db4s2LYxpMhqYL3XT2pdsJhyphenhyphenpvBOGzYSoVlUkzMbvuq3EkVgTE7O0NhhRKUSBYGXZQFC1UIYSIrFvpyp6MnzyzQAyHZiDW3WC1qo96-P9XD1b9QT8Sw8gNKk/s200/3.png" width="200" /></a></div>
<b><a href="http://www.xamarinalliance.com/challenge-3/" target="_blank">Reto 3. Connect</a></b><br />
En este reto integrarás la nube con tu aplicación movil, pues consiste en crear un Azure Mobile App backend que se conecta a tu aplicación móvil creada con Xamarin. Requieres crear una cuenta de Azure. Recuerda que existen varias opciones de obtener una de manera gratuita: <b><a href="https://www.visualstudio.com/es/dev-essentials/" target="_blank">Visual Studio Dev Essentials</a></b> (que te da 25 USD mensuales por un año), <b><a href="https://azure.microsoft.com/es-mx/free/" target="_blank">Trial</a></b> (que te da 200 USD por un mes), <a href="https://azure.microsoft.com/es-mx/pricing/member-offers/visual-studio-subscriptions/" target="_blank"><b>MSDN</b></a> (que te da 150 USD mensuales por la duración de tu membresía) y Azure Pass (que te da 100 USD mensuales por 90 días) y <b><a href="http://icebeamwp.blogspot.cz/2017/02/crea-una-cuenta-de-azure-sin-tarjeta-de.html" target="_blank">aquí</a></b> te explico cómo obtener uno.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNH4um47_8ZLz-qL8tK5nUjvViSfF6jbphoWxCwGaJwT8IEMXt3FidaU3ka19WNjYyh9Tvl_OasFjaBv-yXs-v0VEGKXni775D9SWjKfsR7E7F_OdvYW7Qv42jZo80e-QLdJrP6wy7uNE/s1600/4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNH4um47_8ZLz-qL8tK5nUjvViSfF6jbphoWxCwGaJwT8IEMXt3FidaU3ka19WNjYyh9Tvl_OasFjaBv-yXs-v0VEGKXni775D9SWjKfsR7E7F_OdvYW7Qv42jZo80e-QLdJrP6wy7uNE/s200/4.png" width="200" /></a></div>
<b><a href="http://www.xamarinalliance.com/challenge-4/" target="_blank">Reto 4. Identify</a></b><br />
El cuarto reto consiste en agregar autentificación en tu aplicación móvil, por lo que aprenderás cómo integrar proveedores de identidad (Facebook, Twitter, Microsoft, etc).<br />
<br />
<b>Reto 5. Coming soon!</b><br />
¡Espéralo muy pronto! (No hay más información de momento)<br />
<br />
Al concluir cada reto puedes compartir tus avances en Twitter o Facebook. No es necesario, pero siempre es bonito compartir con los demás lo que haces, ¿cierto? :)<br />
<br />
Otra ventaja es que puedes modificar esta aplicación para que se ajuste a tus necesidades. Tal vez estás desarrollando otra aplicación y de aquí obtienes alguna idea o un código interesante que quieras revisar/implementar :)<br />
<br />
Y bien, ¿qué te parece la idea? ¿Nos unimos al reto? Si tu respuesta es sí, ¡pues comencemos! Yo realizaré un reto cada día, para mantener la emoción del momento jeje. <b><a href="https://twitter.com/darkicebeam" target="_blank">Sígueme en Twitter</a></b> y compárteme tus avances. Recuerda que también tenemos un <b><a href="https://www.facebook.com/groups/xamarindiplomadoitc/" target="_blank">grupo de apoyo de Xamarin en Facebook </a></b>en el que una comunidad en español de más de 2000 miembros nos apoyamos resolviendo dudas, compartiendo conocimiento y oportunidades. Únete dando clic <a href="https://www.facebook.com/groups/xamarindiplomadoitc/" target="_blank"><b>aquí</b></a>.<br />
<br />
Si tienes alguna duda o simplemente compartir tu participación en el reto (me dará gusto saberlo), también déjame un comentario y haré lo posible por ayudarte :) o mándame un tweet, correo o mensaje en el grupo de Facebook.<br />
<br />
¡No pierdas la oportunidad de seguir aprendiendo acerca de Xamarin y demostrando tus conocimientos!<br />
<br />
Por cierto, desconozco la vigencia de este reto, ¡así que recomiendo que comiencen cuanto antes!<br />
<br />
Sitio oficial: <a href="http://www.xamarinalliance.com/" target="_blank">http://www.xamarinalliance.com/</a><br />
<br />
Repositorio de GitHub con el código e instrucciones de cada reto: <a href="https://github.com/msdxbelux/XamarinAlliance" target="_blank">https://github.com/msdxbelux/XamarinAlliance</a><br />
<br />
Espero esta entrada te haya sido de utilidad, y si fue así, no dudes en compartirla :)<br />
<br />
¡Saludos y hasta pronto!<br />
<br />
PD: También te recuerdo que hay otro reto de Xamarin vigente. Más información, <b><a href="http://icebeamwp.blogspot.com/2017/04/xamarin-challenge.html" target="_blank">aquí</a></b>.Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com0tag:blogger.com,1999:blog-8407795827837136717.post-81160242071217352232017-03-27T01:36:00.000-07:002017-03-27T01:36:06.139-07:00Validación de datos usando Behaviors en Xamarin.Forms¡Hola! Hace unos días me escribieron al correo preguntando sobre cómo validar mediante Behaviors la entrada de datos del usuario, por ejemplo, que sólo haya números en un Entry; también había duda sobre cómo limitar la cantidad de caracteres en el Entry, por ejemplo, que solo acepte 10 caracteres.<br />
<br />
Investigando, encontré el siguiente <a href="http://www.c-sharpcorner.com/article/input-validation-in-xamarin-forms-behaviors/" target="_blank"><b>enlace</b></a>, en el cual está basado este post con ciertas modificaciones que voy a mencionar. La idea de esta publicación es validar las entradas de datos que el usuario realiza típicamente en un formulario. En la siguiente publicación veremos cómo validar correos electrónicos, fechas, números telefónicos e incluso verificar la relación entre dos controles (verificando que el texto introducido en dos Entrys sean iguales, por ejemplo). Para ello, utilizaremos <b>Behaviors</b>, que son elementos que permiten añadir funcionalidad a nuestros controles y que los podemos reutilizar, lo cual ayuda a tener un código más compacto y disponible donde lo necesitemos. También haremos uso de otras técnicas, por ejemplo <b>expresiones regulares</b>.<br />
<br />
Básicamente, lo que hay que hacer es declarar una clase que <b>herede </b>de la clase <b>Behavior<t></t></b>, donde <b>T</b> es un control (por ejemplo, un <b>Entry</b>, un <b>DatePicker</b>, etc). Esta clase puede contener una <b>BindableProperty</b>, es decir, un elemento que se desee enlazar al control para interactuar con él desde el código XAML. Lo que si debe realizarse es hacer un <b>override</b> de 2 métodos: <b>OnAttachedTo </b>y <b>OnDetachingFrom</b>, en los cuales nos suscribimos y desuscribimos respectivamente a los manejadores de evento que vamos a considerar para el control. También se pueden hacer operaciones de inicialización y finalización del control. Es importante sobre todo remover las referencias a manejadores de eventos que no vamos a manejar más (mediante OnDetachingFrom) por cuestiones de manejo de memoria en nuestras aplicaciones móviles. Finalmente, otro código opcional (pero casi seguro que lo agregamos) pues es precisamente el de los manejadores de evento agregados desde OnAttachedTo.<br />
<br />
<br />
<pre class="brush:csharp;first-line:1">public class MiClase : Behavior<Control>
{
public static readonly BindableProperty MiPropiedad = BindableProperty.Create("Propiedad", typeof(tipo), typeof(MiClase), valorInicial);
public int Propiedad
{
get { return (tipo)GetValue(MiPropiedad); }
set { SetValue(MiPropiedad, value); }
}
protected override void OnAttachedTo(Control c)
{
}
protected override void OnDetachingFrom(Control c)
{
}
}</pre>
<br />
<br />
<br />
<a name='more'></a><br />
<br />
Vamos a ver el código específico ¡Manos a la obra!<br />
<br />
<b>Paso 1</b>. Crea un proyecto de tipo <b>Xamarin.Forms Portable</b>. Para este caso, he puesto el nombre <b>Validaciones</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitFwkppn0XcKtS2quxmeAKLmzT3QQaa9to1wTp2xZPI0W4QsxWippCy6RaQDnxccpjy88c5tIYMBkHO1TsxpbS1mKuTRAieaD5qI2Pd_3vu6bD54TnxUZV77oImKFlCjglkdHyW06On58/s1600/01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="243" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitFwkppn0XcKtS2quxmeAKLmzT3QQaa9to1wTp2xZPI0W4QsxWippCy6RaQDnxccpjy88c5tIYMBkHO1TsxpbS1mKuTRAieaD5qI2Pd_3vu6bD54TnxUZV77oImKFlCjglkdHyW06On58/s400/01.png" width="400" /></a></div>
<br />
<b>Paso 2</b>. En el proyecto compartido, crea una carpeta llamada <b>Behaviors</b>, en la cual agregarás varias clases, las cuales describiremos a continuación:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvDXtcLFdlSAeAiX0gM1PrzFvMObEwVLB9-diZLVyWx4T1WKWFVi6JcYNpFr7COoI6Gx3k-cEIN0X3eHiYmgnn0sQQgaBjIfJIktdfHRaHXHMSYL1IT3RxDGTfQXa0AUkQ-F3O8Voz30c/s1600/05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="365" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvDXtcLFdlSAeAiX0gM1PrzFvMObEwVLB9-diZLVyWx4T1WKWFVi6JcYNpFr7COoI6Gx3k-cEIN0X3eHiYmgnn0sQQgaBjIfJIktdfHRaHXHMSYL1IT3RxDGTfQXa0AUkQ-F3O8Voz30c/s400/05.png" width="400" /></a></div>
<br />
<b>EmailValidatorBehavior.cs: </b>Esta clase sirve para validar que <b>el correo electrónico </b>introducido en un <b>Entry </b>sea válido. En este caso, utilizo una expresión regular que cubre la mayoría de casos válidos de un correo electrónico (tal vez se me escape alguno). La idea es utilizar el evento TextChanged del Entry. Cada vez que el usuario introduzca un caracter, se valida la cadena de texto completa. En el momento en que el patrón de correo electrónico se cumpla, el color cambiará a verde; mientras que no se cumpla esa condición, será rojo. Cuando ya no se necesite más el control (por ejemplo, que se navegue a otra página), se desuscribe el evento. El código es el siguiente:<br />
<br />
<br />
<pre class="brush:csharp;first-line:1">using System;
using System.Text.RegularExpressions;
using Xamarin.Forms;
namespace Validaciones.Behaviors
{
public class EmailValidatorBehavior : Behavior<Entry>
{
const string emailRegex = @"^[\w!#$%&'*+\-/=?\^_`{|}~]+(\.[\w!#$%&'*+\-/=?\^_`{|}~]+)*" + "@" + @"((([\-\w]+\.)+[a-zA-Z]{2,4})|(([0-9]{1,3}\.){3}[0-9]{1,3}))$";
protected override void OnAttachedTo(Entry entry)
{
entry.TextChanged += TextChanged;
base.OnAttachedTo(entry);
}
// Valida si el texto introducido es un correo electrónico
void TextChanged(object sender, TextChangedEventArgs e)
{
bool valido = (Regex.IsMatch(e.NewTextValue, emailRegex, RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250)));
((Entry)sender).TextColor = valido ? Color.Green : Color.Red;
}
protected override void OnDetachingFrom(Entry entry)
{
entry.TextChanged -= TextChanged;
base.OnDetachingFrom(entry);
}
}
}</pre>
<br />
<b>FechaValidatorBehavior.cs</b>: Esta clase sirve para validar que la fecha seleccionada en un <b>DatePicker</b> no sea menor a 100 años máximo (es solo un ejemplo, tú puedes modificar el valor o la condición, por ejemplo que esté entre el año 1980 y 2000) y su código es el siguiente:<br />
<br />
<br />
<pre class="brush:csharp;first-line:1">using System;
using Xamarin.Forms;
namespace Validaciones.Behaviors
{
public class FechaValidatorBehavior : Behavior<DatePicker>
{
protected override void OnAttachedTo(DatePicker dp)
{
dp.DateSelected += DateSelected;
base.OnAttachedTo(dp);
}
// Valida una fecha menor al año actual en 100 años máximo
private void DateSelected(object sender, DateChangedEventArgs e)
{
int resultado = DateTime.Now.Year - e.NewDate.Year;
bool valido = (resultado <= 100 && resultado >= 0);
((DatePicker)sender).BackgroundColor = valido ? Color.Green : Color.Red;
}
protected override void OnDetachingFrom(DatePicker dp)
{
dp.DateSelected -= DateSelected;
base.OnDetachingFrom(dp);
}
}
}</pre>
<br />
<b>MaxLengthValidatorBehavior.cs: </b>Esta clase sirve para <b>limitar la cantidad de caracteres aceptados </b>en un <b>Entry</b>. Cabe mencionar que todos los ejemplos que encontré utilizan <b>TextChanged</b> y <b>funcionan en Android, pero no en UWP.</b> La única forma de que funcionara en ambos fue suscribiendo en su lugar el evento <b>Unfocused</b>. La ventaja de usar TextChanged es que no te dejará introducir más de N caracteres (es decir, cuando tengas 10 caracteres, todo lo demás que presiones no se agregará a la caja de texto), mientras que para Unfocused necesitas hacer Tap en otra parte del formulario (es decir, que el Entry pierda el foco) para que toda la cadena sea validada y se remuevan los caracteres adicionales. Por un lado, lo ideal sería que funcionara como TextChanged, pero no encontré cómo hacerlo funcionar en UWP, pues siempre dejaba introducir más de 10 caracteres. En fin, con Unfocused funcionó, jeje. El código es el siguiente:<br />
<br />
<br />
<pre class="brush:csharp;first-line:1">using Xamarin.Forms;
namespace Validaciones.Behaviors
{
public class MaxLengthValidatorBehavior : Behavior<Entry>
{
public static readonly BindableProperty MaxLengthProperty = BindableProperty.Create("MaxLength", typeof(int), typeof(MaxLengthValidatorBehavior), 0);
public int MaxLength
{
get { return (int)GetValue(MaxLengthProperty); }
set { SetValue(MaxLengthProperty, value); }
}
protected override void OnAttachedTo(Entry entry)
{
entry.Unfocused += Unfocused;
base.OnAttachedTo(entry);
}
// Devuelve una cadena de máximo una longitud permitida
private void Unfocused(object sender, FocusEventArgs e)
{
Entry entry = (Entry)sender;
entry.Text = entry.Text.Substring(0, MaxLength);
}
protected override void OnDetachingFrom(Entry entry)
{
entry.Unfocused -= Unfocused;
base.OnDetachingFrom(entry);
}
}
}</pre>
<br />
<b>NumeroValidatorBehavior.cs: </b>Esta clase sirve para validar que el <b>Entry </b>solo contenga <b>dígitos</b>, y su código es el siguiente, apoyado en una <b>expresión regular</b>:<br />
<br />
<br />
<pre class="brush:csharp;first-line:1">using System;
using System.Text.RegularExpressions;
using Xamarin.Forms;
namespace Validaciones.Behaviors
{
public class NumeroValidatorBehavior : Behavior<Entry>
{
const string digitosRegEx = @"^[0-9]+$";
protected override void OnAttachedTo(Entry entry)
{
entry.TextChanged += TextChanged;
base.OnAttachedTo(entry);
}
// Solo dígitos
void TextChanged(object sender, TextChangedEventArgs e)
{
bool valido = (Regex.IsMatch(e.NewTextValue, digitosRegEx, RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250)));
((Entry)sender).TextColor = valido ? Color.Green : Color.Red;
}
protected override void OnDetachingFrom(Entry entry)
{
entry.TextChanged -= TextChanged;
base.OnDetachingFrom(entry);
}
}
}</pre>
<br />
<b>PasswordValidatorBehavior.cs: </b>Esta clase sirve para validar que el contenido de un <b>Entry</b> cumpla ciertas reglas. Para este caso específico, yo quiero que contenga <b>10 caracteres</b>, de los cuales al menos exista <b>una mayúscula, una minúscula, un dígito y un caracter especial</b> (por ejemplo, <b>P@$$w0rd123 </b>es una cadena <b>válida</b>, mientras que <b>password123</b> <b>no</b> lo es). Su código es el siguiente:<br />
<br />
<br />
<pre class="brush:csharp;first-line:1">using System.Text.RegularExpressions;
using Xamarin.Forms;
namespace Validaciones.Behaviors
{
public class PasswordValidatorBehavior : Behavior<Entry>
{
const string passwordRegex = @"^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{10,}$";
protected override void OnAttachedTo(Entry entry)
{
entry.TextChanged += TextChanged;
base.OnAttachedTo(entry);
}
//10 caracteres, con al menos: 1 digito, 1 minúscula, 1 mayúscula, 1 caracter especial
void TextChanged(object sender, TextChangedEventArgs e)
{
bool valido = (Regex.IsMatch(e.NewTextValue, passwordRegex));
((Entry)sender).TextColor = valido ? Color.Green : Color.Red;
}
protected override void OnDetachingFrom(Entry entry)
{
entry.TextChanged -= TextChanged;
base.OnDetachingFrom(entry);
}
}
}</pre>
<br />
<b>CompareTextsValidatorBehavior.cs: </b>Esta clase es la primera que utilizo para relacionar dos controles y es muy sencilla de entender. Básicamente, sirve para validar que <b>el texto </b>introducido en dos <b>Entry</b> sea el mismo, por ejemplo cuando queremos confirmar una contraseña. En este caso, se utilizan <b>BindableProperty</b> que vamos a asignar desde el XAML. Solo se requiere la propiedad de <b>Text</b> (el texto del otro control) pero a mi me interesa una referencia cruzada, es decir, una referencia a otro control (<b>Ent</b>) porque quiero que los dos controles aparezcan del mismo color dependiendo la validación. Es decir, si no pusiera esta referencia, cuando la cadena se modifique, solo un control cambiará su color, generando inconsistencias. Su código es el siguiente:<br />
<br />
<br />
<pre class="brush:csharp;first-line:1">using Xamarin.Forms;
namespace Validaciones.Behaviors
{
public class CompareTextsValidatorBehavior : Behavior<Entry>
{
public static BindableProperty TextProperty = BindableProperty.Create<CompareTextsValidatorBehavior, string>(tc => tc.Text, string.Empty, BindingMode.TwoWay);
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static BindableProperty EntProperty = BindableProperty.Create<CompareTextsValidatorBehavior, Entry>(tc => tc.Ent, null, BindingMode.TwoWay);
public Entry Ent
{
get { return (Entry)GetValue(EntProperty); }
set { SetValue(EntProperty, value); }
}
protected override void OnAttachedTo(Entry entry)
{
entry.TextChanged += TextChanged;
base.OnAttachedTo(entry);
}
// Compara que el texto de este control sea el mismo que el de otro control
void TextChanged(object sender, TextChangedEventArgs e)
{
bool valido = (e.NewTextValue == Text);
((Ent == null) ? (Entry)sender : Ent).TextColor = valido ? Color.Green : Color.Red;
}
protected override void OnDetachingFrom(Entry entry)
{
entry.TextChanged -= TextChanged;
base.OnDetachingFrom(entry);
}
}
}</pre>
<br />
<b>CompareDatesValidatorBehavior.cs:</b> Por último, esta clase sirve para validar que la fecha seleccionada en un control <b>DatePicker </b>sea menor a la fecha de otro <b>DatePicker</b>. Al igual que en el caso anterior, solo se requiere una propiedad (<b>Date</b>), pero yo agrego otra propiedad (<b>DatePick</b>) para tener la referencia al otro control, y poder modificar su color si la fecha de cualquiera de los dos cambia y evitar inconsistencias. Su código es el siguiente:<br />
<br />
<br />
<pre class="brush:csharp;first-line:1">using System;
using Xamarin.Forms;
namespace Validaciones.Behaviors
{
public class CompareDatesValidatorBehavior : Behavior<DatePicker>
{
public static BindableProperty DateProperty = BindableProperty.Create<CompareDatesValidatorBehavior, DateTime>(dt => dt.Date, DateTime.Now, BindingMode.TwoWay);
public DateTime Date
{
get { return (DateTime)GetValue(DateProperty); }
set { SetValue(DateProperty, value); }
}
public static BindableProperty OrderProperty = BindableProperty.Create<CompareDatesValidatorBehavior, int>(dt => dt.Order, 0, BindingMode.TwoWay);
public int Order
{
get { return (int)GetValue(OrderProperty); }
set { SetValue(OrderProperty, value); }
}
public static BindableProperty DatePickProperty = BindableProperty.Create<CompareDatesValidatorBehavior, DatePicker>(dt => dt.DatePick, null, BindingMode.TwoWay);
public DatePicker DatePick
{
get { return (DatePicker)GetValue(DatePickProperty); }
set { SetValue(DatePickProperty, value); }
}
protected override void OnAttachedTo(DatePicker dp)
{
dp.DateSelected += DateSelected;
base.OnAttachedTo(dp);
}
// Compara que la fecha seleccionada sea mayor a la de otro control
private void DateSelected(object sender, DateChangedEventArgs e)
{
bool valido = (Order == 1) ? Date > e.NewDate : (e.NewDate > Date);
((DatePicker)sender).BackgroundColor = valido ? Color.Green : Color.Red;
DatePick.BackgroundColor = valido ? Color.Green : Color.Red;
}
protected override void OnDetachingFrom(DatePicker dp)
{
dp.DateSelected -= DateSelected;
base.OnDetachingFrom(dp);
}
}
}</pre>
<br />
<b>Paso 3</b>. Lo que sigue es crear una página a manera de formulario donde enlacemos varios controles a los <b>Behaviors</b> creados. Agregamos una carpeta llamada <b>Paginas</b> y dentro, una <b>Forms Xaml Page</b> llamada <b>Formulario</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWreSx3oZSv9jYBgcpnC91F10k_5WTqT5kRFx-z9BOolfiHVdgRjbaVl5VSjtH21jd3UafEFK3H1atvZoNtXYV7xZ-cJSTrReCpS9_rdFvovZi8E8PWJKwPUzKlbkPEQjkkbQcQeKz0hk/s1600/06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWreSx3oZSv9jYBgcpnC91F10k_5WTqT5kRFx-z9BOolfiHVdgRjbaVl5VSjtH21jd3UafEFK3H1atvZoNtXYV7xZ-cJSTrReCpS9_rdFvovZi8E8PWJKwPUzKlbkPEQjkkbQcQeKz0hk/s400/06.png" width="400" /></a></div>
<br />
El <b>código XAML</b> de esta página se muestra a continuación. Básicamente es un formulario con varios controles <b>Entry, Label y DatePicker</b>, pero observa que algunos de ellos definen uno o varios <b>Behavior</b>. Debes agregar el espacio de nombre que referencia la carpeta Behaviors (lo identificamos como <b>local</b> en el XAML) para que puedan ser localizados.<br />
<br />
<br />
<br />
<pre class="brush:xml;first-line:1"><?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Validaciones.Paginas.Formulario"
xmlns:local="clr-namespace:Validaciones.Behaviors">
<StackLayout BackgroundColor="White">
<Label HorizontalTextAlignment="Center" Text="Formulario" FontAttributes="Bold" TextColor="Blue" />
<Label Text="Nombre: " TextColor="Blue"/>
<Entry x:Name="txtNombre" Placeholder="Ingresa tu nombre" TextColor="Black"/>
<Label Text="Telefono: " TextColor="Blue"/>
<Entry x:Name="txtTelefono" Placeholder="Ingresa tu telefono (máximo 10 dígitos)" TextColor="Black" Keyboard="Numeric" >
<Entry.Behaviors>
<local:MaxLengthValidatorBehavior MaxLength="10"/>
<local:NumeroValidatorBehavior/>
</Entry.Behaviors>
</Entry>
<Label Text="Fecha de nacimiento: " TextColor="Blue"/>
<DatePicker x:Name="dtpFechaNacimiento">
<DatePicker.Behaviors>
<local:FechaValidatorBehavior/>
</DatePicker.Behaviors>
</DatePicker>
<Label Text="Correo: " TextColor="Blue"/>
<Entry x:Name="txtCorreo" Placeholder="Ingresa tu correo" TextColor="Black" >
<Entry.Behaviors>
<local:EmailValidatorBehavior/>
</Entry.Behaviors>
</Entry>
<Label Text="Password: " TextColor="Blue"/>
<Entry x:Name="txtPassword" IsPassword="True" Placeholder="Ingresa tu contraseña">
<Entry.Behaviors>
<local:PasswordValidatorBehavior />
<local:CompareTextsValidatorBehavior BindingContext="{x:Reference txtConfirmaPassword}" Text="{Binding Text}" Ent="{x:Reference txtConfirmaPassword}"/>
</Entry.Behaviors>
</Entry>
<Label Text="Repite tu password: " TextColor="Blue"/>
<Entry x:Name="txtConfirmaPassword" IsPassword="True" Placeholder="Repite tu contraseña">
<Entry.Behaviors>
<local:PasswordValidatorBehavior />
<local:CompareTextsValidatorBehavior BindingContext="{x:Reference txtPassword}" Text="{Binding Text}"/>
</Entry.Behaviors>
</Entry>
<Label Text="Fecha de inicio:" TextColor="Blue"/>
<DatePicker x:Name="dtpFechaInicio">
<DatePicker.Behaviors>
<local:CompareDatesValidatorBehavior BindingContext="{x:Reference dtpFechaFin}" Date="{Binding Date}" Order="1" DatePick="{x:Reference dtpFechaFin}" />
</DatePicker.Behaviors>
</DatePicker>
<Label Text="Fecha de fin: " TextColor="Blue"/>
<DatePicker x:Name="dtpFechaFin">
<DatePicker.Behaviors>
<local:CompareDatesValidatorBehavior BindingContext="{x:Reference dtpFechaInicio}" Date="{Binding Date}" Order="2" DatePick="{x:Reference dtpFechaInicio}" />
</DatePicker.Behaviors>
</DatePicker>
</StackLayout>
</ContentPage></pre>
<br />
<br />
<b>Paso 4.</b> ¡Listo! Ya solo tienes que indicar en tu archivo <b>App.cs </b>del proyecto de <b>Xamarin.Forms</b> que inicie la página <b>Formulario</b> para mostrar la página mediante el código siguiente:
<br />
<br />
<pre class="brush:csharp;first-line:1">public App()
{
MainPage = new Paginas.Formulario();
}
</pre>
<br />
Ahora solo resta ejecutar la aplicación. En primer lugar, observa cómo se visualiza en un teléfono con Windows 10:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI5suMLQxFXmgsl5hmRZ0gvE5f7TZe2kO_jIl9G9CUug-JMmQIPD8nksHCFNdykbfBEP2J8Mm0qcLJZOywJNV40qIbMiOqaa4o7CjU_F15S_Ac7fSwbCycTafPJKYzvHDIltZUXkm4680/s1600/07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI5suMLQxFXmgsl5hmRZ0gvE5f7TZe2kO_jIl9G9CUug-JMmQIPD8nksHCFNdykbfBEP2J8Mm0qcLJZOywJNV40qIbMiOqaa4o7CjU_F15S_Ac7fSwbCycTafPJKYzvHDIltZUXkm4680/s400/07.png" width="225" /></a></div>
<br />
<ul>
<li>El teléfono está limitado a 10 caracteres.</li>
<li>La fecha de nacimiento, como no es menor a la fecha actual, se pone en rojo.</li>
<li>El correo está en formato correcto.</li>
<li>La contraseña utilizada es password123, es decir, es inválida y por eso aparece en rojo.</li>
<li>Aunque la confirmación es la misma cadena, la contraseña no obedece al formato y por eso aparece en rojo.</li>
<li>La fecha de inicio es menor a la fecha de fin, por eso están en verde.</li>
</ul>
<br />
Ahora hagamos una prueba en un dispositivo Android:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuQJ4IeoS7C4jPIPMAa9LTdvVts5pE-qJCOU3m0PFPfx2fUlv82ZrYt3IZa1LM_9mD-8jihF2fwLiB_1iH4oTzpUjLaSj3Snhyphenhyphen8xYL8Nml-dnXlCpqFIu57r0IBMlWrjMry_f1DG0reQk/s1600/08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuQJ4IeoS7C4jPIPMAa9LTdvVts5pE-qJCOU3m0PFPfx2fUlv82ZrYt3IZa1LM_9mD-8jihF2fwLiB_1iH4oTzpUjLaSj3Snhyphenhyphen8xYL8Nml-dnXlCpqFIu57r0IBMlWrjMry_f1DG0reQk/s400/08.png" width="250" /></a></div>
<br />
<br />
<ul>
<li>El teléfono tiene un punto, es decir, un caracter que no es dígito, por tanto aparece en rojo.</li>
<li>La fecha de nacimiento es válida (menor a la fecha actual)</li>
<li>El correo electrónico no es válido</li>
<li>El password introducido es P@$$w0rd123, por tanto es válido.</li>
<li>La confirmación es la misma cadena, por tanto, válida</li>
<li>La fecha de fin es menor a la fecha de inicio, por tanto son no válidas.</li>
</ul>
<div>
<br /></div>
<div>
¡Listo! Como puedes ver, no es complicado utilizar <b>Behaviors </b>para añadir funcionalidad de validación a tus controles. Lo mejor de todo es que puedes reutilizarlos (simplemente llamándolos en el XAML) en otras páginas. Puedes crear tantos como gustes y un mismo control puede tener más de un Behavior enlazado (por ejemplo, el <b>Entry del teléfono </b>tiene los Behaviors <b>MaxLengthValidatorBehavior</b> y <b>NumeroValidatorBehavior</b>). Así mismo, la condición de validación tú mismo la defines.</div>
<div>
<br /></div>
<div>
El código fuente de este proyecto está disponible en mi <a href="https://github.com/icebeam7/Validaciones" target="_blank"><b>GitHub</b></a>. </div>
<div>
<br />
Ahora que has entendido cómo hacerlo y si quieres manejar algo más avanzado, por ejemplo que no se modifique el color de fondo sino que se muestre un mensaje de error para el usuario o hacer una interfaz de usuario más atractiva a la vista, te sugiero revisar <a href="https://blog.xamarin.com/behaviors-in-xamarin-forms/" target="_blank"><b>este enlace</b></a> del blog oficial de Xamarin, el cual también implementa Behaviors.<br />
<br /></div>
<div>
Espero que esta entrada haya sido de tu interés. Compártela con tus amigos si así fue, y espero te sea útil en tus desarrollos.<br />
<br />
¡Saludos!</div>
Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com7tag:blogger.com,1999:blog-8407795827837136717.post-7176797007616158432017-03-24T03:54:00.002-07:002017-03-24T05:12:20.797-07:00Xamarin Diplomado Latinoamérica 3.0¡Hola! Les traigo una excelente noticia. El día de ayer durante el <a href="https://www.facebook.com/MicrosoftDevelopersMX/videos/802634749894404/" target="_blank">Facebook Live</a> de Microsoft México se anunció una nueva versión del #XamarinDiplomado: <b>Xamarin Diplomado Latinoamérica 3.0</b>, el cual abarcará desde los temas básicos (instalación de herramientas) hasta temas más avanzados, con nuevos speakers y sorpresas.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5KElG9BkXl-z38n-BIG4RTn2doEhszWkPkKNkAcX66gpIETGvaWuK6lZ7UEE5CFu5RZLMKXmjExJgHcNmLZNKDMWdGlD9ffvw6LylNXt6xH3jLPt4jhOcJwyRjDmqb0Z9VfSfkid7YGQ/s1600/lg.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="268" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5KElG9BkXl-z38n-BIG4RTn2doEhszWkPkKNkAcX66gpIETGvaWuK6lZ7UEE5CFu5RZLMKXmjExJgHcNmLZNKDMWdGlD9ffvw6LylNXt6xH3jLPt4jhOcJwyRjDmqb0Z9VfSfkid7YGQ/s320/lg.jpg" width="320" /></a></div>
<br />
<br />
De momento no se ha dado más información sobre la fecha de inicio y los temas específicos del diplomado, pero ya te puedes registrar, dando clic en el siguiente enlace:<br />
<br />
<a href="http://bit.ly/diplomadoxamarin" target="_blank">http://bit.ly/diplomadoxamarin</a><br />
<br />
En el momento en que se dé más información al respecto del diplomado, se los haré saber en este blog. Por lo pronto, <b>aparta tu lugar e inscríbete.</b> Créeme, valdrá la pena :)<br />
<br />
<a name='more'></a><br />
Recuerda que el diplomado es gratuito, en línea (se tiene un aula virtual disponible las 24 horas del día los 7 días de la semana, es decir, tú decides cuándo acceder a los recursos, videos, laboratorios, PDFs, etc) y que aprenderás muchas cosas nuevas sobre Xamarin, una herramienta que te permite desarrollar aplicaciones móviles multiplataforma que se pueden ejecutar en Android, iOS y Windows 10. Si ya tomaste los diplomados anteriores, continúa con tu formación en esta nueva versión del curso; y si no has comenzado con Xamarin pero te interesa aprender, pues esta es una excelente oportunidad para hacerlo, dado que el curso comenzará desde lo básico. Y en español.<br />
<br />
Otra de las ventajas es que los instructores son expertos en Xamarin. En diplomados anteriores se ha contado con la presencia de Xamarin MVPs y Microsoft MVPs de Latinoamérica, lo cual quiere decir que el conocimiento que se comparte en los diplomados es de excelente calidad y utilidad.<br />
<br />
Nos vemos en el diplomado, no sin antes recordarte que tenemos un <b>grupo de estudio en Facebook</b>, donde nos apoyamos resolviendo dudas, compartimos noticias de Xamarin y en general la comunidad de desarrolladores Xamarin en Latinoamérica (y España y otros países) ha llevado un buen ambiente en el grupo. Solicita tu acceso dando clic en el siguiente enlace: <a href="http://bit.ly/xamarinitc" target="_blank">http://bit.ly/xamarinitc</a><br />
<br />
Y si eres mexicano, no dudes en participar en el <b>Xamarin Championship</b>, que es un concurso en el que se busca encontrar al mejor desarrollador Xamarin del país al resolver 2 retos mensuales, con interesantes premios para los ganadores. Para más información, consulta el siguiente enlace <a href="http://bit.ly/XamarinChampionship" target="_blank">http://bit.ly/XamarinChampionship</a><br />
<br />
¡Saludos!Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com14tag:blogger.com,1999:blog-8407795827837136717.post-19602988347524783482017-03-10T09:37:00.000-08:002017-03-10T09:51:28.094-08:00Xamarin Fest Celaya¡Hola! Además del <a href="https://ti.to/xamarin/dev-days-celaya-2017/en" target="_blank">Xamarin Dev Days Celaya</a> del cual te hablé en la <a href="http://icebeamwp.blogspot.cz/2017/03/invitacion-al-xamarindevdays-celaya-20.html" target="_blank">anterior entrada</a>, te invitamos a otro evento que estamos organizando en el mes de Mayo en el <a href="http://itcelaya.edu.mx/" target="_blank">Instituto Tecnológico de Celaya</a>, el <b><a href="https://xamarinfestlatam.azurewebsites.net/" target="_blank">Xamarin Fest Latam</a></b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq8m4KutgX2pkkiz2JZywpBdCf-O024mohf-sl7UPTobCjrg-aB_dzBw0fXFqjTuD1BX0RLfgEIo4O0IvvknM1zMl7wHkAWMG48wd4jCHlwZNcOqvw1BpIoZAkrCf_rJHwMz6i7doJEwc/s1600/xf.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="110" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq8m4KutgX2pkkiz2JZywpBdCf-O024mohf-sl7UPTobCjrg-aB_dzBw0fXFqjTuD1BX0RLfgEIo4O0IvvknM1zMl7wHkAWMG48wd4jCHlwZNcOqvw1BpIoZAkrCf_rJHwMz6i7doJEwc/s400/xf.png" width="400" /></a></div>
<br />
<br />
Citando del sitio oficial:<br />
<br />
<blockquote class="tr_bq">
Xamarin Fest es una iniciativa de capacitación para Latinoamérica que te permitirán tener el conocimiento para desarrollar y desplegar aplicaciones móviles desde cualquier plataforma con Xamarin, conectarlas con todo el poder que te trae la nube y realizar tus propios proyectos en nuestros talleres prácticos utilizando algunas de las tecnologías más innovadoras del momento.</blockquote>
<br />
<a name='more'></a><br />
<br />
Así, el próximo <b>25 de Mayo </b>de <b>10 am a 2 pm </b>tendrá lugar el <b>Xamarin Fest Celaya </b>en el <b><a href="https://goo.gl/maps/DPfBavBMKVu" target="_blank">Campus II del Instituto Tecnológico de Celaya</a></b>. Dado que el cupo es limitado, regístrate y aparta tu lugar llenando el formulario que aparece en el <a href="https://www.microsoftevents.com/profile/form/index.cfm?PKformID=0x15938547fc4" target="_blank"><b>siguiente enlace</b></a>. La entrada es gratuita y libre 😊<br />
<br />
El tema central del evento es <b>Cognitive Services y Xamarin</b> y la agenda propuesta es la siguiente:<br />
<br />
10:00 - 10:30 Registro<br />
10:30 - 11:00 Introducción a Xamarin<br />
11:00 - 11:50 Servicios Cognitivos y Xamarin<br />
11:50 - 12:00 Descanso<br />
12:00 - 14:00 Taller (Hands-on-Labs)<br />
<br />
Como puedes ver, habrá sesiones teóricas y prácticas, por lo que si quieres aprovechar al máximo la sesión, se recomienda que traigas tu equipo de cómputo con Xamarin instalado. <a href="https://msmdotnet.wordpress.com/2016/10/19/hello-xamarin-hands-on-lab/" target="_blank">Aquí</a> tienes una guía de instalación que te puede servir. Además, en una próxima entrada publicaré una guía de instalación de Xamarin con la última versión disponible a través de <b>Visual Studio 2017 Community</b>, el cual es gratuito.<br />
<br />
Me complace anunciar también que en el Xamarin Fest Celaya contaremos con la participación de <b><a href="https://twitter.com/EnriqueAguilar" target="_blank">Enrique Aguilar</a></b>, distinguido <b>Microsoft MVP</b>, <b>Xamarin MVP</b> y Director de la Facultad de T.I. en la Universidad De La Salle Bajío, quien con mucho gusto nos compartirá sus conocimientos y expertiz en <b>Xamarin y Servicios Cognitivos</b>, un tema muy interesante<b>.</b> Además de haber participado en diversos eventos de Xamarin en Latinoamérica (México, Colombia y más países), él es uno de los instructores de los <b>Diplomados de Xamarin Latinoamérica Niveles Básico e Intermedio</b>. En pocas palabras, contaremos con un experto reconocido internacionalmente en este evento, así que aprovechemos sus conocimientos 😃 Más que todo ello, destaco su humildad y quiero comentarles que cuando le pregunté si deseaba apoyarnos con el evento de Xamarin en el ITC; su respuesta fue inmediata y rotunda: SI, por lo que estamos muy agradecidos con su participación, profesor =)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj86oQyFpc3crb3J7U-HokZfokiIJHcZF-bshe33He1Z7blkR530XUUHOQDQKjeDLOOmZOBhoFrNvcYVW_y_TxpWxKpoZ0bUHPUE_VjGk6yPEOL7a6hwm6zBrU7hIlfmvjE94tGzQXrz1U/s1600/xf2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj86oQyFpc3crb3J7U-HokZfokiIJHcZF-bshe33He1Z7blkR530XUUHOQDQKjeDLOOmZOBhoFrNvcYVW_y_TxpWxKpoZ0bUHPUE_VjGk6yPEOL7a6hwm6zBrU7hIlfmvjE94tGzQXrz1U/s320/xf2.jpg" width="320" /></a></div>
<br />
Y también contaremos con la participación de otro <b>Microsoft MVP</b>, en este caso, <a href="https://twitter.com/darkicebeam" target="_blank">su servidor</a> 😏. En mi caso, apoyaré con los temas de <b>Introducción a Xamarin</b> y el <b>Hands-On-Labs</b>, Los que me conocen, ya saben que me apasiona dirigir sesiones prácticas y que con mucho gusto estaré también apoyando a los asistentes con las sesiones de Xamarin. Actualmente no estoy en México, sino en República Checa estudiando un doctorado, pero con mucho gusto estaremos ahí (si todo sale bien) para participar con los eventos del ITC.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4Qtc78apfbLnd98Fo0v5jpAsoQDlN0QarBxXLxZ2qKZ0z_c9gsNGCA1wf0_EO7uDdP9BtIjhz-c5SXPrm8ovmlfO_1eAeP9UFYReMfEMYdZnTAMGK3Tmtj755mdX137RSuEz0fZ8hOrU/s1600/xf3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4Qtc78apfbLnd98Fo0v5jpAsoQDlN0QarBxXLxZ2qKZ0z_c9gsNGCA1wf0_EO7uDdP9BtIjhz-c5SXPrm8ovmlfO_1eAeP9UFYReMfEMYdZnTAMGK3Tmtj755mdX137RSuEz0fZ8hOrU/s320/xf3.jpg" width="320" /></a></div>
<br />
Y también te invito a que seas parte de nuestro <b><a href="https://www.meetup.com/CelayaMobileDevelopers/" target="_blank">Meetup de Desarrolladores Móviles Xamarin de Celaya</a></b>, donde podrás conocer a otros expertos, entusiastas y profesionales relacionados con la programación de aplicaciones móviles en Xamarin.<br />
<br />
Ayúdanos a difundir esta entrada incluyendo los hashtags #XamarinFest y #XamarinFestCelaya. Y si piensas asistir al evento, compártenos un tweet. Nos dará mucho gusto saber que contaremos con tu presencia =)<br />
<br />
<br />
<blockquote class="twitter-tweet" data-lang="en">
<div dir="ltr" lang="es">
<a href="https://twitter.com/hashtag/XamarinFest?src=hash">#XamarinFest</a> ¿Me acompañas al <a href="https://twitter.com/hashtag/XamarinFestCelaya?src=hash">#XamarinFestCelaya</a>?Registro <a href="https://t.co/TLZEWuMxAB">https://t.co/TLZEWuMxAB</a> Tema Servicios cognitivos,más info <a href="https://t.co/hB8muJwXiJ">https://t.co/hB8muJwXiJ</a></div>
— Luis Beltran (@darkicebeam) <a href="https://twitter.com/darkicebeam/status/840255142423330816">March 10, 2017</a></blockquote>
<script async="" charset="utf-8" src="//platform.twitter.com/widgets.js"></script>
#XamarinFest ¿Me acompañas al #XamarinFestCelaya?Registro https://www.microsoftevents.com/profile/form/index.cfm?PKformID=0x15938547fc4 Tema Servicios cognitivos,más info http://icebeamwp.blogspot.com/2017/03/xamarin-fest-celaya.html<br />
<br />
<b>¡Te esperamos!</b><br />
<br />
Nos vemos en Mayo, muy pronto...<br />
<br />
Saludos,<br />
-LuisLuis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com0tag:blogger.com,1999:blog-8407795827837136717.post-4203668628559350952017-03-03T12:48:00.000-08:002017-03-03T13:13:35.045-08:00¡Invitación al #XamarinDevDays Celaya 2.0!¡Hola! Estoy muy emocionado por compartirles esta noticia y es que hoy se ha anunciado el primer bloque de ciudades aceptadas para organizar un <b>Xamarin Dev Day...</b> <b>¡y Celaya está presente nuevamente en este evento internacional! 👍 </b>El anuncio oficial con las ciudades que organizarán un evento de Xamarin este año está disponible en el <a href="https://blog.xamarin.com/xamarin-dev-days-are-coming-to-your-city/" target="_blank">siguiente enlace</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBafTC8lohs0qTnO6ETP0fVnmw_x2uLhj5wIblGJU9-4xq4hqgBuFOPbf5oXpXbqWJiQj6gxczJO34iQzq2KWnB7anknMiJLta14BYm6jssK1HLUPr-AZ5bDyR_1U6dZFYyyrCvD9xvlU/s1600/xd4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBafTC8lohs0qTnO6ETP0fVnmw_x2uLhj5wIblGJU9-4xq4hqgBuFOPbf5oXpXbqWJiQj6gxczJO34iQzq2KWnB7anknMiJLta14BYm6jssK1HLUPr-AZ5bDyR_1U6dZFYyyrCvD9xvlU/s400/xd4.png" width="400" /></a></div>
<br />
<span style="text-align: center;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggnbC_Ph3VhDsRSByL4NoYAzP_Vq4MN5Cd04WZ5K_U-W5EMM-Ni3GM_vZ0OUtxIovYgWfXZaPx3j2x9DQF9QALvbnTCtCv1en3r_eNJEIplPJZUNzKSpazGaKnyPb7OVLFI8HO-OR372s/s1600/xd3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="135" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggnbC_Ph3VhDsRSByL4NoYAzP_Vq4MN5Cd04WZ5K_U-W5EMM-Ni3GM_vZ0OUtxIovYgWfXZaPx3j2x9DQF9QALvbnTCtCv1en3r_eNJEIplPJZUNzKSpazGaKnyPb7OVLFI8HO-OR372s/s400/xd3.png" width="400" /></a></div>
<span style="text-align: center;"><br /></span>
<span style="text-align: center;"><br /></span>
<span style="text-align: center;">Así es, me complace anunciar que en el </span><a href="http://itcelaya.edu.mx/" style="text-align: center;" target="_blank">Instituto Tecnológico de Celaya</a><span style="text-align: center;"> organizaremos de nueva cuenta un evento oficial de Xamarin el próximo </span><b style="text-align: center;">Sábado 27 de Mayo </b><span style="text-align: center;">en el </span><a href="https://goo.gl/maps/DPfBavBMKVu" style="text-align: center;" target="_blank">Campus II</a><b style="text-align: center;">.</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrvNIfQO5Yoe4hkhtXb_TswimnDlK_aP1o3NOxkKzK2L4nLv_8dLzyN2uKYzw5FeHTnhb_4GPIEY4KupSpvx7zG-W0kHw3gaJtVHa4hS-uNR5_8YUVn4qp_-HjucXuPVGd90J0Eitpqdk/s1600/xd5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="113" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrvNIfQO5Yoe4hkhtXb_TswimnDlK_aP1o3NOxkKzK2L4nLv_8dLzyN2uKYzw5FeHTnhb_4GPIEY4KupSpvx7zG-W0kHw3gaJtVHa4hS-uNR5_8YUVn4qp_-HjucXuPVGd90J0Eitpqdk/s400/xd5.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<b><a href="https://ti.to/xamarin/dev-days-celaya-2017" target="_blank">Regístrate en este enlace</a> </b>para apartar tu lugar en el segundo <b>Xamarin Dev Days Celaya</b>, pues los cupos son limitados ;) Al registrarte, obtendrás un ticket que incluye un código QR (o puede ser que lo revibas en tu correo). El día del evento asiste con tu ticket (en digital o impreso) para que podamos registrar tu asistencia. Hablaremos de temas interesantes como los Servicios Cognitivos, Azure, códigos QR y muchos más temas. No dejes pasar esta oportunidad de capacitarte gratuitamente en una de las tecnologías por las que Microsoft está apostando fuertemente para ofrecer a los desarrolladores de aplicaciones móviles una plataforma sólida y funcional.<br />
<br />
<br />
<a name='more'></a><br /><br />
<br />
Y por cierto, ¿qué es un Xamarin Dev Day? Pues es un evento <b>gratuito </b>en el que <b>expertos </b><b>de tu comunidad </b>comparten sus conocimientos, te explican temas interesantes, te muestran proyectos en los que de primera mano puedes aprender cómo desarrollar aplicaciones móviles multiplataforma mediante esta tecnología. ¡Podrás desarrollar aplicaciones móviles que funcionan en Android, iOS, Windows 10 y Windows Phone!<br />
<br />
Un Xamarin Dev Day se compone típicamente de 3 sesiones de aprendizaje y un laboratorio (Hands-On-Labs) con los siguientes temas iniciales (pero pueden cambiar) en un horario de 9 am a 4 pm. En el laboratorio todos desarrollamos una aplicación móvil que podemos probar en nuestro teléfono o emulador.<br />
<br />
<ul>
<li>Introducción a Xamarin</li>
<li>Xamarin.Forms</li>
<li>Xamarin y Azure</li>
<li>¡Lunch gratuito!</li>
<li>Hands-on-Labs: Xamarin + Azure + Cognitive Services</li>
</ul>
<br />
Revisa <a href="https://www.xamarin.com/dev-days" target="_blank">el sitio oficial</a> para más información.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtHiSsdCtwd23vB44Uu7w9coPZTlvpKIfRt77nch1oO3OPIUSR73rrQNK8vwvZKFAdCzzG2SKnfgFWktexgCO9MHEuWC7bacghIUhSOkvVFwhT1vFFqidLlw_o4PCQDoB3TVq5YpGHknc/s1600/xd6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="281" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtHiSsdCtwd23vB44Uu7w9coPZTlvpKIfRt77nch1oO3OPIUSR73rrQNK8vwvZKFAdCzzG2SKnfgFWktexgCO9MHEuWC7bacghIUhSOkvVFwhT1vFFqidLlw_o4PCQDoB3TVq5YpGHknc/s400/xd6.png" width="400" /></a></div>
<br />
Comentamos que es la segunda ocasión que organizamos este evento, pues el 10 de Diciembre de 2016 tuvimos el gusto de organizar nuestro primer evento oficial de la comunidad y de Xamarin. El evento tuvo buena recepción entre la comunidad, varios alumnos, egresados y profesionistas pudieron aprender sobre esta interesante tecnología... y también hubo tacos 😜 (en lo personal me dio mucho gusto haber visto nuevamente a varios de mis compañeros y alumnos después de 2 años jeje). Puedes ver algunas fotografías (tweets) aquí :) <a href="https://twitter.com/darkicebeam/status/807607696769908736" target="_blank">1</a>, <a href="https://twitter.com/darkicebeam/status/807617300077707264" target="_blank">2</a>, <a href="https://twitter.com/darkicebeam/status/807618220366643200" target="_blank">3</a>, <a href="https://twitter.com/darkicebeam/status/807625642476978176" target="_blank">4</a>, <a href="https://twitter.com/darkicebeam/status/807630089970208769" target="_blank">5</a>, <a href="https://twitter.com/darkicebeam/status/807667322987155456" target="_blank">6</a>, <a href="https://twitter.com/darkicebeam/status/807695636325892096" target="_blank">7</a>, <a href="https://twitter.com/EdgarKmarita/status/807681276136345601" target="_blank">8</a>, <a href="https://twitter.com/darkicebeam/status/807636446492459009" target="_blank">Maambo</a> (jaja, ok no) y esta también <a href="https://twitter.com/darkicebeam/status/807651734072020993" target="_blank">9</a>.<br />
<br />
Esto fue lo que tratamos en el evento anterior:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY-_1dNH_qxn89PpOOnpDqgPvvMUATNWUmcANN4Db6qi5rfRRZd1q6lb0BylnFQzXZv7Ey6sgvyKywXAY7w2MzUg20PpBFHIkefgiAjS_GK5XKLyEx5jKwEl9yXUPHN-AxbVhIFLO4kuk/s1600/xdd2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="312" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY-_1dNH_qxn89PpOOnpDqgPvvMUATNWUmcANN4Db6qi5rfRRZd1q6lb0BylnFQzXZv7Ey6sgvyKywXAY7w2MzUg20PpBFHIkefgiAjS_GK5XKLyEx5jKwEl9yXUPHN-AxbVhIFLO4kuk/s320/xdd2.png" width="320" /></a></div>
<br />
<br />
¿Tienes alguna duda o sugerencia? ¿Asististe al anterior DevDay y tienes alguna recomendación? ¿Qué temas te interesaría que tratáramos? Por favor déjanos un comentario. Tu opinión es muy valiosa para que este evento (que es tuyo, por tí y para tí) sea una experiencia de aprendizaje agradable.<br />
<br />
No olvides que para la sesión práctica se recomienda que lleves Xamarin instalado en tu computadora. <a href="https://msmdotnet.wordpress.com/2016/10/19/hello-xamarin-hands-on-lab/" target="_blank">Aquí </a>tienes una guía de instalación que te puede servir.<br />
<br />
Y también te invito a que seas parte de nuestro <b><a href="https://www.meetup.com/CelayaMobileDevelopers/" target="_blank">Meetup de Desarrolladores Móviles Xamarin de Celaya</a></b>, donde podrás conocer a otros expertos, entusiastas y profesionales relacionados con la programación de aplicaciones móviles en Xamarin.<br />
<br />
Ayúdanos a difundir esta entrada incluyendo los hashtags #XamarinDevDays y #XamarinDevDaysCelaya2. Y si piensas asistir al evento, compártenos un tweet. Nos dará mucho gusto saber que contaremos con tu presencia =)<br />
<br />
<blockquote class="twitter-tweet" data-lang="en">
<div dir="ltr" lang="es">
<a href="https://twitter.com/hashtag/XamarinDevDays?src=hash">#XamarinDevDays</a> ¿Me acompañas al <a href="https://twitter.com/hashtag/XamarinDevDaysCelaya2?src=hash">#XamarinDevDaysCelaya2</a>? Regístrate en <a href="https://t.co/qMtQHjv1sa">https://t.co/qMtQHjv1sa</a> Más información en <a href="https://t.co/RJrS8wJjwc">https://t.co/RJrS8wJjwc</a></div>
— Luis Beltran (@darkicebeam) <a href="https://twitter.com/darkicebeam/status/837766883474538500">March 3, 2017</a></blockquote>
<script async="" charset="utf-8" src="//platform.twitter.com/widgets.js"></script>
#XamarinDevDays ¿Me acompañas al #XamarinDevDaysCelaya2? Regístrate en https://ti.to/xamarin/dev-days-celaya-2017 Más información en http://icebeamwp.blogspot.com/2017/03/invitacion-al-xamarindevdays-celaya-20.html<br />
<br />
<b>¡Te esperamos! 😃</b><br />
<b><br /></b>
Nos vemos en Mayo, muy pronto...<br />
<br />
Saludos,<br />
-LuisLuis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com0tag:blogger.com,1999:blog-8407795827837136717.post-69370158726789400022017-02-17T03:41:00.000-08:002017-03-25T10:36:40.383-07:00ZXing.Net.Mobile for Forms, una librería para escanear códigos de barras, QRs y más¡Hola! En la entrada de esta semana te hablaré acerca de <a href="https://components.xamarin.com/view/zxing.net.mobile.forms" target="_blank">ZXing.Net.Mobile for Forms</a>, el cual es una librería basada en otra librería de código abierto para escanear códigos de barras llamada ZXing (Zebra Crossing) y que hace uso del ZXing.Net.Port.<br />
<br />
Esta librería funciona para diversos proyectos .NET, incluyendo por supuesto, Xamarin (Forms, Android, iOS, Windows Phone, UWP...) y reduce el esfuerzo para implementar un scanner de códigos de barras, QRs y más en nuestros proyectos multiplataforma.<br />
<br />
¡A continuación te explico qué fácil es utilizar esta librería!<br />
<br />
<b>Paso 1</b>. Crea un proyecto de tipo <b>Xamarin.Forms Portable</b>. Para este caso, he puesto el nombre <b>ScannerZXing</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZP2lvpubYScDMftloSBwVu3SEwHn1ipcr_XaC7c2e-islA0z6ERZDe6HWJEU2V0rDVWakihQG2lWFDcKdtaKDfA9NK6ma9hZum9wuuMiRQIzgjm0VHlz0UwNdRkUIo9K8YVs8neYVHcI/s1600/01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="243" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZP2lvpubYScDMftloSBwVu3SEwHn1ipcr_XaC7c2e-islA0z6ERZDe6HWJEU2V0rDVWakihQG2lWFDcKdtaKDfA9NK6ma9hZum9wuuMiRQIzgjm0VHlz0UwNdRkUIo9K8YVs8neYVHcI/s400/01.png" width="400" /></a></div>
<br />
<b>Paso 2</b>. Da clic derecho en la solución y elige <b>Administrar Paquetes Nuget para la Solución</b><br />
<br />
<a name='more'></a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0wW2_N-J1MXc7J4tn1kL9Vf9gKSxRbfF8ct8qBVIUQnvsTI-6a1Tu8i_yqHEgmUoODign_kr7ElsSXMcS6ZGqW1mFTVu4xflB6EzSCwt7BofA1RgYEv9PlKWu6q01raKghSFO7ClPhLs/s1600/02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0wW2_N-J1MXc7J4tn1kL9Vf9gKSxRbfF8ct8qBVIUQnvsTI-6a1Tu8i_yqHEgmUoODign_kr7ElsSXMcS6ZGqW1mFTVu4xflB6EzSCwt7BofA1RgYEv9PlKWu6q01raKghSFO7ClPhLs/s400/02.png" width="373" /></a></div>
<br />
<b>Paso 3</b>. Busca el paquete <b>ZXing.Net.Mobile.Forms</b> y agrégalo a todos los proyectos de tu solución que vayas a manejar.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhP4m23lKfv1r9M-0uiLhRlKXXupWnQY5XHlQw9nRL-aFL_SsqZVcsTg0GKV-Wp2Yrf_RuhnI7qAQHH0Jpdoj2UjF7QT1f2W65IVfMzrbW1azFL-zRKDuMGKWyNj6PGZKUafLtBv-GFpvU/s1600/03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhP4m23lKfv1r9M-0uiLhRlKXXupWnQY5XHlQw9nRL-aFL_SsqZVcsTg0GKV-Wp2Yrf_RuhnI7qAQHH0Jpdoj2UjF7QT1f2W65IVfMzrbW1azFL-zRKDuMGKWyNj6PGZKUafLtBv-GFpvU/s400/03.png" width="400" /></a></div>
<br />
<b>Paso 4. </b>Debes inicializar el renderer de plataforma específica en cada proyecto donde hayas agregado el paquete. Siempre será después del <b>Init </b>de <b>Xamarin.Forms</b> y la instrucción a colocar es <b>ZXing.Net.Mobile.Forms.<i>Plataforma</i>.Platform.Init();</b> donde <i>Plataforma</i> es reemplazado por <b>Android </b>o<b> iOS</b>, según el caso.<br />
<br />
Por ejemplo, para <b>Android </b>debes agregar dicha instrucción en el <b>MainActivity</b>; en el caso de <b>iOS</b>, es en <b>AppDelegate</b>:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyqgqkXoe5qb4puI6UGnBBNdj6HthtzJ-dWVodHh30oJ6KV5Ep0VEn5Ww7OX_7Ku1TPHRAxEh3u2aFsUgB7Z8JLByLRB2h1YSbHMOfSMIz8isKSCXVxm7NcNx_1OtzQTZ7Sig7Rn_69ZQ/s1600/07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyqgqkXoe5qb4puI6UGnBBNdj6HthtzJ-dWVodHh30oJ6KV5Ep0VEn5Ww7OX_7Ku1TPHRAxEh3u2aFsUgB7Z8JLByLRB2h1YSbHMOfSMIz8isKSCXVxm7NcNx_1OtzQTZ7Sig7Rn_69ZQ/s400/07.png" width="400" /></a></div>
<br />
<b>Nota. En el caso de Android</b>, además debes sobreescribir método <b>OnRequestPermissionsResult</b> debido a la actualización del manejo de permisos desde <b>Android Marshmallow</b>:<br />
<br />
<pre class="brush:csharp;first-line:1">public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
global::ZXing.Net.Mobile.Forms.Android.PermissionsHandler.OnRequestPermissionsResult (requestCode, permissions, grantResults);
}
</pre>
<br />
Para <b>UWP</b> y <b>Windows Phone</b>, busca el archivo <b>App.xaml.cs</b> de cada plataforma específica y agrega la instrucción <b>ZXing.Net.Mobile.Forms.<i>Plataforma</i>.ZXingScannerViewRenderer.Init();</b> para inicializar los renderers, donde <i>Plataforma</i> es reemplazada por <b>WindowsUniversal</b> y <b>WindowsPhone</b>, respectivamente:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkpAxddVOow01124M4b4_kGiX9ZFzpVQcOwTifKiEuI96nsCKEWV4ctUYSHCVBmPy7FmQt2bus9qULa6R-7KgjP43sP6De5ZBZgaF6VVERoXwqL3Ri1xdtO9nv1jDMRFpSwbeL6EBKvXo/s1600/08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="291" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkpAxddVOow01124M4b4_kGiX9ZFzpVQcOwTifKiEuI96nsCKEWV4ctUYSHCVBmPy7FmQt2bus9qULa6R-7KgjP43sP6De5ZBZgaF6VVERoXwqL3Ri1xdtO9nv1jDMRFpSwbeL6EBKvXo/s400/08.png" width="400" /></a></div>
<br />
<b>Paso 5. </b>En el proyecto Portable crea una carpeta llamada <b>Paginas</b>, dentro de la cual agregarás un <b>Forms Xaml Page.</b> En este caso, le he puesto el nombre <b>PaginaMenu</b>:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikbFo2WOqrUfMEJFrCL5r1a81FqtH48ynaRp_ajFzhmOezZCHJy1-3niKdizS5qCG6yC5Djb9ozw9YPCcJnAUHwzZoQgQ9yQGt3gOO_6nsZyAM6dYMOhGjnv3K5U1RhQ6jXYUYmEQVU2A/s1600/04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikbFo2WOqrUfMEJFrCL5r1a81FqtH48ynaRp_ajFzhmOezZCHJy1-3niKdizS5qCG6yC5Djb9ozw9YPCcJnAUHwzZoQgQ9yQGt3gOO_6nsZyAM6dYMOhGjnv3K5U1RhQ6jXYUYmEQVU2A/s400/04.png" width="400" /></a></div>
<br />
<b>Paso 6. </b>El código <b>XAML</b> de esta página es muy sencillo, pues simplemente consta de un <b>StackLayout</b> con 3 elementos: Un botón y 2 labels. A continuación te presento el código:<br />
<br />
<pre class="brush:xml;first-line:1"><?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ScannerZXing.Paginas.PaginaMenu">
<StackLayout BackgroundColor="White">
<Button Text="Escanear código" HorizontalOptions="CenterAndExpand"
TextColor="White" FontSize="20" BackgroundColor="Black" x:Name="btnEscanear" Clicked="btnEscanear_Clicked" />
<Label Text="Resultado" HorizontalOptions="StartAndExpand"
TextColor="Black" FontSize="20" />
<Label Text="N/A" HorizontalOptions="StartAndExpand"
TextColor="Blue" x:Name="lblResultado" FontSize="24" />
</StackLayout>
</ContentPage>
</pre>
<br />
La idea es que cuando el usuario presione el botón, se lance el scanner llamando a la aplicación de cámara que viene integrado en tu dispositivo.<br />
<br />
<b>Paso 7.</b> Ahora veamos el <i>code-behind</i>, es decir, el código de <b>C#</b> requerido para que la aplicación funcione como esperamos:<br />
<br />
<pre class="brush:csharp;first-line:1">using System;
using Xamarin.Forms;
using ZXing.Net.Mobile.Forms;
namespace ScannerZXing.Paginas
{
public partial class PaginaMenu : ContentPage
{
async void btnEscanear_Clicked(object sender, EventArgs e)
{
var pagina = new ZXingScannerPage();
await Navigation.PushAsync(pagina);
pagina.OnScanResult += (resultado) =>
{
pagina.IsScanning = false;
Device.BeginInvokeOnMainThread(async () =>
{
await Navigation.PopAsync();
lblResultado.Text = resultado.Text;
});
};
}
public PaginaMenu()
{
InitializeComponent();
}
}
}
</pre>
<br />
En el momento en que el usuario dé clic, se crea una página <b>ZXingScannerPage</b> y se muestra en el dispositivo (esto sucede al hacer <b>Push </b>al <b>Stack </b>de <b>Navegación</b>). Entonces, aparecerá una vista con la cámara a manera de scanner que tratará de leer un código de barras y en el momento en que la lectura sea exitosa, retornará a la página que llamó al scanner (<b>PaginaMenu</b> en este caso) y gracias a que manejamos el evento <b>OnScanResult</b>, podremos obtener el valor leído (a veces será una serie de números y letras, otras veces una URL o más información).<br />
<br />
<div>
<b>Paso 8.</b> En tu archivo <b>App.cs </b>del proyecto portable de <b>Xamarin.Forms</b> indica que <b>PaginaMenu</b> será la página inicial:</div>
<br />
<pre class="brush:csharp;first-line:1">public App()
{
MainPage = new NavigationPage(new Paginas.PaginaMenu());
}
</pre>
<br />
<b>Paso 9.</b> Si vas a hacer tu prueba con el proyecto de <b>Android</b>, tienes que agregar 2 permisos en el <b>AndroidManifest</b>: <b>Camera</b> y <b>Flashlight</b>. Desde Visual Studio, accede a las propiedades del proyecto de Android para habilitar ambos permisos:<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXQWZ9IXIy_6ck0Yqxt3EknA57P391GE352Z5xUtiWChJ-XQFSZQaMYGyYAlYd_cx-UQesKnyl2qIKkaZHUsOuJkWPeejiuU8wScxPdGhL5z9A4s7BzTB5nQdqp6hstak9QoKHaoqDgU4/s1600/09a.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXQWZ9IXIy_6ck0Yqxt3EknA57P391GE352Z5xUtiWChJ-XQFSZQaMYGyYAlYd_cx-UQesKnyl2qIKkaZHUsOuJkWPeejiuU8wScxPdGhL5z9A4s7BzTB5nQdqp6hstak9QoKHaoqDgU4/s400/09a.png" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipwShjraYTXkGGAFtn5aOmV-_denXlvhw7pLfTgTv7VhjtvYGLjRYtbY8EgWnzzmq_rWuG0tQYax4ZwspcstU2giN_xD0L9B-PclVpKlJB7HEr80oHGFZJ179I4p4eOBTkxAFs11fdtbI/s1600/10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipwShjraYTXkGGAFtn5aOmV-_denXlvhw7pLfTgTv7VhjtvYGLjRYtbY8EgWnzzmq_rWuG0tQYax4ZwspcstU2giN_xD0L9B-PclVpKlJB7HEr80oHGFZJ179I4p4eOBTkxAFs11fdtbI/s400/10.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b>Paso 10. </b>¿Eres de los pocos (pero orgullosos, como yo) poseedores de un dispositivo Windows 8.1/10 (jeje) para hacer tus pruebas? Entonces habilita la Capability <b>Webcam </b>en el <b>Package Manifest </b>(dentro de Properties en el proyecto de UWP o WP)<b> </b>para que la aplicación funcione correctamente:</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6U6qKhIyvug5USOekQDyibZT77UDQ9uG3ZEDCL_AWuml7665Ds3XEGOzp_vjl_Z2MG8eH2tVWB8uoJi3LfluKh9HrSbNDMLhcyYsFJYaBxTB2CUuFCoylm2k53cIPKVLObCfswHFQbjU/s1600/09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="230" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6U6qKhIyvug5USOekQDyibZT77UDQ9uG3ZEDCL_AWuml7665Ds3XEGOzp_vjl_Z2MG8eH2tVWB8uoJi3LfluKh9HrSbNDMLhcyYsFJYaBxTB2CUuFCoylm2k53cIPKVLObCfswHFQbjU/s400/09.png" width="400" /></a></div>
<br />
<b>Paso 11.</b> ¡Listo! Es hora de probar nuestra aplicación. A continuación va un ejemplo de su implementación en una tablet con Android y en un teléfono con Windows 10 (el iPhone, pendiente):<br />
<br />
<b>Ejemplo 1:</b> Esta es la pantalla inicial<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkIIgBpheU-mK-iz3n8OmcsjyOC5xRNaGo-iK_ucBxeI0piQjoAubD9b6ccx7MA4o7YqLJuH__OdKu6XFW8_8iSu3vQdc94RKZ3Hj0lVcvs3y-Iz9ex_mToeAhh6FBUalfOJftKuWaxMU/s1600/13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkIIgBpheU-mK-iz3n8OmcsjyOC5xRNaGo-iK_ucBxeI0piQjoAubD9b6ccx7MA4o7YqLJuH__OdKu6XFW8_8iSu3vQdc94RKZ3Hj0lVcvs3y-Iz9ex_mToeAhh6FBUalfOJftKuWaxMU/s400/13.png" width="250" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Si presionamos el botón <b>Escanear código</b>, aparecerá una pantalla con la cámara habilitada y lista para escanear algún código de barras, como en este caso. Alinea la línea roja aproximadamente al centro de tu codigo de barras:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_Si4RPJuWHCoGcR5tABxKpdSbYxL1ky6taA_aerIhaanX07KOPCRewvEnRQQLJzte6hpEhb66AqY6Kk375_mXTfdMR3ucPNtEdg-hvieLhlIAN2gcp6Avc382Isb3LqYZKr83Uc-sTEM/s1600/14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_Si4RPJuWHCoGcR5tABxKpdSbYxL1ky6taA_aerIhaanX07KOPCRewvEnRQQLJzte6hpEhb66AqY6Kk375_mXTfdMR3ucPNtEdg-hvieLhlIAN2gcp6Avc382Isb3LqYZKr83Uc-sTEM/s400/14.png" width="250" /></a></div>
<br />
¡Genial! ¡El código de barras respectivo ha sido leido y mostrado en nuestra etiqueta de texto!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsdxkGXChobQdUXs-Jbn-Dr6lJVUaK_GoldKuER55gmujKUkqoGAXxsLARsW8JSnZO5eejXvJi96q48TRyL2Hc8LpfAWnkX5GCy8ko6v7DcrfELGBGyNI2M-Lt3TWni-D_C4Zgo_wbNJY/s1600/15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsdxkGXChobQdUXs-Jbn-Dr6lJVUaK_GoldKuER55gmujKUkqoGAXxsLARsW8JSnZO5eejXvJi96q48TRyL2Hc8LpfAWnkX5GCy8ko6v7DcrfELGBGyNI2M-Lt3TWni-D_C4Zgo_wbNJY/s400/15.png" width="250" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<b>Ejemplo 2: </b>Ahora vamos a escanear un <b>código QR </b>de un boleto que tengo.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjk9UUmV1J__HjZUtqO_DtP-zKyviHz15yg7kj4QsCKuVZP4jkNOI8RqCVJJx3qf5XO_0busV045MyqUgOWNssvWuZLW35jOBctBKmKntA7TlkiOLz2wZnZyTdyhyphenhyphenrafnH2DxEV6faWKPU/s1600/16.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="250" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjk9UUmV1J__HjZUtqO_DtP-zKyviHz15yg7kj4QsCKuVZP4jkNOI8RqCVJJx3qf5XO_0busV045MyqUgOWNssvWuZLW35jOBctBKmKntA7TlkiOLz2wZnZyTdyhyphenhyphenrafnH2DxEV6faWKPU/s400/16.png" width="400" /></a></div>
<br />
El código ha sido leido exitosamente y su valor, retornado:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd-a4H6HWBFQCmILGbN34RyVlLbJ0vwsJsPsKwYNxSS4ahU4yqkQs4_z516IHahu5szMYM4LrVwS5cJ4kzTj7gTqUWE_37Y2iZxRC5X_pDlabOMOQpbLnmK3TueZGn6EHVS_vgEcQhBhc/s1600/17.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd-a4H6HWBFQCmILGbN34RyVlLbJ0vwsJsPsKwYNxSS4ahU4yqkQs4_z516IHahu5szMYM4LrVwS5cJ4kzTj7gTqUWE_37Y2iZxRC5X_pDlabOMOQpbLnmK3TueZGn6EHVS_vgEcQhBhc/s400/17.png" width="250" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b>Ejemplo 3: </b>Prueba en Windows 10. Primero, la pantalla inicial.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTTmUXTK044qeN18yh9eYmq2TFxamh3BNO2Nf8ER8_dnfADZCOIeewCzWC0KLta44wsketDXC3pTAPaH_tz8FznPfqVKm2flYgGErIDNOzNow0t0_O9uH-IhDo6Kw_kH5bygREBZkRwM4/s1600/18.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTTmUXTK044qeN18yh9eYmq2TFxamh3BNO2Nf8ER8_dnfADZCOIeewCzWC0KLta44wsketDXC3pTAPaH_tz8FznPfqVKm2flYgGErIDNOzNow0t0_O9uH-IhDo6Kw_kH5bygREBZkRwM4/s400/18.png" width="225" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Cuando damos clic en <b>Escanear código</b>, aparece la cámara lista para buscar algo qué leer.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2nYBtd_LrTg_Al3J3yE3cu6mBWP2kEuiu4M6Z-0IsLxD3qEXyLG_A_zCGaGUlRwm1gYN262HxfnJSaPO-kSxGsXiGdiHkRD2GucN8xRGjBl4sIu3oPhwaf1F5vtiCqVwQqSL_Jechly8/s1600/19.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2nYBtd_LrTg_Al3J3yE3cu6mBWP2kEuiu4M6Z-0IsLxD3qEXyLG_A_zCGaGUlRwm1gYN262HxfnJSaPO-kSxGsXiGdiHkRD2GucN8xRGjBl4sIu3oPhwaf1F5vtiCqVwQqSL_Jechly8/s400/19.png" width="225" /></a></div>
<br />
En este caso, nuevamente leimos un código QR, que devuelve una página web como su valor:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPHOpSSnaCmpCNeuXMcESbv1rqrKHLj_REo-bvXH0-5HlrsWl7AD8iwxbrth3jCMyIGDYCnsCgrSrkDP63aVnk5AHYKw0GUtS8cpU_JohjhkH5hXBvEcSaCRWKN63e35zvEb4-5IOnRg8/s1600/20.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPHOpSSnaCmpCNeuXMcESbv1rqrKHLj_REo-bvXH0-5HlrsWl7AD8iwxbrth3jCMyIGDYCnsCgrSrkDP63aVnk5AHYKw0GUtS8cpU_JohjhkH5hXBvEcSaCRWKN63e35zvEb4-5IOnRg8/s400/20.png" width="225" /></a></div>
<br />
<b>Ejemplo 4: </b>Ahora leeremos otro código de un boleto más, en este caso, uno de tren.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYgkri94dURPCSVVsY5kxtRTVCCRcF3QHFTyxswZJroVZhjhX8lnaDBiJN7HUUibebz5b5U0vFRBSIU9TAl5F37j5Ftz8TQdGxGjT_XSdgwFWMipgHr8WZ5ALQ51H6hsAWs1EKEt__8Qc/s1600/21.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYgkri94dURPCSVVsY5kxtRTVCCRcF3QHFTyxswZJroVZhjhX8lnaDBiJN7HUUibebz5b5U0vFRBSIU9TAl5F37j5Ftz8TQdGxGjT_XSdgwFWMipgHr8WZ5ALQ51H6hsAWs1EKEt__8Qc/s400/21.png" width="225" /></a></div>
<br />
El resultado es un poco extraño, pero válido. Supongo que la información está encriptada precisamente para seguridad y que no haya forma de generar <i>boletos falsos</i>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtKHPOy9uoGbh_yCESRUg09dzl_fsNqMuc2CBjtskH36gBqkID0vjaiaUuUWGx2n8XLAnTjomlTK50M_TGuihLJZeFgYowLE3aVHWZ3AMGeFUyMi2jRtyLcFQ9RCjzlkh9Yzk8mFM8pDo/s1600/22.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtKHPOy9uoGbh_yCESRUg09dzl_fsNqMuc2CBjtskH36gBqkID0vjaiaUuUWGx2n8XLAnTjomlTK50M_TGuihLJZeFgYowLE3aVHWZ3AMGeFUyMi2jRtyLcFQ9RCjzlkh9Yzk8mFM8pDo/s400/22.png" width="225" /></a></div>
<br />
<b>Ejemplo 5</b>. Finalmente, escaneamos un ticket del metro de Praga (como no tenía uno a la mano, uso uno de Internet).<br />
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH0s6zhiBgFqdb0Vy68-oYkjEE4aRy-6kv15rOBZBgM0KwES0ncDqWTguwiTTwHktXpHcJ46uZooqE5M97idsMSQ4p85rGXeJRs93dhbbuk7dRHXlHVsjkDVPuooi8meoplfZITwhUw10/s1600/23.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH0s6zhiBgFqdb0Vy68-oYkjEE4aRy-6kv15rOBZBgM0KwES0ncDqWTguwiTTwHktXpHcJ46uZooqE5M97idsMSQ4p85rGXeJRs93dhbbuk7dRHXlHVsjkDVPuooi8meoplfZITwhUw10/s400/23.png" width="225" /></a></div>
<br />
Y este es el resultado.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDs3a4HZEopY4e0ESMQ3l1I-Ohyphenhyphenij9P_hjtEMbAXZbVlSMPrIVHg6kRA9CDpLoCusPFE_pNQ1_3HZcgH1GjjgzSVkAL6IAKk5PdiuA6M1GRTfMv1yQdJ3LprDc_E3N6cbfisrgywV9Ouo/s1600/24.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDs3a4HZEopY4e0ESMQ3l1I-Ohyphenhyphenij9P_hjtEMbAXZbVlSMPrIVHg6kRA9CDpLoCusPFE_pNQ1_3HZcgH1GjjgzSVkAL6IAKk5PdiuA6M1GRTfMv1yQdJ3LprDc_E3N6cbfisrgywV9Ouo/s400/24.png" width="225" /></a></div>
<br />
¿Qué tal? Fácil, ¿no? Ahora te toca aplicarla en tus proyectos :)<br />
<br />
Por supuesto, puedes descargar el código fuente de mi GitHub dando clic <a href="https://github.com/icebeam7/ScannerZXing" target="_blank">aquí</a>.<br />
<br />
Espero que esta entrada haya sido de tu interés. Si te agradó, compártela con tus amigos y espero te sea útil. Si tienes alguna duda, con gusto la puedo atender por este medio.<br />
<br />
¡Saludos!Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com5tag:blogger.com,1999:blog-8407795827837136717.post-68356095911980020102017-02-10T04:11:00.000-08:002017-03-25T10:36:47.529-07:00Oxyplot: Una solución gratuita y open-source para crear gráficas en .NET y Xamarin¡Hola! En esta entrada te mostraré lo fácil que es agregar gráficas en un proyecto de Xamarin.Forms utilizando <b><a href="http://www.oxyplot.org/" target="_blank">Oxyplot</a></b>, la cual es una librería multiplataforma para agregar charts en soluciones basadas en .NET Framework, tales como WPF, Windows Forms, Windows, Windows Phone, Silverlight, y por supuesto, Xamarin (Forms, Android, iOS, etc).<br />
<br />
Existen 4 pasos básicos a seguir:<br />
<ol>
<li>Agregar el paquete <b>Oxyplot</b> a tu proyecto mediante el <b>Nuget Package Manager</b>.</li>
<li>Agregar un control <b>PlotView</b> en tu interfaz de usuario</li>
<li>Crear un objeto <b>PlotModel</b>.</li>
<li>Asociar (mediante <b>Binding</b>, por ejemplo) el <b>PlotModel </b>a la propiedad <b>Model </b>del <b>PlotView</b>.</li>
</ol>
<div>
<br /></div>
<div>
Ahora vamos a ver cómo se hace paso a paso en un proyecto de Xamarin.Forms.</div>
<div>
<br /></div>
<div>
<b>Paso 1</b>. Crea un proyecto de tipo <b>Xamarin.Forms Portable</b>. Para este caso, he puesto el nombre <b>GraficasOxyplot</b>.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTIGDqfPoXIZlhup9YNI9J39ql_NkxsRT5Pjl2eDtGu62s0ovwwpILkD0Ep-Vf-snw-t-w-UKgdIh8J92Ku230YO5tVuhRmXy0wEi5adJivQCXeJd_9COGVchYkEDQEzbVQw4dtRXR18Q/s1600/01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="243" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTIGDqfPoXIZlhup9YNI9J39ql_NkxsRT5Pjl2eDtGu62s0ovwwpILkD0Ep-Vf-snw-t-w-UKgdIh8J92Ku230YO5tVuhRmXy0wEi5adJivQCXeJd_9COGVchYkEDQEzbVQw4dtRXR18Q/s400/01.png" width="400" /></a></div>
<br />
<b>Paso 2</b>. Da clic derecho en la solución y elige <b>Administrar Paquetes Nuget para la Solución</b>.<br />
<br />
<a name='more'></a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKvA6Rcb-lXhECeVwdaZQSCEaOu_WTTCY82EG1f5C-LBglwdMsiNUcWkfM4bNQKU1Hg_P5nGKo9EtThLH0XJoPri8dZJwQpmfTQBy5yukGJT2pvH-kxCZ-fgejeyLPKeL-sIRZeyhdl58/s1600/02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKvA6Rcb-lXhECeVwdaZQSCEaOu_WTTCY82EG1f5C-LBglwdMsiNUcWkfM4bNQKU1Hg_P5nGKo9EtThLH0XJoPri8dZJwQpmfTQBy5yukGJT2pvH-kxCZ-fgejeyLPKeL-sIRZeyhdl58/s400/02.png" width="383" /></a></div>
<br />
<b>Paso 3</b>. Busca el paquete <b>Oxyplot.Xamarin.Forms</b> y agrégalo a todos los proyectos de tu solución que vayas a manejar.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIHoPQm6f8pxZm-iW-9SrpZI9Rk2pQicHi1Oi1A37IzFPi26K8uo8F6VNQpLnFGpZsgWQFuhW5DTExU4mjLiMTi5Yj0LCBLPm0EwEd_eBDRhLN3VNRUog4k1XkhnmDwIjlhxTM4cdBuRU/s1600/03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="243" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIHoPQm6f8pxZm-iW-9SrpZI9Rk2pQicHi1Oi1A37IzFPi26K8uo8F6VNQpLnFGpZsgWQFuhW5DTExU4mjLiMTi5Yj0LCBLPm0EwEd_eBDRhLN3VNRUog4k1XkhnmDwIjlhxTM4cdBuRU/s400/03.png" width="400" /></a></div>
<br />
<b>Paso 4. </b>Debes inicializar el renderer de plataforma específica en cada proyecto donde hayas agregado el paquete. Siempre será después del <b>Init </b>de <b>Xamarin.Forms</b> y la instrucción a colocar es <b>OxyPlot.Xamarin.Forms.Platform.<i>Plataforma</i>.PlotViewRenderer.Init();</b> donde Plataforma es reemplazado por <b>Android, iOS, UWP y WP8</b>, según el caso.<br />
<br />
Por ejemplo, para <b>Android </b>debes agregar dicha instrucción en el <b>MainActivity</b>; en el caso de <b>iOS</b>, es en <b>AppDelegate</b>:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP4fbTrOsokjYFS7AursRVRI2yzZRkhxI-jOTNhULoEqAxhCevIrhkeogoNSuGWfEZBv673YmiCJ8KxoYkVqgmoJNx0-x4Az9_Ug2qVtDxNcSh0T7S-DwfJsZfen48BJNEAjaNzGiMamI/s1600/04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP4fbTrOsokjYFS7AursRVRI2yzZRkhxI-jOTNhULoEqAxhCevIrhkeogoNSuGWfEZBv673YmiCJ8KxoYkVqgmoJNx0-x4Az9_Ug2qVtDxNcSh0T7S-DwfJsZfen48BJNEAjaNzGiMamI/s400/04.png" width="400" /></a></div>
<br />
Para <b>UWP</b> y los proyectos de <b>Windows</b>, busca el archivo <b>App.xaml.cs</b> de cada plataforma específica y agrega la instrucción mencionada para inicializar los renderers:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaA9jKjhYiA6hX4MY091FGlB42rtQUPg2A7HRhA3qS03HjUphBYFypiol6Em4hiqVeVcMwPuTw7HBXRMacVpK2IVdtFFkPmEytIxz9J8no6n7ddMnzLQCztP8gBtOpBIs4h_mYhRER5YQ/s1600/05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="297" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaA9jKjhYiA6hX4MY091FGlB42rtQUPg2A7HRhA3qS03HjUphBYFypiol6Em4hiqVeVcMwPuTw7HBXRMacVpK2IVdtFFkPmEytIxz9J8no6n7ddMnzLQCztP8gBtOpBIs4h_mYhRER5YQ/s400/05.png" width="400" /></a></div>
<br />
<b>Paso 5. </b>Ahora crea una carpeta llamada <b>ViewModels</b>. En ella, agrega una clase llamada <b>PastelViewModel</b> con el código siguiente, en el cual creamos un objeto <b>PlotModel</b> y le agregamos series de datos mediante la colección Series. En este caso usamos un <b>PieSeries</b> lleno de <b>PieSlices </b>porque vamos a mostrar una gráfica de pay:<br />
<b><br /></b>
<br />
<pre class="brush:csharp;first-line:1">using OxyPlot;
using OxyPlot.Series;
namespace GraficasOxyplot.ViewModels
{
public class PastelViewModel
{
public PlotModel Modelo { get; set; }
public PastelViewModel()
{
PieSeries serie = new PieSeries();
serie.Slices.Add(new PieSlice("Hielo", 40) { IsExploded = true, Fill = OxyColors.SkyBlue });
serie.Slices.Add(new PieSlice("Fuego", 67) { IsExploded = false, Fill = OxyColors.Red });
serie.Slices.Add(new PieSlice("Normal", 109) { IsExploded = false, Fill = OxyColors.LightGray });
serie.Slices.Add(new PieSlice("Dragón", 48) { IsExploded = true, Fill = OxyColors.Orange });
serie.Slices.Add(new PieSlice("Agua", 133) { IsExploded = true, Fill = OxyColors.Blue });
serie.Slices.Add(new PieSlice("Eléctrico", 51) { IsExploded = false, Fill = OxyColors.Yellow });
Modelo = new PlotModel() { PlotMargins = new OxyThickness(50) };
Modelo.Series.Add(serie);
}
}
}
</pre>
<b>Paso 6.</b> En el proyecto de Xamarin.Forms, crea una carpeta llamada Views, donde agregaremos todas las vistas (páginas). En dicha carpeta, agrega un <b>Forms Xaml Page</b>. En este caso, le he puesto el nombre <b>PastelView.</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://www.blogger.com/null" hxml="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVHK3KevyQQGhd2i1-5x7XKDdlo_HL7CNjsG-mseojWZLZVPRlsDa6bopulR3XLmF7bxasrmqD3I9-atKSdycOXHcmi02EERs8_KKElE6PmiPmX2ZWOC59LAMSDHEt_wmztC3VgmixPqE/s1600/06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="291" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVHK3KevyQQGhd2i1-5x7XKDdlo_HL7CNjsG-mseojWZLZVPRlsDa6bopulR3XLmF7bxasrmqD3I9-atKSdycOXHcmi02EERs8_KKElE6PmiPmX2ZWOC59LAMSDHEt_wmztC3VgmixPqE/s400/06.png" width="400" /></a></div>
<div>
<br /></div>
<div>
<b>Paso 7. </b>Como mencionamos anteriormente, se agregará un objeto <b>PlotView</b> en la interfaz de usuario. Para que sea reconocido en nuestro XAML, debemos agregar <b>una referencia a la librería</b> en la parte de espacios de nombre (lo puedes observar a continuación en el código <b>xmlns:oxy</b>). Ahora sí, agregamos el control PlotView con las propiedades <b>Model, BackgroundColor, VerticalOptions, HorizontalOptions y HeightRequest</b> establecidas. <b>Model </b>tiene la referencia al modelo creado en el <b>paso 5</b> (<b>Modelo</b>).</div>
<div>
<br /></div>
<div>
Así pues, el código <b>XAML</b> de esta vista es el siguiente:</div>
<br />
<pre class="brush:xml;first-line:1"><?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="GraficasOxyplot.Views.PastelView"
xmlns:oxy="clr-namespace:OxyPlot.Xamarin.Forms;assembly=OxyPlot.Xamarin.Forms">
<ContentPage.Content>
<StackLayout BackgroundColor="White">
<Label HorizontalTextAlignment="Center" Text="Pokémon por Tipo"
FontAttributes="Bold" TextColor="Blue" />
<oxy:PlotView Model="{Binding Modelo}" BackgroundColor="White"
VerticalOptions="Fill" HorizontalOptions="Fill" HeightRequest="400"/>
</StackLayout>
</ContentPage.Content>
</ContentPage></pre>
<div>
<br /></div>
<div>
El <i>code-behind</i>, es decir, el código <b>C#</b> de la vista es simplemente un enlace de la <b>View </b>al <b>ViewModel</b> (mediante <b>BindingContext</b>) <b>PastelViewModel </b>que creamos en el paso 5 y que contiene la propiedad <b>Modelo</b>.</div>
<div>
<br />
<pre class="brush:csharp;first-line:1">using Xamarin.Forms;
using GraficasOxyplot.ViewModels;
namespace GraficasOxyplot.Views
{
public partial class PastelView : ContentPage
{
public PastelViewModel vm { get; set; }
public PastelView()
{
InitializeComponent();
vm = new PastelViewModel();
BindingContext = vm;
}
}
}
</pre>
</div>
<div>
<br /></div>
<div>
<b>Paso 8.</b> ¡Listo! Ya solo tienes que indicar en tu archivo <b>App.cs </b>del proyecto de <b>Xamarin.Forms</b> que inicie la vista PastelView para mostrar la página que contiene la gráfica mediante el código siguiente:</div>
<br />
<pre class="brush:csharp;first-line:1">public App()
{
MainPage = new NavigationPage(new Views.PastelView());
}
</pre>
<br />
¿Cómo se ve la gráfica generada? A continuación te muestro el resultado en <b>Android</b>:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPH_7p2wmEHxzSagAfVD9_qxgDvOnSYvF0B5pGwZoQ5RMdSDgKsg41Ktyx7eTGi0bEq1b7HselO4t5LFdiH8eQVxD3DEGPu1TeRfAAI_g8gsw53knemgD4wjEPJvpdChnd5zJh7m3m-c4/s1600/ox1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPH_7p2wmEHxzSagAfVD9_qxgDvOnSYvF0B5pGwZoQ5RMdSDgKsg41Ktyx7eTGi0bEq1b7HselO4t5LFdiH8eQVxD3DEGPu1TeRfAAI_g8gsw53knemgD4wjEPJvpdChnd5zJh7m3m-c4/s400/ox1.png" width="225" /></a> </div>
<br />
¿Y cómo se ven en <b>Windows 10</b>? Pues así:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIZNeXTqZMhUH_F2kLPegBv97yVFky-ERfqOE7st7CJdDa1X0f65MSawNINo-18I43I4uuL0pY1ElUQAQCSKNPXPbMO6w5TBbQTcvuQCLDr3SEVocRScA8L_gBC9WFcF-syVMDm_Imzcc/s1600/wp_ss_20170210_0001.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIZNeXTqZMhUH_F2kLPegBv97yVFky-ERfqOE7st7CJdDa1X0f65MSawNINo-18I43I4uuL0pY1ElUQAQCSKNPXPbMO6w5TBbQTcvuQCLDr3SEVocRScA8L_gBC9WFcF-syVMDm_Imzcc/s400/wp_ss_20170210_0001.png" width="225" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<i>(Luego les muestro cómo se ve en un iPhone =) )</i><br />
<br />
Fácil, ¿no? En mi <b><a href="https://github.com/icebeam7" target="_blank">GitHub</a></b> puedes encontrar el <b><a href="https://github.com/icebeam7/GraficasOxyplot" target="_blank">código fuente</a></b> de este proyecto. Observa que he agregado <b>4 Views y</b> <b>4 ViewModels</b> más, además de que el <b>App.cs</b> es diferente porque muestro también cómo crear una <b>gráfica de barras, áreas y XY</b>. Algo como esto:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdRWGzEicV7Oy3GRJh0AHhn3Vb20dgxug06l462MAniVXXQWutnA8gAWrTLT56defEwb2_g47Z2I25Ez6fmYfqBBUI6GH6V_fI5dJOkzaXhEf0JtV2c1bXXgF2XMtMWdwOyuMAHQoroXM/s1600/ox2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdRWGzEicV7Oy3GRJh0AHhn3Vb20dgxug06l462MAniVXXQWutnA8gAWrTLT56defEwb2_g47Z2I25Ez6fmYfqBBUI6GH6V_fI5dJOkzaXhEf0JtV2c1bXXgF2XMtMWdwOyuMAHQoroXM/s400/ox2.png" width="225" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAhgR3ZrQM5uZJGCINuLThI3RDyfhOid5pwrEmV3QNCQ1wzIExoGov7YXAC7XyeFdJjvRP-Pwb2JOPsDNHWOosv7bQL9ya23K7DWZiJSgZrQETt80tgCkpH6n0OlRJnOpfNZRX43zJKPo/s1600/ox3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAhgR3ZrQM5uZJGCINuLThI3RDyfhOid5pwrEmV3QNCQ1wzIExoGov7YXAC7XyeFdJjvRP-Pwb2JOPsDNHWOosv7bQL9ya23K7DWZiJSgZrQETt80tgCkpH6n0OlRJnOpfNZRX43zJKPo/s400/ox3.png" width="225" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEij8OkGz94ewRmOtFOkXAioBZOnDDIniR9wUFt3AOcZjKFugmzk9bzbryFE9zjie3uZ4RpCDGb5C_Em47HiVTnOOZFLYk3HJe92nfU6U9SqQYQKh-OJhj3FmM32iCukoPDy6A1YjnhzdJw/s1600/ox4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEij8OkGz94ewRmOtFOkXAioBZOnDDIniR9wUFt3AOcZjKFugmzk9bzbryFE9zjie3uZ4RpCDGb5C_Em47HiVTnOOZFLYk3HJe92nfU6U9SqQYQKh-OJhj3FmM32iCukoPDy6A1YjnhzdJw/s400/ox4.png" width="225" /></a></div>
<br />
Espero que esta entrada haya sido de tu interés. Compártela con tus amigos si así fue, y espero te sea útil en tus desarrollos.<br />
<br />
¡Saludos!Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com6tag:blogger.com,1999:blog-8407795827837136717.post-53070539165421462422017-02-09T04:59:00.003-08:002017-02-09T04:59:36.754-08:00Crea una cuenta de Azure SIN tarjeta de créditoA continuación les paso un método para obtener un <b>Azure Pass</b>, el cual les permitirá utilizar Azure con créditos de manera gratuita y sin requerir tarjeta de crédito. De esta manera, podrán iniciar bien el diplomado de <b>Xamarin Intermedio</b> (ya inició, <a href="http://icebeamwp.blogspot.cz/2017/01/despues-del-exito-obtenido-gracias-la.html" target="_blank"><b>aquí la noticia</b></a>) y de <b>Azure University</b> (está por iniciar, <b><a href="http://icebeamwp.blogspot.cz/2017/02/diplomado-en-linea-azure-university.html" target="_blank">la noticia aquí</a></b>). Azure y el cómputo en la nube son una parte esencial en ambos cursos.<br />
<br />
<b>NOTAS:</b><br />
<br />
<ul>
<li><b>NO ABUSAR DEL SERVICIO</b>. Solo genera un código porque sólo necesitas uno. Se recomienda no compartir el método con personas ajenas al diplomado, para evitar un mal uso de Azure. El método es gratuito, evitemos que lo den de baja por usuarios que hacen uso indebido de Azure.</li>
<li>El código tiene una vigencia de <b>3 meses</b></li>
<li>Cuentas <b>100 USD mensuales</b> para tus servicios (máquinas virtuales, bases de datos, servicios en la nube, servicios móviles, etc).</li>
<li>Si ya usaron Azure gratis con su cuenta por alguna otra razón (<b>DevEssentials</b>, AzurePass, ITProCloudEssentials, Trial) es probable que el código obtenido no funcione. Tendrán que crear otra cuenta de Outlook/Hotmail/Live</li>
<li>Solo funciona con Internet Explorer. Con Chrome y otros navegadores (Edge, Firefox) la pantalla se queda en negro. Esto es porque se instala un ActiveX y bueno, ya saben, Internet Explorer...</li>
</ul>
<br />
Pasos a seguir:<br />
<br />
Ingresa a <b><a href="https://aka.ms/ignite2016labs">https://aka.ms/ignite2016labs</a></b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlWe6XItHaXhTxvzXM7rm4hrF5s6R6Wv3TM2hIhYKrtvh2MPQou1DfMTzGwEvBlpzCQgZSphvqK_A756usXK2eKwvCA0RiH1Glgzjo2pEZTHT21qAy1CsY37mq6XKrn7Kg5Rp5cCQPELI/s1600/az01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="208" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlWe6XItHaXhTxvzXM7rm4hrF5s6R6Wv3TM2hIhYKrtvh2MPQou1DfMTzGwEvBlpzCQgZSphvqK_A756usXK2eKwvCA0RiH1Glgzjo2pEZTHT21qAy1CsY37mq6XKrn7Kg5Rp5cCQPELI/s400/az01.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Inicia sesión con tu cuenta de Hotmail/Live/Outlook y acepta los 2 permisos solicitados.<div>
<a name='more'></a><br /></div>
<div>
Busca el curso "<b>Azure SQL Data Warehouse</b>"</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLbbgQoc1eF7dSzTqkd2poWWX65vdcF9gFa4m8kbpu3RkTawxcHyNbZLUODYUdGf6fNqq7zwaWOwb0vo4oD4cdxAzWoRpmrNrnM158mtn_sONjkBk7eaGMbL9bCUSiFAWKTKsKdUBuzR0/s1600/az02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="211" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLbbgQoc1eF7dSzTqkd2poWWX65vdcF9gFa4m8kbpu3RkTawxcHyNbZLUODYUdGf6fNqq7zwaWOwb0vo4oD4cdxAzWoRpmrNrnM158mtn_sONjkBk7eaGMbL9bCUSiFAWKTKsKdUBuzR0/s400/az02.png" width="400" /></a></div>
<div>
<br /></div>
<div>
Dale clic en <b>Launch</b>. Se cargará un ActiveX que tardará un rato, dependiendo tu conexión. </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9hF-sIXz2D-wpZDKmtXdUu5FqueomT_noJNH239zhGnH9zB0Cc8GjW8fg6Ud4yBzICftJGarmOlFskvsNCOSrZ5lH6RPybONe1XLrzQopjAQOtTvtyX-bE4AbQMFf3IXs9qGRTYta9EU/s1600/az03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="21" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9hF-sIXz2D-wpZDKmtXdUu5FqueomT_noJNH239zhGnH9zB0Cc8GjW8fg6Ud4yBzICftJGarmOlFskvsNCOSrZ5lH6RPybONe1XLrzQopjAQOtTvtyX-bE4AbQMFf3IXs9qGRTYta9EU/s400/az03.png" width="400" /></a></div>
<div>
<br /></div>
<div>
Una vez finalizada la carga del complemento, aparecerá un <b>Azure Promo Code</b> en la esquina superior derecha. Cópialo.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAAcZ5lSB9ql6UU8lfldWKeURA0p351lVqotmkERH4iE5YAJeFp_T_QYyyTz4Z_h3hMhm6H4sthGXq_KUqGJqk0jRCYnQAHLje7pqqor-eOT2g24hcbnBEYiTCIbo3I8mIhxqbQQ9d7iE/s1600/az04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="186" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAAcZ5lSB9ql6UU8lfldWKeURA0p351lVqotmkERH4iE5YAJeFp_T_QYyyTz4Z_h3hMhm6H4sthGXq_KUqGJqk0jRCYnQAHLje7pqqor-eOT2g24hcbnBEYiTCIbo3I8mIhxqbQQ9d7iE/s400/az04.png" width="400" /></a></div>
<div>
<br /></div>
<div>
Ingresa a <b>https://www.microsoftazurepass.com/. </b>Selecciona tu pais, escribe el codigo y da clic en Submit.<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1nJ1SMLcKC9c9zeOt-C6bzstS4FY3667nKsCvRAev3HPORVBs1hzZyGsA_dpEa-ptk6PBFQce92F21aDTPEgJUjr5nlINY-8lZoRgSMdX_1gncGBfSUrpPdWjCh3CUd3TfNxyhtBXtX8/s1600/az05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1nJ1SMLcKC9c9zeOt-C6bzstS4FY3667nKsCvRAev3HPORVBs1hzZyGsA_dpEa-ptk6PBFQce92F21aDTPEgJUjr5nlINY-8lZoRgSMdX_1gncGBfSUrpPdWjCh3CUd3TfNxyhtBXtX8/s400/az05.png" width="400" /></a></div>
<br />
Inicia sesión con la cuenta que quieres utilizar el código.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPyE7TxnI_xS3S8YN3u1t5qx8ST7afS2QF2L7aF5vaPITVWRtcCUcAuGMz-dMkK0N8t7gx4x9IER4dfcXth5KEk4kwX9ZcJELSLLWmRjfeEq6HNd2xn8gADddXkaaun2c6fzlWikyLnRU/s1600/az06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPyE7TxnI_xS3S8YN3u1t5qx8ST7afS2QF2L7aF5vaPITVWRtcCUcAuGMz-dMkK0N8t7gx4x9IER4dfcXth5KEk4kwX9ZcJELSLLWmRjfeEq6HNd2xn8gADddXkaaun2c6fzlWikyLnRU/s400/az06.png" width="400" /></a></div>
<br />
Llena los datos solicitados.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCVgfuOTJHmdD_WXAjfv-0IkK9djEgncYjpj6LGDOkaRNDsN1sv-Rv3wYaVGHUAK28lxgETOaTbtVc1wWzQrJEaTu_F7L6ZZMvxXvR0gXTIxdaNLdPBpdzcKQDMqqe9JNz0kyyQP2T-Q8/s1600/az07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="227" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCVgfuOTJHmdD_WXAjfv-0IkK9djEgncYjpj6LGDOkaRNDsN1sv-Rv3wYaVGHUAK28lxgETOaTbtVc1wWzQrJEaTu_F7L6ZZMvxXvR0gXTIxdaNLdPBpdzcKQDMqqe9JNz0kyyQP2T-Q8/s400/az07.png" width="400" /></a></div>
<br />
Se te presentará un resumen con la promoción incluida en tu código. Da clic en <b>Activate</b>.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHQLqfRh6-TwA-Gw_3a8Dsd1IJMRiVQcPCOmCJScZAoTRGnBKpF5fYeX0VY-i-7VNSMo92HiBrk6lOr0aWDlx9M0tzh5EOvPiAN-QSoj5yeB2VHCZgRAw5fUMN-u0yWAe6xXnXKelhN_U/s1600/az08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="222" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHQLqfRh6-TwA-Gw_3a8Dsd1IJMRiVQcPCOmCJScZAoTRGnBKpF5fYeX0VY-i-7VNSMo92HiBrk6lOr0aWDlx9M0tzh5EOvPiAN-QSoj5yeB2VHCZgRAw5fUMN-u0yWAe6xXnXKelhN_U/s400/az08.png" width="400" /></a></div>
<br />
Llena los datos solicitados en cada una de las secciones. Primero, Acerca De.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYsL0QHbwUIxMQCSjUtd3UJuYl3bph9AcrnwmTt_Lb70pWXqKkUSwTSvgGqGsKGQmePhWO15dmk1t47T1NnJLPGerI6BuQFDvRGE2cM9Tpif4rTEOgpUDfORIlGZKULmF-0wli9uvqNMM/s1600/az09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="268" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYsL0QHbwUIxMQCSjUtd3UJuYl3bph9AcrnwmTt_Lb70pWXqKkUSwTSvgGqGsKGQmePhWO15dmk1t47T1NnJLPGerI6BuQFDvRGE2cM9Tpif4rTEOgpUDfORIlGZKULmF-0wli9uvqNMM/s400/az09.png" width="400" /></a></div>
<br />
En segundo lugar, tu teléfono.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3pZUEbWqH0Xa_t1kUnLSizDP7g6RhdlZn5IAPMEe6XTwadjWXr4KOQ8W3r759TpSTX6EwvTHmyZq1oTehGbOfPdoIOMhLqdUhMQlX_kpq-ifqkSXQ4b_06a-Ny5F4Vf1sz2BaT9JT1uM/s1600/az10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="270" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3pZUEbWqH0Xa_t1kUnLSizDP7g6RhdlZn5IAPMEe6XTwadjWXr4KOQ8W3r759TpSTX6EwvTHmyZq1oTehGbOfPdoIOMhLqdUhMQlX_kpq-ifqkSXQ4b_06a-Ny5F4Vf1sz2BaT9JT1uM/s400/az10.png" width="400" /></a></div>
<br />
Finalmente, acepta el acuerdo y los términos de uso.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkWj0yQqIVJeuFPeU8f6rubgGpMazi-NQok7lHA8i58yL97H8RESr3tc_10danfhbhEC3bXCBpsxJ_AXDjIYjp0R6F_5Rwa8DxZH5gy3twXifArA7-sOSZKFgEpH_tQP2Zkat12CTgN-U/s1600/az11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="268" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkWj0yQqIVJeuFPeU8f6rubgGpMazi-NQok7lHA8i58yL97H8RESr3tc_10danfhbhEC3bXCBpsxJ_AXDjIYjp0R6F_5Rwa8DxZH5gy3twXifArA7-sOSZKFgEpH_tQP2Zkat12CTgN-U/s400/az11.png" width="400" /></a></div>
<br />
Se tardará un momento en generar la suscripción y provisionar un área de trabajo, pero una vez finalizado, aparecerá el mensaje de que la suscripción está lista para ser utilizada.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcv3qD1u3yEZPI7meFO5JttLjOxnAXY8LvM7RAL_V0IcYYHLj4IYLXo6dEIj4RTsA9AGweCTh38c0exjQjCn0u6wk8RJSK2KZSF6d62V1QyAGJKkunzOak1-CuO6lKQUWZwIfytUjQ4zE/s1600/az12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="270" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcv3qD1u3yEZPI7meFO5JttLjOxnAXY8LvM7RAL_V0IcYYHLj4IYLXo6dEIj4RTsA9AGweCTh38c0exjQjCn0u6wk8RJSK2KZSF6d62V1QyAGJKkunzOak1-CuO6lKQUWZwIfytUjQ4zE/s400/az12.png" width="400" /></a></div>
<br />
Incluso, puedes ingresar al portal y verás que tu espacio de trabajo está disponible.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc8jLAGtfnQ4guoM8n4ledGfJDf_TjoKflsQjRLPagRH_ZYQZpnRqd-3DOZNd5686sDZ9hyphenhyphenLAeyXluJxwQemlHowQG3WS1wQkaIQD705NA4SDUHwwPIn9Fyfcu-0pzjfAvYYetG3wCFQY/s1600/az13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc8jLAGtfnQ4guoM8n4ledGfJDf_TjoKflsQjRLPagRH_ZYQZpnRqd-3DOZNd5686sDZ9hyphenhyphenLAeyXluJxwQemlHowQG3WS1wQkaIQD705NA4SDUHwwPIn9Fyfcu-0pzjfAvYYetG3wCFQY/s400/az13.png" width="400" /></a></div>
<br />
Te recuerdo que hay otras alternativas para probar Azure:<br />
<br />
<br />
<ul>
<li><a href="https://azure.microsoft.com/en-us/free/" target="_blank"><b>Cuenta trial</b></a> (requiere tarjeta de crédito para su activación, otorga 200 USD durante un mes)</li>
<li><a href="https://azure.microsoft.com/en-us/pricing/member-offers/vs-dev-essentials/" style="font-weight: bold;" target="_blank">Visual Studio Dev Essentials</a> (requiere tarjeta de crédito para su activación, otorga 25 USD mensuales durante un año)</li>
<li><b><a href="https://www.microsoftazurepass.com/" target="_blank">Azure Pass</a></b> (no requiere tarjeta de crédito y hay varias formas de conseguir uno. En este post justo explique una manera)</li>
<li><b><a href="https://bizspark.microsoft.com/" target="_blank">Bizspark</a></b> (requiere tarjeta de crédito para su activación, otorga 150 USD mensuales durante un año. La cuenta se puede compartir con 5 desarrolladores, dando un total de 750 USD al mes)</li>
<li><b><a href="https://www.microsoft.com/itprocloudessentials/" target="_blank">IT Pro Cloud Essentials</a></b> (requiere tarjeta de crédito para su activación, otorga 100 USD mensuales durante 90 días)</li>
<li><b><a href="https://www.microsoft.com/en-us/research/academic-program/microsoft-azure-for-research/" target="_blank">Azure for Research</a></b> (este método no lo he probado, pero está dirigido a universidades, investigadores y proyectos de investigación).</li>
<li><b><a href="https://imagine.microsoft.com/en-us/Catalog/Product/99" target="_blank">Azure for Students</a></b> (no requiere tarjeta de crédito, está dirigido a estudiantes. Anteriormente bajo el programa Dreamspark, ahora está incluido en los beneficios Imagine para estudiantes. Otorga servicios como App Services, Mobile Services, Notification Hubs, SQL and MySQL databases. y otros, pero no puedes crear Virtual Machines. La duración del beneficio se limita al tiempo que seas estudiante, renovando el permiso anualmente).</li>
</ul>
<div>
<br /></div>
<div>
Espero que esta entrada haya sido de utilidad para tí.</div>
<div>
<br /></div>
<div>
¡Saludos y buen día! :)</div>
</div>
Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com17tag:blogger.com,1999:blog-8407795827837136717.post-46339242570558500902017-02-09T04:59:00.001-08:002017-02-13T05:12:37.744-08:00Diplomado en línea: Azure University<b>Microsoft </b>continúa ofreciendo cursos gratuitos para que sigas preparándote y aprendiendo de sus tecnologías. En esta ocasión, se han abierto las inscripciones para el <b>Diplomado en línea Azure University.</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVeV3GJDVHLYbuC60pZjHrBvD1tNt3-sRY7dG1kjssPAEhVQkuVBySjhsg3yOtjdeXci13YXUcdvRwwSEFJcA7HUd2yn0VfilZH2Z9Z8SiE5WAiS6Axojy0boxqRFMGOjgs7irtfM9gRA/s1600/azureuniv.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="202" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVeV3GJDVHLYbuC60pZjHrBvD1tNt3-sRY7dG1kjssPAEhVQkuVBySjhsg3yOtjdeXci13YXUcdvRwwSEFJcA7HUd2yn0VfilZH2Z9Z8SiE5WAiS6Axojy0boxqRFMGOjgs7irtfM9gRA/s400/azureuniv.jpg" width="400" /></a></div>
<br />
En este nuevo diplomado, aprenderás 2 temas por semana y habrá sesiones en directo con los instructores y expertos internacionales, donde podrás preguntarles y aprovechar al máximo la experiencia de aprendizaje.<br />
<br />
Además, los recursos (videos, pdfs, enlaces) estarán disponibles on-demand mientras el curso esté vigente.<br />
<br />
Para aprobar y recibir un diploma digital otorgado por Microsoft que valida tu superación del curso, deberás realizar exámenes en línea semanalmente. El criterio de aprobación es obtener 8/10.<br />
<br />
Los módulos del curso son:<br />
<br />
<ul>
<li>Computo de nube Empresarial</li>
<li>Tipos de soluciones de la nube como centro de computo</li>
<li>Redes de Datos en Azure (Networking)</li>
<li>Seguridad y Firewalls en Azure</li>
<li>Resguardo y recuperación</li>
<li>Monitoreo de componentes de Azure</li>
<li>Manejo de Identidades en la Nube</li>
<li>Bases de datos y analítica en Azure</li>
</ul>
<br />
Para más información y realizar tu registro, da clic en el siguiente <a href="http://ticapacitacion.com/curso/azureuniv/" target="_blank"><b>enlace</b></a>. Todavía no se define una fecha de inicio, pero si te registras, te llegará posteriormente un correo cuando el aula esté abierta.<br />
<div>
<br /></div>
<div>
</div>
<br />
<div>
Te invito a que participes en esta experiencia de aprendizaje. Si gustas, puedes unirte a nuestro <b><a href="https://www.facebook.com/groups/windows10university/" target="_blank">grupo de estudio en Facebook</a></b>, donde varios alumnos del curso nos apoyamos resolviendo dudas, compartiendo conocimiento y más. (Nota: Anteriormente hubo un diplomado llamado Windows 10 University y decidimos que reutilizaremos el mismo grupo, por eso momentáneamente se sigue llamando así).</div>
<br />
<br />
¡Saludos y a seguir aprendiendo!Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com3tag:blogger.com,1999:blog-8407795827837136717.post-76424306167850027542017-02-06T15:51:00.001-08:002017-02-08T00:59:43.621-08:00Data Science and Analytics Free Beta Certification Exams!¡Hola! En esta entrada te comento que Microsoft está ofreciendo !<b>2 exámenes de certificación totalmente gratuitos</b>! Si estás interesado en las ciencias de datos y análisis, has utilizado Azure Machine Learning para desarrollr soluciones inteligentes en la nube y quieres evaluar tus conocimientos en estas áreas, esta información te interesa :)<br />
<br />
La idea es que solicitarás el examen, agendarás cada uno en una fecha <b>no posterior al 31 de Marzo</b> y al momento de hacer la compra, colocarás un código (voucher) para que salga gratis el examen <b>(solo hay 300 disponibles en todo el mundo, así que apresúrate a aplicar!)</b><br />
<br />
El primer examen es el <b><a href="https://www.microsoft.com/en-us/learning/exam-70-774.aspx" target="_blank">70-774: Perform Cloud Data Science with Azure Machine Learning</a></b>, el cual evalua 4 habilidades:<br />
<br />
<ul>
<li>Preparación de datos para el Análisis en Azure Machine Learning y su exportación</li>
<li>Desarrollar modelos de Aprendizaje Automático</li>
<li>Operar y administrar servicios de Azure Machine Learning </li>
<li>Usar otros servicios para Aprendizaje Automático</li>
</ul>
<div>
<br /></div>
<div>
Para obtener gratis este examen, ingresa a <b><a href="https://www.microsoft.com/en-us/learning/exam-70-774.aspx" target="_blank">su página</a> </b>y sigue la guía que coloco más abajo. El voucher que utilizarás es <b>SCPAZ774EP</b>.</div>
<div>
<br /></div>
<div>
El segundo examen es el <b><a href="https://www.microsoft.com/en-us/learning/exam-70-775.aspx" target="_blank">70-775 Perform Data Engineering on Microsoft Azure HDInsight (beta)</a></b>, el cual se centra en las siguientes habilidades:</div>
<div>
<br /></div>
<div>
<ul>
<li></li>
<li>Administrar y provisionar clústeres HDInsight </li>
<li>Implementar soluciones de procesamiento por lotes de Big Data</li>
<li>Implementar soluciones de procesamiento interactivo de Big Data </li>
<li>Implementar soluciones de procesamiento en tiempo real de Big Data Real</li>
</ul>
</div>
<div>
<br /></div>
<div>
De igual forma, sigue la guía para solicitar el examen desde <a href="https://www.microsoft.com/en-us/learning/exam-70-775.aspx" target="_blank"><b>esta página</b></a>. El voucher a utilizar es <b>BPERB775VM</b>.</div>
<div>
<br /></div>
<div>
No lo pienses tanto porque hay solo 300 asientos disponibles por examen, así que cuanto antes lo solicites, mejor :)</div>
<div>
<br /></div>
<div>
Esta información la obtuve desde el blog <b><a href="https://borntolearn.mslearn.net/" target="_blank">Born To Learn</a></b>, el cual es oficial de Microsoft. Te sugiero lo revises constantemente, pues siempre colocan entradas interesantes, incluyendo la oportunidad de realizar exámenes betas gratuitos.</div>
<div>
<br /></div>
<div>
Ahora sí, la guía para solicitar el examen gratis. Para este ejemplo, utilicé el 70-774:</div>
<div>
<br /></div>
<div>
<b>Paso 1. </b>Ingresa a la página del examen y da clic en Schedule exam.</div>
<div>
<br /></div>
<div>
<br />
<a name='more'></a><br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2aE4KJbZxmqBqglqRlr7mhbui2QoAzVrApZoHmPjozlQfHQu6hYd5Tb5VUJq4jAYZbR4oHbAmOSOIQcxBX2MxZRSbDFkBM4HbkKGjoi4q3HOtrfFYuXp3fkrfTXCGoGzGI1px-RxYp_4/s1600/ex01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="297" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2aE4KJbZxmqBqglqRlr7mhbui2QoAzVrApZoHmPjozlQfHQu6hYd5Tb5VUJq4jAYZbR4oHbAmOSOIQcxBX2MxZRSbDFkBM4HbkKGjoi4q3HOtrfFYuXp3fkrfTXCGoGzGI1px-RxYp_4/s400/ex01.png" width="400" /></a></div>
<br />
<b>Paso 2. </b>Verifica que la información mostrada sea la correcta o edítala en caso contrario. Da clic en Submit una vez que los datos sean correctos.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOVnn3v9WoDIyOFdsm0XpESf5ISj0zz7NDRk2qxgQiHRT47gUsdgYyqxbwCJ38mF64X79UgoPxP_hQod0k6Tsw1Xvtk3hONT17MoF7vDz-w0ngS0i-a9UAzeQ3au8KXZxBtmpl-HKCX6Y/s1600/ex02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="296" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOVnn3v9WoDIyOFdsm0XpESf5ISj0zz7NDRk2qxgQiHRT47gUsdgYyqxbwCJ38mF64X79UgoPxP_hQod0k6Tsw1Xvtk3hONT17MoF7vDz-w0ngS0i-a9UAzeQ3au8KXZxBtmpl-HKCX6Y/s400/ex02.png" width="400" /></a></div>
<br />
<b>Paso 3. </b>Elige la opción de agendar examen en un centro de certificación (recomendada) o la de realizar el examen en línea.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpbe5kjfGSgs25pBj_bSC01m2NN5wxG7k3p5VegSwAPck6KFhed8RWhblq9bRBg_Cn0DfwAHq07PNYH4w-wcG_Ha4Ja2pwqUgFlXRkz1jrAUbIJal5CjnJDXIG-RBe-mAhVgVbWxBUmFE/s1600/ex03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="293" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpbe5kjfGSgs25pBj_bSC01m2NN5wxG7k3p5VegSwAPck6KFhed8RWhblq9bRBg_Cn0DfwAHq07PNYH4w-wcG_Ha4Ja2pwqUgFlXRkz1jrAUbIJal5CjnJDXIG-RBe-mAhVgVbWxBUmFE/s400/ex03.png" width="400" /></a></div>
<br />
<b>Paso 4. </b>Da clic en Schedule exam (no te asustes si aparece el precio ;) )<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMko_R-KtPw7OzxglO9EdQN8n5gMXnCwiZjPhiRBCxJHaQaYM2O3OB06kLOlC13gDRcg3qCHm38E3BWbcGSSlpIFAEjaH0bL-z-r-chQuU8stXoStKZVIPEOBo3-NNnnjP0AcEAluxCuo/s1600/ex04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="292" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMko_R-KtPw7OzxglO9EdQN8n5gMXnCwiZjPhiRBCxJHaQaYM2O3OB06kLOlC13gDRcg3qCHm38E3BWbcGSSlpIFAEjaH0bL-z-r-chQuU8stXoStKZVIPEOBo3-NNnnjP0AcEAluxCuo/s400/ex04.png" width="400" /></a></div>
<br />
<b>Paso 5. </b>En esta página coloca una dirección o ciudad de tu convenciencia. En los resultados de búsqueda aparecerán los centros de certificación más cercanos. Puedes elegir hasta 3 para evaluar los horarios y fechas disponibles.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnbqsWRJuj3HsfMzOX3_04MHzenGm2eTAB3kcQ8uW5ZWY2ABPcXzdxkL_TZZ9XUucBh01ROjJj7vTMlmgeeaweG9FcTtCGMc_H-PSyJKwaLcy0f-S7TNuUHFT_JDhJcdq1m4dE4bixcIY/s1600/ex05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="290" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnbqsWRJuj3HsfMzOX3_04MHzenGm2eTAB3kcQ8uW5ZWY2ABPcXzdxkL_TZZ9XUucBh01ROjJj7vTMlmgeeaweG9FcTtCGMc_H-PSyJKwaLcy0f-S7TNuUHFT_JDhJcdq1m4dE4bixcIY/s400/ex05.png" width="400" /></a></div>
<br />
<b>Paso 6. </b>Por cada centro de certificación seleccionado, podrás ver las fechas y horarios disponibles. Si no te conviene ninguno de los 3, regresa al paso anterior y selecciona otros centros. Tienes que seleccionar máximo el 31 de Marzo para estos dos exámenes. Puedes presentar ambos el mismo día, con una diferencia de 3 horas y 15 minutos entre examen (ejemplo, el primero a las 9 am y el segundo a las 12:15 pm).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAcG_TtbalR-xUiP65Q0Iy6vPPNRZHfmB1jcg7zEkTwKe3DwBY1wIjh_OWquKimVPIiuezxTSLVhh3LmzLz6sAhIc3cNjEAV_TexiUt8EBXln47NVZasy8IqviqbcxAZ5WG1A0Y5DzZAg/s1600/ex06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAcG_TtbalR-xUiP65Q0Iy6vPPNRZHfmB1jcg7zEkTwKe3DwBY1wIjh_OWquKimVPIiuezxTSLVhh3LmzLz6sAhIc3cNjEAV_TexiUt8EBXln47NVZasy8IqviqbcxAZ5WG1A0Y5DzZAg/s400/ex06.png" width="400" /></a></div>
<br />
<b>Paso 7. </b>Una vez que selecciones el centro, día y fecha, verifica que los datos sean correctos y procede al checkout.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5OZh2aEdpSl7wE6GXRZRFoR5qMQyzglto3mUBALhmCI5V4YjMXDljbHUz_FUdyGDgtx6-lhAyjPF8SvEmO1XEnDWCBIWjflD6Nq_jPlgquJsK2XOLn4ZEcE6q6eyOqey4e8TAq2zyG-w/s1600/ex07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="396" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5OZh2aEdpSl7wE6GXRZRFoR5qMQyzglto3mUBALhmCI5V4YjMXDljbHUz_FUdyGDgtx6-lhAyjPF8SvEmO1XEnDWCBIWjflD6Nq_jPlgquJsK2XOLn4ZEcE6q6eyOqey4e8TAq2zyG-w/s400/ex07.png" width="400" /></a></div>
<br />
<b>Paso 8. </b>Verifica nuevamente que los datos mostrados sean correctos.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJFfXUqzKECfYovI9jS5np70PdOXoHlUy1sammhoJSb3n6fseh9wxekDG4X5XUh4aun0PStMpG8VF7dh1zmIUXY5fubq6kqut8-5ct52ehE9ilWCERjWZNUmnTFGgWVgYYwbSrNz86I60/s1600/ex08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJFfXUqzKECfYovI9jS5np70PdOXoHlUy1sammhoJSb3n6fseh9wxekDG4X5XUh4aun0PStMpG8VF7dh1zmIUXY5fubq6kqut8-5ct52ehE9ilWCERjWZNUmnTFGgWVgYYwbSrNz86I60/s400/ex08.png" width="400" /></a></div>
<br />
<b>Paso 9. </b>Lee y acepta las políticas de Microsoft acerca del examen de certificación.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-QZmZIsk6s8fs2bamS_1ljB4jY8JGsuIYnm9bQy3ndH4_ekHVOl9i3r2qA2DTyHts5gICq6vu7oazHQqtAPUckH5Jflj0MEw5xvsgdGHl4nxYhlkv47kWDwZoVYsNXCfOOl4uEHnExBY/s1600/ex09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="308" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-QZmZIsk6s8fs2bamS_1ljB4jY8JGsuIYnm9bQy3ndH4_ekHVOl9i3r2qA2DTyHts5gICq6vu7oazHQqtAPUckH5Jflj0MEw5xvsgdGHl4nxYhlkv47kWDwZoVYsNXCfOOl4uEHnExBY/s400/ex09.png" width="400" /></a></div>
<br />
<b>Paso 10. </b>En esta página es donde se ingresa el voucher. Da clic en Add Voucher or Promo Code.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYt3R8KyIfu8o-PF5oo2j6-SgksAZijbOET2l4epUU6bLOPOxSbJjfE0y0JhXWURC8TKEVRpJzG5JrcgXCw9F4Uo-dVprXdoVCpdasaw2w_I-fe9QeE3rE2ujCpGX5MspKFw6kQGE8MxY/s1600/ex10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="301" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYt3R8KyIfu8o-PF5oo2j6-SgksAZijbOET2l4epUU6bLOPOxSbJjfE0y0JhXWURC8TKEVRpJzG5JrcgXCw9F4Uo-dVprXdoVCpdasaw2w_I-fe9QeE3rE2ujCpGX5MspKFw6kQGE8MxY/s400/ex10.png" width="400" /></a></div>
<br />
<b>Paso 11. </b>Ingresa el código respectivo del examen a solicitar (lo mostré más arriba).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxFR7VRFOqL9o6X_c3Z1zTmwyNlCmmdrq7fpcbO0sQDiDipa20JI3B8iF_NAn_jMm7RDconQNipiY-NE3_zCTjvSf3M7gqfFHdyJfqyfwAifVn8-h2-RuQ6lw9M2miZ39yJcoDLFe8-nk/s1600/ex11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="195" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxFR7VRFOqL9o6X_c3Z1zTmwyNlCmmdrq7fpcbO0sQDiDipa20JI3B8iF_NAn_jMm7RDconQNipiY-NE3_zCTjvSf3M7gqfFHdyJfqyfwAifVn8-h2-RuQ6lw9M2miZ39yJcoDLFe8-nk/s400/ex11.png" width="400" /></a></div>
<br />
<b>Paso 12. </b>Verifica que el descuento se haya realizado y da clic en Next. <b>NOTA: Si aparece un mensaje de que ya no hay asientos disponibles, mala suerte. Recuerda que son limitados. Ya no podrás hacer el examen gratis :(</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitKGe_7vAQ4QTxIqrWnuYFtcH1HfRWtc9mnUeluwltRIccL6x57w81zogTTE7f0fMyB2SjmFJrY0Y3z77eYJ5cjxQrZ5MCPqi4AgMaUscuhxHEgWmPa8uJFM4MxKyLJqFFcwlAZ71HqUA/s1600/ex12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitKGe_7vAQ4QTxIqrWnuYFtcH1HfRWtc9mnUeluwltRIccL6x57w81zogTTE7f0fMyB2SjmFJrY0Y3z77eYJ5cjxQrZ5MCPqi4AgMaUscuhxHEgWmPa8uJFM4MxKyLJqFFcwlAZ71HqUA/s400/ex12.png" width="400" /></a></div>
<br />
<b>Paso 13. </b>Verifica que todos los datos sean correctos (nombre, centro de certificación, horario, fecha, costo).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEbkrfRfrOvvI0TrEU8TCn9Wv51wQ79xWQxrhim8cAuwaSgd_Yl6_pQD_dAPuOv7UBWxg8yAFXHV_5Xpvpfc1aOXcxuU7Pi7yfnr_4g6uY7yrpGMz7X3oiKNv1_LXyrKTrs9_JzFZGbXk/s1600/ex13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEbkrfRfrOvvI0TrEU8TCn9Wv51wQ79xWQxrhim8cAuwaSgd_Yl6_pQD_dAPuOv7UBWxg8yAFXHV_5Xpvpfc1aOXcxuU7Pi7yfnr_4g6uY7yrpGMz7X3oiKNv1_LXyrKTrs9_JzFZGbXk/s400/ex13.png" width="400" /></a></div>
<br />
<b>Paso 14. </b>¡Listo! Tu examen ha sido agendado. Se presenta un resumen de la operación.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgz1Vn9rUjqcD5c5NsWIaxgK4fmEr6X5NzRL3D-_J9C2Q8eHiFb6UFQYnjogRrPxYxg6ia0Iw_3AIVRqVWDs93sz6hN5ViyuQU3EgNtutwiA0iOERJEgNGY4yIt9F8RE2KbXR_CnYibFOY/s1600/ex14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgz1Vn9rUjqcD5c5NsWIaxgK4fmEr6X5NzRL3D-_J9C2Q8eHiFb6UFQYnjogRrPxYxg6ia0Iw_3AIVRqVWDs93sz6hN5ViyuQU3EgNtutwiA0iOERJEgNGY4yIt9F8RE2KbXR_CnYibFOY/s400/ex14.png" width="400" /></a></div>
<br />
<b>Paso 15. </b>Y además recibes un par de correos. El primero te muestra los detalles del examen de certificación y algunas reglas. La más importante es que tienes que llevar 2 identificaciones oficiales, si no no podrás realizar el examen (Credencial de Elector, Pasaporte, Visa, licencia de manejo).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMxVI4ew-gk8WTb34A0tf0yNGJNEzq-GQvVC_1hyBJxPBvmrVPpZUW3wWbGVFWolgWDAFQm9RsP-2eVvARMoQQ8VVxlOV_9u763EJ4pvd9yfbrQt3XrtlH_n1LquAd-XL4CUxx6FQeeNI/s1600/ex15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="376" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMxVI4ew-gk8WTb34A0tf0yNGJNEzq-GQvVC_1hyBJxPBvmrVPpZUW3wWbGVFWolgWDAFQm9RsP-2eVvARMoQQ8VVxlOV_9u763EJ4pvd9yfbrQt3XrtlH_n1LquAd-XL4CUxx6FQeeNI/s400/ex15.png" width="400" /></a></div>
<br />
<b>Paso 16. </b>El segundo correo es un detalle del pago efectuado (por 0 dólares).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUSnVcp8bFpEewpYiVjcgNR8tF_KHtBKWxGGzlA5CvvXgbpKcaruzzYAPLklTSEImdMGzcMX0h1LZ6ycapvI-BD8ZlU5vT04E3SKGJKzHiydzGzZ8DsX2kGtz85EwWyL4EYLEturt0SEk/s1600/ex16.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="376" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUSnVcp8bFpEewpYiVjcgNR8tF_KHtBKWxGGzlA5CvvXgbpKcaruzzYAPLklTSEImdMGzcMX0h1LZ6ycapvI-BD8ZlU5vT04E3SKGJKzHiydzGzZ8DsX2kGtz85EwWyL4EYLEturt0SEk/s400/ex16.png" width="400" /></a></div>
<div>
<br /></div>
<div>
Espero que esta guía e información te haya sido útil. Compártela con tus amigos si fue así :)</div>
<div>
<br /></div>
<div>
Saludos y éxito con la preparación del examen. Si en algo te puedo ayudar, coméntame de favor.</div>
<div>
<br /></div>
<div>
¡Hasta luego!</div>
Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com0tag:blogger.com,1999:blog-8407795827837136717.post-60338842570061541262017-01-27T06:33:00.000-08:002017-02-08T01:00:10.032-08:00¡Regístrate al #XamarinDiplomado y continúa con tu aprendizaje!Después del éxito obtenido gracias a la iniciativa de <b>Microsoft Latinoamérica</b> y a los <b>Xamarin MVPs de Latinoamérica</b>, regresa el <a href="https://twitter.com/search?q=%23XAMARINDIPLOMADO" target="_blank"><b>#XamarinDiplomado</b></a> ahora en su <b>Nivel Intermedio </b>y en esta ocasión orientado a <b>Conectar apps móviles a la nube. </b>Nuevamente, contaremos con el inigualable apoyo y los conocimientos de los Xamarin MVPs de Latinoamérica <b><a href="http://www.hjr.com.mx/" target="_blank">Humberto Jaimes</a></b>, <b><a href="http://stvansolano.github.io/blog/" target="_blank">Esteban Solano</a> </b>y <a href="http://www.enriqueaguilarvargas.com/" style="font-weight: bold;" target="_blank">Enrique Aguilar</a>. A esta iniciativa se suma el experto <b><a href="https://github.com/rcervantes-dev" target="_blank">Roberto Cervantes</a></b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEievDK3WBvMeajd3u0F865LniwHuYGaXnPvuIN_FR-bnmrhCO-9Tl8ZxIrCipxd2OC05fhbRmoxHXXWqHMuoxwAhMsBoAT2P4VxgoDd7gT2jsBKF806ZhXxyzlkLavD62kHkpekl581_zo/s1600/xamdip.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="132" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEievDK3WBvMeajd3u0F865LniwHuYGaXnPvuIN_FR-bnmrhCO-9Tl8ZxIrCipxd2OC05fhbRmoxHXXWqHMuoxwAhMsBoAT2P4VxgoDd7gT2jsBKF806ZhXxyzlkLavD62kHkpekl581_zo/s400/xamdip.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Al igual que el diplomado básico, es en español, totalmente gratuito y al finalizarlo obtendrás un reconocimiento digital oficial otorgado por Microsoft donde avala que cumpliste con las actividades del diplomado (en caso de acreditar, por supuesto).<br />
<br />
El curso, impartido en la modalidad de aula virtual, consta de 4 módulos repartidos en 4 semanas, en los cuales los expertos te guiarán con sus conocimientos para que aprendas diferentes temas relacionados con Xamarin y Azure. Mediante videos, podrás seguir sus explicaciones y prácticas donde demostrarán cómo conectar tus aplicaciones móviles a la nube.<br />
<br />
Los 4 módulos del curso son:<br />
<br />
<b>Módulo 1 - Acceso a Azure Storage (Blobs y Tablas NoSQL) con Xamarin.iOS y Xamarin.Android</b><br />
Impartido por <a href="https://twitter.com/enriqueaguilar" target="_blank"><b>Enrique Aguilar</b></a> en la semana del 30 de Enero<br />
<br />
<b>Módulo 2 - HockeyApp para manejar betas</b><br />
Impartido por <b><a href="http://twitter.com/stvansolano" target="_blank">Esteban Solano</a></b> en la semana del 6 de Febrero<br />
<br />
<b>Módulo 3 - Xamarin.UITest y Xamarin.TestCloud</b><br />
Impartido por <b><a href="https://twitter.com/hjaimesdev" target="_blank">Humberto Jaimes</a></b> en la semana del 13 de Febrero<br />
<br />
<a name='more'></a><br /><br />
<b>Módulo 4 – Mobile DevOps con Visual Studio Team Services y Xamarin</b><br />
Impartido por <b><a href="https://twitter.com/rob_cervantes" target="_blank">Roberto Cervantes</a></b> en la semana del 20 de Febrero<br />
<br />
¡Aprovecha esta oportunidad e inscríbete llenando el formulario que encuentras <a href="https://www.microsoftevents.com/profile/form/index.cfm?PKformID=0x1280639bef3" target="_blank"><b>aquí</b></a>! Una vez inscrito, revisa tu bandeja de entrada, pues recibirás un correo donde te indicarán los pasos a seguir para finalizar tu registro. O directamente regístrate <b><a href="http://ticapacitacion.com/registro/xamarinlt2" target="_blank">en este enlace</a> </b>(si ya tienes cuenta en TI Capacitación, ingresa tus credenciales; en caso contrario, crea una cuenta nueva ahí mismo).<br />
<br />
Notas (disponibles en <b><a href="http://ticapacitacion.com/curso/xamarinlt2/" target="_blank">este enlace</a></b>):<br />
<br />
<ul>
<li>El curso finaliza el 26 de Febrero y el material estará disponible hasta 2 semanas después de finalizado el curso (después de eso, no se podrá acceder al material)</li>
<li>Tienes hasta el 12 de Marzo para entregar tu evidencia y tener derecho al diploma (más información, posteriormente)</li>
<li>Habrá sesiones en línea de apoyo en vivo con los instructores del curso para despejar dudas</li>
<li>Puedes acceder al aula virtual en el horario que te sea más cómodo, pues está disponible 24/7</li>
<li>El material del Diplomado Básico de Xamarin estará disponible en la sección Recursos de consulta dentro del aula virtual.</li>
<li>Revisa la sección de Requerimientos técnicos para conocer cómo configurar tu entorno de desarrollo, entre otras cosas, crear una cuenta de Azure, HockeyApp, Xamarin Test Cloud y Visual Studio Team Services, además de obviamente Xamarin.</li>
<li>Aquí tienes una <b><a href="https://msmdotnet.wordpress.com/2016/10/19/hello-xamarin-hands-on-lab/" target="_blank">guía</a></b> para instalar Xamarin.</li>
</ul>
<br />
<br />
Te deseo mucho éxito en este nuevo diplomado y si tienes alguna duda, con mucho gusto te puedo ayudar. También te comento que en Facebook tenemos un grupo de estudio para apoyo durante el diplomado, el cual tiene más de 1500 miembros, entre ellos los instructores del curso y más expertos de diferentes países de Latinoamérica. Solicita tu acceso al <b><a href="https://www.facebook.com/groups/xamarindiplomadoitc/" target="_blank">grupo de Facebook</a></b>, no tenemos galletas, pero la pasamos bien =)<br />
<br />
¡Saludos y éxito!Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com0tag:blogger.com,1999:blog-8407795827837136717.post-3972321892520929572016-09-20T05:59:00.000-07:002020-04-01T04:06:49.607-07:00Conectando una app de Xamarin con SQL Server<div style="text-align: justify;">
ACTUALIZACIÓN: Esta publicación NO es la forma recomendada de comunicar una app móvil con una base de datos. El esquema ideal es crear un Web Api que se conecta a tu base de datos, exponiendo métodos que serán accesibles para tu aplicación móvil. Dicho lo anterior, esta publicación es un mero ejercicio ilustrativo y NO se recomienda para producción sobre todo por esquemas de seguridad.<br />
<br />
<b><a href="https://www.luisbeltran.mx/2019/11/27/tutorial-basico-de-asp-net-core-mvc/" target="_blank">Aquí</a></b> tienes un ejemplo de cómo hacerlo con SQL Server (solo quedaría publicarlo y accederlo desde Xamarin) y <a href="https://www.youtube.com/watch?v=6ysRCkvmpZo" target="_blank"><b>aquí</b></a> va otro ejemplo con MySQL<br />
<br />
---------------------------------------<br />
De verdad, de verdad...<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFrH_OnyMY0m_eulH2B4OKsFK7S0_ASaJlpQNHBpfR35sVfQJgUC47X9VGGZJJH39hHLuO1ThJxQe4VYgUx3bR077dXo0w_gLYEAWym7UF3cPko0q41sJSt7vmPYaxFzW8y_dpEwz52-4/s1600/nolohagacompa.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="298" data-original-width="358" height="266" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFrH_OnyMY0m_eulH2B4OKsFK7S0_ASaJlpQNHBpfR35sVfQJgUC47X9VGGZJJH39hHLuO1ThJxQe4VYgUx3bR077dXo0w_gLYEAWym7UF3cPko0q41sJSt7vmPYaxFzW8y_dpEwz52-4/s320/nolohagacompa.png" width="320" /></a></div>
<br />
---------------------------------------<br />
<br />
¡Hola! En la semana me preguntaron acerca de cómo conectar una base de datos <b>SQLServer </b>en una red local con una app móvil en <b>Xamarin</b>, lo cual es posible a través de la clase <b>SQLConnection </b>que se encuentra en el espacio de nombres <b>System.Data </b>pero nunca lo había hecho, así que me dí a la tarea de intentarlo ayer porque es interesante. A continuación, les comparto la experiencia por si les sirve en alguna ocasión.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b>Parte 1. Creación de la base de datos, tablas e información</b></div>
<div style="text-align: justify;">
Inicia <b>SQL Server Management Studio</b>. En mi caso, tengo instalado SQL Server 2012, pero no debería haber diferencia si utilizas otra versión.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Para este ejemplo, he creado la base de datos Empresa con la tbla Empleados. Le he agregado 3 registros. Fácil, ¿no?</div>
<div style="text-align: justify;">
<br /></div>
<pre class="brush:sql;first-line:1">CREATE DATABASE Empresa
GO
USE Empresa
GO
CREATE TABLE Empleados(
ID INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
Nombre VARCHAR(100) NOT NULL,
Salario DECIMAL(12, 4) NOT NULL
)
INSERT INTO Empleados VALUES ('Ana Mendez', 7812.45)
INSERT INTO Empleados VALUES ('Juan Pérez', 10000.51)
INSERT INTO Empleados VALUES ('Raúl Rico', 4703.12)
</pre>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b>Parte 2. Inicio de sesión y Configuración del servidor</b></div>
<div style="text-align: justify;">
A fin de que otros dispositivos se puedan conectar a nuestra base de datos a través de aplicaciones (en este caso, una app móvil), tenemos que configurar ciertos permisos en el servidor.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b>a) Inicio de sesión</b></div>
<div style="text-align: justify;">
El primer paso es que SQL Server acepte la autenticación mixta (la que nos interesa en realidad es la autenticación de SQL Server, no tanto la de Windows).</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifOv61UkFH98fNz9BesDsDJTzaN1ibo_Zrl8ub__VmR_Vp3Q9XUKaJFwMzc2ybf1nPR54VZWfHWYdubdqbPyzn2UGGXEIKzMg6gm3sBJcOsTR0DyYwUdiBidguFcQYMzwOC8YNcWFnmJo/s1600/sql01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="243" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifOv61UkFH98fNz9BesDsDJTzaN1ibo_Zrl8ub__VmR_Vp3Q9XUKaJFwMzc2ybf1nPR54VZWfHWYdubdqbPyzn2UGGXEIKzMg6gm3sBJcOsTR0DyYwUdiBidguFcQYMzwOC8YNcWFnmJo/s320/sql01.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Esta propiedad se establece cuando instalas SQL Server, pero si elegiste la autenticación de Windows, simplemente realiza lo siguiente:</div>
<div style="text-align: justify;">
<br />
<a name='more'></a><br /></div>
<div style="text-align: justify;">
En <b>SQL Server Management Studio </b>inicia sesión. Da <b>clic derecho </b>en el nombre del servidor y selecciona <b>Propiedades</b>.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpvhFghlXxE1iPfr7rV_CX4qf0ZBZL5PrukpVAYeXD4k4pXanXqOANV4TTvCj-KN3Giw87sUyOq7Xjg8fzKMMevLVQk2WWH8y23LwgddLHRLHrPY3d4nW1C_nge2uwrVilT0TsuoRLV3g/s1600/sql02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpvhFghlXxE1iPfr7rV_CX4qf0ZBZL5PrukpVAYeXD4k4pXanXqOANV4TTvCj-KN3Giw87sUyOq7Xjg8fzKMMevLVQk2WWH8y23LwgddLHRLHrPY3d4nW1C_nge2uwrVilT0TsuoRLV3g/s320/sql02.png" width="301" /></a></div>
<br />
<div style="text-align: justify;">
En la página <b>Seguridad, </b>modifica la propiedad <b>Autenticación de servidor </b>y establece su valor en <b>Autenticación de SQL Server y Windows</b>. Da clic en <b>OK</b>.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBOny6xd8hiuYDxpqeNyguQgxf1vWWKwa98pKK4AP6nSQFNK_VB7anC-68NdyidvyZ6YklNK1wHwL662xav5UOZ9BqjYorQKC9u0EY0KmFtkjH-bKRx9GYmsHvU5J9xYOTQ4xx-z4iSDQ/s1600/sql03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="287" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBOny6xd8hiuYDxpqeNyguQgxf1vWWKwa98pKK4AP6nSQFNK_VB7anC-68NdyidvyZ6YklNK1wHwL662xav5UOZ9BqjYorQKC9u0EY0KmFtkjH-bKRx9GYmsHvU5J9xYOTQ4xx-z4iSDQ/s320/sql03.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Es probable que te pida un reinicio del servicio de SQL Server. Acepta y espera. Una vez reiniciado, inicia sesión nuevamente. Ahora expande el panel del servidor y da <b>clic derecho </b>en <b>Inicios de sesión </b>dentro <b>de </b>Seguridad. Elige la opción <b>Nuevo inicio de sesión</b>:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrm7xrIYBLxXtsKHehyTytJZEauh-Y8Yv3f9NPFXgTnybeuorm5TtKf_tpE9jMETg84E_M37F2Ft0J3L4-Cy-QelVx18tMEjFk29ydiW3mqSxo0iT2I0780H07ByJQW7KZcjhCkVQOZ58/s1600/sql04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="205" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrm7xrIYBLxXtsKHehyTytJZEauh-Y8Yv3f9NPFXgTnybeuorm5TtKf_tpE9jMETg84E_M37F2Ft0J3L4-Cy-QelVx18tMEjFk29ydiW3mqSxo0iT2I0780H07ByJQW7KZcjhCkVQOZ58/s320/sql04.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
En la página <b>General, </b>escribe un <b>inicio de sesión</b>, selecciona <b>Autenticación de SQL Server</b>, coloca y confirma una <b>contraseña</b>. Desmarca los 3 checkboxes de <b>opciones de contraseña</b>. Selecciona la base de datos <b>Empresa </b>y accede a la página <b>Roles de servidor</b>:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4VqMqt57v93XuuCqXHh8fWNrw2iz1k-ozawEiY9y_Pj0Bf4AUqcjoGW84kxZhMLPgZ3vpjtL9ozcZGdydQ7XotCQ697rCqUNLIyf9UTbTClzVyRsrk2XsjyF5KkPN51AioiEtbon_MhI/s1600/sql05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="288" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4VqMqt57v93XuuCqXHh8fWNrw2iz1k-ozawEiY9y_Pj0Bf4AUqcjoGW84kxZhMLPgZ3vpjtL9ozcZGdydQ7XotCQ697rCqUNLIyf9UTbTClzVyRsrk2XsjyF5KkPN51AioiEtbon_MhI/s320/sql05.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
En <b>Roles de Servidor</b>, asigna los <b>privilegios </b>que este usuario tendrá. Ahora accede a la página <b>Mapeo de Usuario</b>:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPpAUaM-vFyxj1R7JQhFXvUOnCK6sgIUbhCxmy7cKobMmNpLoZqVWijHJsMWIltkUtXdvXJcGT9FsgUXaMPRwuE4v5YNs7RaNOQSMhaTGtuJnGmPhINrrWKGE9uAiLScBLYDUkhHyl-JA/s1600/sql06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="288" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPpAUaM-vFyxj1R7JQhFXvUOnCK6sgIUbhCxmy7cKobMmNpLoZqVWijHJsMWIltkUtXdvXJcGT9FsgUXaMPRwuE4v5YNs7RaNOQSMhaTGtuJnGmPhINrrWKGE9uAiLScBLYDUkhHyl-JA/s320/sql06.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
En <b>Mapeo de Usuario</b>, marca la base de datos <b>Empresa</b>, escribe el <b>login </b>que acabas de crear y asigna el esquema <b>dbo</b>. Accede a la página <b>Status</b>:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwcwO0qPafDs7nU_6706CsAKLugIXUGM0fai3SE07UYH8rcG_E6ebbAaihtxIS0KOGZn7hkxvwEad2d2rycfhMrXGR65NuEHK5MXGuCL-_b77QQXKuJRzEBu9CK4AW2O9ORVuDNHL84MQ/s1600/sql07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="288" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwcwO0qPafDs7nU_6706CsAKLugIXUGM0fai3SE07UYH8rcG_E6ebbAaihtxIS0KOGZn7hkxvwEad2d2rycfhMrXGR65NuEHK5MXGuCL-_b77QQXKuJRzEBu9CK4AW2O9ORVuDNHL84MQ/s320/sql07.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Finalmente, en <b>Status </b>verifica que el permiso de conexión al motor de base de datos está concedido (<b>Grant</b>) y que el inicio de sesión está activado (<b>Enabled</b>). Da clic en <b>OK</b>:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY29xWzqPg44-0cdVmsX4cgE_XLK41KSAjQmXdYlQkt-fQ7Qb-CQlyuCLOHSBd2wRkU6HObP4wZ74AVR6zStnR87eCm4Q8MTEynataay9yJln9VKPOzizmzuC4GLE-bFlM2j6fZYrih_0/s1600/sql08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="288" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY29xWzqPg44-0cdVmsX4cgE_XLK41KSAjQmXdYlQkt-fQ7Qb-CQlyuCLOHSBd2wRkU6HObP4wZ74AVR6zStnR87eCm4Q8MTEynataay9yJln9VKPOzizmzuC4GLE-bFlM2j6fZYrih_0/s320/sql08.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Ahora intenta realizar una conexión con el inicio de sesión que has creado. Si es correcto, procederemos a configurar el servidor.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8f2P_Agt18OBfbHlPveQLbE22bK30gqRB142RDfKtgr2R-e38uX5fJN4Vu_8d37whP4LHt9iVakMztWqR1_u2YsPxOXuL6-mT1nC4-zV9Ee7e2BsjojqCSJZWXY1PMHWKwpB2vQ3xqBg/s1600/sql09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="142" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8f2P_Agt18OBfbHlPveQLbE22bK30gqRB142RDfKtgr2R-e38uX5fJN4Vu_8d37whP4LHt9iVakMztWqR1_u2YsPxOXuL6-mT1nC4-zV9Ee7e2BsjojqCSJZWXY1PMHWKwpB2vQ3xqBg/s320/sql09.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
<b>b) Configuración de servidor:</b></div>
<div style="text-align: justify;">
Inicia el <b>Administrador de configuración de SQL Server</b>:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhigPcqOwk7lxFZ-41I5T82TV114vk96D335LmpsmbZCmu0JoXhqzRcfiIdjtjFT3OLwxwD-4_cNWsGA1PIUYDPOtkGEXaVWjmN2Gi8M1Y4LGKqQekZ7o9DkqJoJUImCe2pBQmZCJNEe8o/s1600/12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="151" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhigPcqOwk7lxFZ-41I5T82TV114vk96D335LmpsmbZCmu0JoXhqzRcfiIdjtjFT3OLwxwD-4_cNWsGA1PIUYDPOtkGEXaVWjmN2Gi8M1Y4LGKqQekZ7o9DkqJoJUImCe2pBQmZCJNEe8o/s320/12.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
En cada una de las siguientes categorías habilita el servicio <b>TCP/IP</b> (da clic derecho y selecciona <b>Habilitar</b>): <b>Protocolos de cliente</b> (dentro de Configuración de SQL Native Client 11.0 32 bits), <b>Protocolos de <servidor></servidor></b> y <b>Protocolos de cliente</b> (dentro de Configuración de SQL Native Client 11.0):</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmZ0euymOnKB41reRtId2Z4UiZXGUzWgHNmeIF7i6ZfuFc-jJ-TBW392xNCsph3bRBuQESL_EICpjxWr6fAw3zWZ-h47Omqxw0SWQ_4MEfW66CuUr5OmE8ad3Gc2ZHxmiNu3c0E02LWf4/s1600/13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="129" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmZ0euymOnKB41reRtId2Z4UiZXGUzWgHNmeIF7i6ZfuFc-jJ-TBW392xNCsph3bRBuQESL_EICpjxWr6fAw3zWZ-h47Omqxw0SWQ_4MEfW66CuUr5OmE8ad3Gc2ZHxmiNu3c0E02LWf4/s320/13.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Inicia el servicio <b>SQL Server Browser</b>. Lo puedes hacer en la pestaña <b>Servicios de SQL Server</b> o desde <b>Panel de Control -> Servicios</b>:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF3T3jPsrDMLkn2U8SJW2hyOBj1zp04S0k6HPGpxgIp_g9goZV94S-o0UQCT7dGpvsLs3zN-Kl_R67bh7XCqrFhSvEM_mwxKsirl8lcyhSC6NZH9bSnPaOsiX0sR_qJuoOkzKJoYtz-lU/s1600/14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="59" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF3T3jPsrDMLkn2U8SJW2hyOBj1zp04S0k6HPGpxgIp_g9goZV94S-o0UQCT7dGpvsLs3zN-Kl_R67bh7XCqrFhSvEM_mwxKsirl8lcyhSC6NZH9bSnPaOsiX0sR_qJuoOkzKJoYtz-lU/s320/14.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
<b>Reinicia </b>el servicio de SQL Server a fin de autorizar los cambios recién realizados:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjk-teTxmiIgYLXuDgGV_xeo2B3igXrEdNk0pV0kB81Ui9j32UPYyWIBdt5Mba9droRZYeBYQGZZCk3UEO9AcY1TjIUAeKYozSWiqYEDI9OzOnxcktm9QpHgCZQ0_67WT9b7y4gf4eMNxk/s1600/15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="125" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjk-teTxmiIgYLXuDgGV_xeo2B3igXrEdNk0pV0kB81Ui9j32UPYyWIBdt5Mba9droRZYeBYQGZZCk3UEO9AcY1TjIUAeKYozSWiqYEDI9OzOnxcktm9QpHgCZQ0_67WT9b7y4gf4eMNxk/s320/15.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Para que el servidor sea visible por otros dispositivos, es necesario dar de alta <b>4 reglas en el firewall de Windows</b> (si utilizas otro firewall, los pasos pueden variar). Accede a la <b>Configuración avanzada</b> del Firewall:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtr9UBrEOVT7VuX2uqObXtgKOVwv6ULI7sfUUTqh_V44hl8mvsThq5XzENqsk7KV0_JsmbZXuXG4JKMxaxzcn5ldLxhgVeCTB6lKTXP0bBkmoFkKmHc1Wg_2mhbOZZCY239HPu7YJ2Akk/s1600/16.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="166" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtr9UBrEOVT7VuX2uqObXtgKOVwv6ULI7sfUUTqh_V44hl8mvsThq5XzENqsk7KV0_JsmbZXuXG4JKMxaxzcn5ldLxhgVeCTB6lKTXP0bBkmoFkKmHc1Wg_2mhbOZZCY239HPu7YJ2Akk/s320/16.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Selecciona <b>Nueva regla </b>en la categoría Reglas <b>de entrada</b>:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsZiHuDnE3tHa0ZpdvXKNd3r-h81_lHI1otq_nm__suF_leYHYzgf3uSZNwJ3KJOjq5AYtJnaERyg4EvWbshmNlnvrp1TEK1GYavyCWU1v6O14De7W49pFpo0jWrsBBaRzE8zgPgl5liY/s1600/17.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="90" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsZiHuDnE3tHa0ZpdvXKNd3r-h81_lHI1otq_nm__suF_leYHYzgf3uSZNwJ3KJOjq5AYtJnaERyg4EvWbshmNlnvrp1TEK1GYavyCWU1v6O14De7W49pFpo0jWrsBBaRzE8zgPgl5liY/s320/17.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
La primer regla servirá para autorizar un <b>Puerto</b>. Da clic en Siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhP0aHar_PzHHiUkG1C9rXrjy2_1jc909xhDm19JPhhYUPZVhi96LLL8nMEssMhA8oVNhNxBHn7aDEswAOH6AJ-doS8a4v89JMRLW9DVb3yK_tfh3asrOFLuk7xNOrlC4XlCfI5h81CcNI/s1600/18.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="257" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhP0aHar_PzHHiUkG1C9rXrjy2_1jc909xhDm19JPhhYUPZVhi96LLL8nMEssMhA8oVNhNxBHn7aDEswAOH6AJ-doS8a4v89JMRLW9DVb3yK_tfh3asrOFLuk7xNOrlC4XlCfI5h81CcNI/s320/18.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
El tipo de puerto es <b>TCP</b>, específicamente el <b>1433</b>. Da clic en Siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDqdI0tK9RgL3USeacAUzRBJnl4ZDNhHtB1GgWIGBPzB6jvRwpJwXsOUSMeLsbUmtauWXBklxL46LUOShR02jrMfWmbZKYE-d1TSR2nAzqh6VXQqQYrv0jmPQpteIsUgPww4OiDfggvN8/s1600/19.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDqdI0tK9RgL3USeacAUzRBJnl4ZDNhHtB1GgWIGBPzB6jvRwpJwXsOUSMeLsbUmtauWXBklxL46LUOShR02jrMfWmbZKYE-d1TSR2nAzqh6VXQqQYrv0jmPQpteIsUgPww4OiDfggvN8/s320/19.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
<b>Permite la conexión</b>. Da clic en Siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQaoKRL45l7vK9eMyj5ZX1uh4w2y34DvxafaMhksFgUWfQ4g6b2TGzuFjpxiWESVHKume2RabHdqOnPI7eL1mAXVxrTM99ZAxrbjQoC4bDviMcAAz7KgauqnTWmcVN8nurSrOFr2x2ocQ/s1600/20.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQaoKRL45l7vK9eMyj5ZX1uh4w2y34DvxafaMhksFgUWfQ4g6b2TGzuFjpxiWESVHKume2RabHdqOnPI7eL1mAXVxrTM99ZAxrbjQoC4bDviMcAAz7KgauqnTWmcVN8nurSrOFr2x2ocQ/s320/20.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Selecciona los <b>tres tipos </b>de redes. Da clic en Siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgG6bRy0qS2djSLN9DiCYg3lEPMgRcLp44WJ3Rxk1cJFnhfdnAsOVYv5-HKc9juk_hWXoJPrDFf6Cf_tSj7R2KOBJAe8_YRzR00Mr04GAurf1D1GymFMpEnqNxmh3U3c-poy62CoZzs6tQ/s1600/21.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="259" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgG6bRy0qS2djSLN9DiCYg3lEPMgRcLp44WJ3Rxk1cJFnhfdnAsOVYv5-HKc9juk_hWXoJPrDFf6Cf_tSj7R2KOBJAe8_YRzR00Mr04GAurf1D1GymFMpEnqNxmh3U3c-poy62CoZzs6tQ/s320/21.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Asigna un nombre a la primer regla, por ejemplo <b>SQL - TCP 1433</b>. Da clic en Finalizar:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi14TAtraTad2RuxrEmPsEKJCp3GnqeAi6HIlYsw732MhkG8SKHmlOgG4QWdtRjVlX4dv4iQy5lA5rupKcWcWlpPymgkn03XpVIar5zgiZbTPCoAT02qaLNQ43qF6c6Jxbzj3ut1RgrMDE/s1600/22.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="259" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi14TAtraTad2RuxrEmPsEKJCp3GnqeAi6HIlYsw732MhkG8SKHmlOgG4QWdtRjVlX4dv4iQy5lA5rupKcWcWlpPymgkn03XpVIar5zgiZbTPCoAT02qaLNQ43qF6c6Jxbzj3ut1RgrMDE/s320/22.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
<b>Agrega otra regla</b>. La segunda regla servirá para autorizar otro <b>Puerto</b>. Da clic en Siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXU6VJwo8a9mcVSGujswURvovopXsByWa5ac3svrJfcuoJ00A-vVEB5x2qNa9ORCNjMLoirV6hZCPyZwFBcNuKgayWF1Jzca2j0bEbyFwSTFUaMMDrthNWdfUtKyUB3fKWTbDjXIIiCPM/s1600/23.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXU6VJwo8a9mcVSGujswURvovopXsByWa5ac3svrJfcuoJ00A-vVEB5x2qNa9ORCNjMLoirV6hZCPyZwFBcNuKgayWF1Jzca2j0bEbyFwSTFUaMMDrthNWdfUtKyUB3fKWTbDjXIIiCPM/s320/23.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Ahora selecciona <b>UDP </b>en tipo y especifica el puerto <b>1434</b>. Da clic en Siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn0DyxwqwZMjKkBktu4XdMyPXQL0kN7nzL_Z10yhuq7i1guUXH16zD5FgL7DkrLkjZFe5wCgJhuT9_FawmS331Mmcq0JzDJt2ciTGlAFrVyYq6Jd3pORKxSqfrlQLbX9cuNUrlx_QgbiU/s1600/24.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="259" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn0DyxwqwZMjKkBktu4XdMyPXQL0kN7nzL_Z10yhuq7i1guUXH16zD5FgL7DkrLkjZFe5wCgJhuT9_FawmS331Mmcq0JzDJt2ciTGlAFrVyYq6Jd3pORKxSqfrlQLbX9cuNUrlx_QgbiU/s320/24.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
<b>Permite la conexión</b>. Da clic en Siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8WrTtKCGyC4puncPsGCO4TnHp6Qjcq6RySDSIirADMLVlo8eDTb1JX3DYHaimKNwVea37iEpXF1w4BvK0Votb-yqwzcnDxYYj371_rWqKs_FFW5BD2uzaSwehN4a1KY7DNna4U-ur0w0/s1600/25.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8WrTtKCGyC4puncPsGCO4TnHp6Qjcq6RySDSIirADMLVlo8eDTb1JX3DYHaimKNwVea37iEpXF1w4BvK0Votb-yqwzcnDxYYj371_rWqKs_FFW5BD2uzaSwehN4a1KY7DNna4U-ur0w0/s320/25.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Selecciona los <b>tres tipos </b>de redes. Da clic en Siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4drWSR6NCmdP80ksXoA9jecSDBmgp0RhwTZsgqXXfDjMBJvU_-nqBJZJ_1rNzom3-CqRZohPMDehHA5daOZvw_ZCWoaWZGJAOORzvaSvGd2m8QzVnw1mB3eJEWFNV74a0fwi-54dMhyM/s1600/26.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="259" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4drWSR6NCmdP80ksXoA9jecSDBmgp0RhwTZsgqXXfDjMBJvU_-nqBJZJ_1rNzom3-CqRZohPMDehHA5daOZvw_ZCWoaWZGJAOORzvaSvGd2m8QzVnw1mB3eJEWFNV74a0fwi-54dMhyM/s320/26.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
El nombre de esta regla es <b>SQL - UDP 1434</b>. Da clic en Finalizar:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXyHKJMybIE0X0dxK5UQEk2ho5LDL4PSptLJXzVTX4qcDv2MQ4XfNYmZMmhMfizRQr1chpuTdQvFFRYVKal6WUlCNXzCQ3vZJIWydDyu0MVcUY5b0LCfuLxbAupapjqKzG85rJDBPlp7k/s1600/27.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="259" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXyHKJMybIE0X0dxK5UQEk2ho5LDL4PSptLJXzVTX4qcDv2MQ4XfNYmZMmhMfizRQr1chpuTdQvFFRYVKal6WUlCNXzCQ3vZJIWydDyu0MVcUY5b0LCfuLxbAupapjqKzG85rJDBPlp7k/s320/27.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
<b>Agrega una tercer regla</b>, la cual ahora será de tipo <b>Programa</b>. Da clic en Siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyxVBl4KaaICo6wS3m9gs0DlFcOnjgU4bVWjmZjz_xE9K5yWtjOD0GyuQ2EKRT2Bsfhw3tPKmzTdTHvbuqmN9lzY_wL9y9MSzAD4cYi2Sy0jh0EimmnpUiZ5O2C_NvwqrxlQlfk0KyS6o/s1600/28.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyxVBl4KaaICo6wS3m9gs0DlFcOnjgU4bVWjmZjz_xE9K5yWtjOD0GyuQ2EKRT2Bsfhw3tPKmzTdTHvbuqmN9lzY_wL9y9MSzAD4cYi2Sy0jh0EimmnpUiZ5O2C_NvwqrxlQlfk0KyS6o/s320/28.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Selecciona <b>ruta de acceso del programa</b>. Localiza la aplicación <b>sqlservr.exe</b> que está localizada en <b>C:/Program Files/ Microsoft SQL Server/<instancia>/MSSQL/Binn</instancia></b>. Da clic en Abrir:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwAUMeExTrd6wOi6YPIFEuZxJPbJ3sLeFxhiZYp95q1RD1jPfomQYmXh4lOA8IApooa-4aFUC2RwuUib-JR19VTLCTO-rktOLbdQCFAxR-144HAdMI_Z26G_SzfNyn4_GfhyP4127rLNo/s1600/29.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwAUMeExTrd6wOi6YPIFEuZxJPbJ3sLeFxhiZYp95q1RD1jPfomQYmXh4lOA8IApooa-4aFUC2RwuUib-JR19VTLCTO-rktOLbdQCFAxR-144HAdMI_Z26G_SzfNyn4_GfhyP4127rLNo/s320/29.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
La ruta de acceso debería ser similar a la mostrada en la figura. Da clic en Siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikRFddUxaMl8wJKTgW5MlfJD4bSWY_DpA5RgzLv9ChJF55aEmE8y3MwBg0ZNNPY6scLzDgyl5WHzns1o6WSqUNPy_pz4K5jAcUdayJaQRR2GxJ5Wjz-oybI6kptARe-bOnEz-7aM3tcIk/s1600/30.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="257" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikRFddUxaMl8wJKTgW5MlfJD4bSWY_DpA5RgzLv9ChJF55aEmE8y3MwBg0ZNNPY6scLzDgyl5WHzns1o6WSqUNPy_pz4K5jAcUdayJaQRR2GxJ5Wjz-oybI6kptARe-bOnEz-7aM3tcIk/s320/30.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
<b>Permite la conexión</b>. Da clic en Siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6vR55NO9EC-D4dGhYcVSL73rbOTMzsXRnMuLd56lnZAnMV3RuELrr-weowXaDgSMzXK4A6ffvjfZFEb3kOodFT_I3g_FfJhixK_fyMF5NkDlWLv8CBx4d7WO88DWL7Z9qXJcYKc0IT5M/s1600/31.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="259" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6vR55NO9EC-D4dGhYcVSL73rbOTMzsXRnMuLd56lnZAnMV3RuELrr-weowXaDgSMzXK4A6ffvjfZFEb3kOodFT_I3g_FfJhixK_fyMF5NkDlWLv8CBx4d7WO88DWL7Z9qXJcYKc0IT5M/s320/31.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Selecciona los <b>tres tipos </b>de redes. Da clic en Siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiks2NFVJ3MIWaz2NhpktDeM1pZJvLl7_KHGOC61KSCI5rEYXqDXT1F4WNQhKv6tnfz8kOA963yMidMuj_9elvswmpIoyQ7dwKbR-KPkUxeUEep9NJqeO5jY_SiPtqjM5NMAbbKxLCFmb0/s1600/32.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiks2NFVJ3MIWaz2NhpktDeM1pZJvLl7_KHGOC61KSCI5rEYXqDXT1F4WNQhKv6tnfz8kOA963yMidMuj_9elvswmpIoyQ7dwKbR-KPkUxeUEep9NJqeO5jY_SiPtqjM5NMAbbKxLCFmb0/s320/32.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
El nombre de la tercer regla es <b>SQL - sqlservr.exe</b>. Da clic en Finalizar:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgobNkK78MVhYR_-JQUz4h0-ZkSmHMAuNqUvGFNa6FELhHnXxjmvx7loJrbKSSII-7nEsxtCXsx4wwMvUSS1y8uXBGBXsjJTQUf6HQdn2QhAVBk9uMWWahQK1AnSq-CJ1b_gqbyFzndODY/s1600/33.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgobNkK78MVhYR_-JQUz4h0-ZkSmHMAuNqUvGFNa6FELhHnXxjmvx7loJrbKSSII-7nEsxtCXsx4wwMvUSS1y8uXBGBXsjJTQUf6HQdn2QhAVBk9uMWWahQK1AnSq-CJ1b_gqbyFzndODY/s320/33.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Por último, <b>agrega una nueva regla</b> de tipo <b>Programa</b>. Da clic en Siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjevfgzuBW3Y-iX3fq2YlEVRmIvk0XeTEkIcH-zqfLsJvaWmAZ8ZYzicIrqlxgG_e4EQoTn9IKX_NpPV7ftl1yzyyUciuNJ2qtBrIOQx_e8M7y933CAfC7KkAuBmTeVf3zlUEnOerM8VqQ/s1600/34.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="259" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjevfgzuBW3Y-iX3fq2YlEVRmIvk0XeTEkIcH-zqfLsJvaWmAZ8ZYzicIrqlxgG_e4EQoTn9IKX_NpPV7ftl1yzyyUciuNJ2qtBrIOQx_e8M7y933CAfC7KkAuBmTeVf3zlUEnOerM8VqQ/s320/34.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
En <b>ruta de acceso del programa</b>, localiza <b>sqlbrowser.exe</b>, el cual se encuentra en <b>C:/Program Files(x86)/Microsoft SQL Server/90/Shared</b>:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeDWx0q_OPrLGKjrKbOWBCF9OlwU4NXewXVvMQuY9ca6Lhgfw94DJptp8tp-K8GpwA9_TAuRhcFCkgkFXx_4ckEd4UnDqaVdM_XO9y1KX6gkQLPMxlfFsC689DP34gzrcrXxtgEJDUc2o/s1600/35.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="167" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeDWx0q_OPrLGKjrKbOWBCF9OlwU4NXewXVvMQuY9ca6Lhgfw94DJptp8tp-K8GpwA9_TAuRhcFCkgkFXx_4ckEd4UnDqaVdM_XO9y1KX6gkQLPMxlfFsC689DP34gzrcrXxtgEJDUc2o/s320/35.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
La ruta de acceso será similar a la mostrada en la figura. Da clic en Siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQiaoj1K6aT8MMw2yPSV-bQXA2LBI2JhIc0dQm6oSyWs72D2dHNPc6mwv6fFqkJfEj9vO-jr0GTxGAehRUQAr_CbL1Mq50-47z3idgjbTb8F7pb_ktnpd114Eb04_yDGRjMxcTvhg0kjc/s1600/36.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="259" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQiaoj1K6aT8MMw2yPSV-bQXA2LBI2JhIc0dQm6oSyWs72D2dHNPc6mwv6fFqkJfEj9vO-jr0GTxGAehRUQAr_CbL1Mq50-47z3idgjbTb8F7pb_ktnpd114Eb04_yDGRjMxcTvhg0kjc/s320/36.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
<b>Permite la conexión</b>. Da clic en Siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6aHwJx9WDR-IVa7QF9aey28FQv7jxPplLNeazWokWr2MBJUSaXmovTPEUP2vQYNM3w_q58KBhHNFfwlUWEIpZkZvMLdDLUI4Knuy-Tq2PuasZ5X2xuVGWyiJkNSfF2GvlhJ4AO5OY5lE/s1600/37.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6aHwJx9WDR-IVa7QF9aey28FQv7jxPplLNeazWokWr2MBJUSaXmovTPEUP2vQYNM3w_q58KBhHNFfwlUWEIpZkZvMLdDLUI4Knuy-Tq2PuasZ5X2xuVGWyiJkNSfF2GvlhJ4AO5OY5lE/s320/37.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Selecciona los <b>tres tipos </b>de redes. Da clic en Siguiente:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhys-yx-om61cGmF3Q5ptfE2TO-NganajprAxvNmiLNaVqZKBVDqlvH9k0caSBSfvRCjiW5av3yqYz7XXhbcxY5P0in64BwqRXdiLQm9e1SI8xVwqlS1eL9cHkqQt1lS93KIpJdCxb9zCQ/s1600/38.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="259" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhys-yx-om61cGmF3Q5ptfE2TO-NganajprAxvNmiLNaVqZKBVDqlvH9k0caSBSfvRCjiW5av3yqYz7XXhbcxY5P0in64BwqRXdiLQm9e1SI8xVwqlS1eL9cHkqQt1lS93KIpJdCxb9zCQ/s320/38.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Por último, escribe un nombre para esta regla de entrada, por ejemplo, <b>SQL - sqlbrowser.exe</b>. Da clic en Finalizar:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_vqtdfwrkEbRX0vYfp8Iw6GlGp3VnJUt3d6LV2954LU2KLbgaOKwyOE-wfTcxqmN_ZRL010946ihv-rofqCjD1tT9CSLhnXpmCGNp6dj9V6LxwavHTBdjL2vNHKbrSoCJk6WswWSCDjY/s1600/39.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_vqtdfwrkEbRX0vYfp8Iw6GlGp3VnJUt3d6LV2954LU2KLbgaOKwyOE-wfTcxqmN_ZRL010946ihv-rofqCjD1tT9CSLhnXpmCGNp6dj9V6LxwavHTBdjL2vNHKbrSoCJk6WswWSCDjY/s320/39.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Al final, tendrás <b>cuatro reglas de entrada en tu Firewall</b>, las cuales permitirán <b>conexiones entrantes </b>a tu servidor <b>SQL Server</b>:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSELTzHxPvEQGl7-kF30S58NpXIQBumUMA7rDcvcPoqjOkbdxPGwWx0A2762CxoLpKaOBR0Wxs1V5CsoFo3w6kGvRCFMuzmid-COkjXAYQL0_gCsbw2R07uJ2jZIvYqnNeLNksVvr3Ogg/s1600/40.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="54" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSELTzHxPvEQGl7-kF30S58NpXIQBumUMA7rDcvcPoqjOkbdxPGwWx0A2762CxoLpKaOBR0Wxs1V5CsoFo3w6kGvRCFMuzmid-COkjXAYQL0_gCsbw2R07uJ2jZIvYqnNeLNksVvr3Ogg/s320/40.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="text-align: justify;">
<b>Parte 3. Código de Xamarin</b></div>
<div style="text-align: justify;">
¡Ahora vamos con el código!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Abre Visual Studio 2015. Crea una nueva aplicación vacía de tipo <b>Xamarin.Forms Shared</b>, localizado en la categoría <b>Cross-Platform. </b>El nombre de la app es <b>XamarinSQL</b>:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKdQ2WUnggJzhHYgjQmv6PITCfLIXQ7Bp73pyuMIYLN13XnPBBcmnfUS_PVtmZoyePJaJc0AOqO72coxShsmMrc4qGmhnxN_bsci2XfkxjFyeb2IWZ1ITjbvL31z5XVeRluLRTf_vkUfU/s1600/01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKdQ2WUnggJzhHYgjQmv6PITCfLIXQ7Bp73pyuMIYLN13XnPBBcmnfUS_PVtmZoyePJaJc0AOqO72coxShsmMrc4qGmhnxN_bsci2XfkxjFyeb2IWZ1ITjbvL31z5XVeRluLRTf_vkUfU/s320/01.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Descarga estas <a href="https://github.com/icebeam7/CelayaMeetups/tree/master/2016-09-02/Imagenes" target="_blank">3 imágenes</a>, las cuales serán utilizadas en el Toolbar de la app para agregar, modificar o eliminar registros en nuestra tabla.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Para agregarlas, recuerda que en Xamarin no se recomienda agregar las imágenes al SharedProject. Es mejor incluirlas en cada proyecto específico. Da clic derecho en la carpeta especificada a continuación (dependiendo el proyecto) y elige <b>Agregar > Elemento existente</b>, seleccionando las 3 imágenes:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<ul>
<li style="text-align: justify;">Android: Resources > Drawable</li>
<li style="text-align: justify;">iOS: Resources</li>
<li style="text-align: justify;">UWP, Windows, WinPhone: Carpeta raíz del proyecto</li>
</ul>
<div style="text-align: justify;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8NV0252_Stm_rZCcZ9UqnmiMK_nrYIpwp0V4-pcP3zi3QwZwcXUP6Q-lYMxiw9GUfik6UZGmFbHj_oe-n7TbmofzWcrRAhGxJMHwUHR6VOe-ibvzefZk6D3pxrpADDuP8H19jSH3gtoA/s1600/02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="194" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8NV0252_Stm_rZCcZ9UqnmiMK_nrYIpwp0V4-pcP3zi3QwZwcXUP6Q-lYMxiw9GUfik6UZGmFbHj_oe-n7TbmofzWcrRAhGxJMHwUHR6VOe-ibvzefZk6D3pxrpADDuP8H19jSH3gtoA/s320/02.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
En el <b>SharedProject (XamarinSQL)</b> agrega 3 carpetas: <b>Clases, Datos y Paginas </b>dando clic derecho en el nombre del proyecto y seleccionando <b>Agregar > Nueva carpeta</b>:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMCXwRqe8t5ZWIRFRQ27lsT5Hq7ufBZrV9WJkcGTjlsv2kt9xd2IugMADbE_ZlTtgPzw_8JL06-HNPxviaLoS7FBIuQqMuF5k97X9BpKPgMvX0G14aTC5CTZ2LL6-zUAQjp_xAQXikKfQ/s1600/03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMCXwRqe8t5ZWIRFRQ27lsT5Hq7ufBZrV9WJkcGTjlsv2kt9xd2IugMADbE_ZlTtgPzw_8JL06-HNPxviaLoS7FBIuQqMuF5k97X9BpKPgMvX0G14aTC5CTZ2LL6-zUAQjp_xAQXikKfQ/s1600/03.png" /></a></div>
<br />
<div style="text-align: justify;">
En la carpeta <b>Clases</b>, agrega una clase llamada <b>Empleados</b>:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8GiKrLvoTFl1UUfDxVo9JZlHHc4H-7D87NtD74zmmQ_s0kiz46AcS94-lbmdMnHcO8fhQfWtXpy4Efqu6sysg0ZeVIizy4kDCcUU4Hoo-0oxTpGRq7LwKn3Ks3pCYv79_4iPQaTu6U8c/s1600/04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8GiKrLvoTFl1UUfDxVo9JZlHHc4H-7D87NtD74zmmQ_s0kiz46AcS94-lbmdMnHcO8fhQfWtXpy4Efqu6sysg0ZeVIizy4kDCcUU4Hoo-0oxTpGRq7LwKn3Ks3pCYv79_4iPQaTu6U8c/s320/04.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
El código de la clase se presenta a continuación (básicamente es el modelado de la tabla Empleados):</div>
<br />
<pre class="brush:csharp;first-line:1">namespace XamarinSQL.Clases
{
public class Empleados
{
public int ID { get; set; }
public string Nombre { get; set; }
public decimal Salario { get; set; }
}
}
</pre>
<br />
<div style="text-align: justify;">
Para conectar la app con SQLServer, se hará uso de clases que están en <b>System.Data</b>. Es necesario agregar esta referencia a cada proyecto de plataforma específica. A continuación se muestra como realizarlo en el proyecto de Android (repite este paso para los otros proyectos que desees incluir en tus pruebas). Da clic derecho en <b>References</b> dentro del proyecto de plataforma específica. Selecciona <b>Agregar Referencia</b>:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghPwzJUZ51HzlnnSpHig0ndcQLwXYFxRYk3fPLdC8zDKi3PCYpIPcZ8FXXsFhnkRbbTOx2zFTIc16WwCNTEGprAEec9suN-Hl6fAo-Dxk5Cv6Vh3qOCExowgQC6aIFv8IomRM3pucWcrs/s1600/08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="152" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghPwzJUZ51HzlnnSpHig0ndcQLwXYFxRYk3fPLdC8zDKi3PCYpIPcZ8FXXsFhnkRbbTOx2zFTIc16WwCNTEGprAEec9suN-Hl6fAo-Dxk5Cv6Vh3qOCExowgQC6aIFv8IomRM3pucWcrs/s320/08.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
En la categoría <b>Assemblies</b>, elige <b>Framework</b> y selecciona <b>System.Data </b>de la lista de ensamblados que aparece. Da clic en <b>OK </b>para que esta referencia sea agregada al proyecto de Android.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5c8kMvRabeezXMat5X1WVx2XYyg37tKPul-WWCtSQKaSBfNTqrMg3G7tDlyiBkx3IP2LHZySywOOmNmMSRB-HEsobEiO46BtVDMgqP0t1c0C33tKjTx3Gsnlda6dHu3qOXPa_YP_W_pE/s1600/09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="177" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5c8kMvRabeezXMat5X1WVx2XYyg37tKPul-WWCtSQKaSBfNTqrMg3G7tDlyiBkx3IP2LHZySywOOmNmMSRB-HEsobEiO46BtVDMgqP0t1c0C33tKjTx3Gsnlda6dHu3qOXPa_YP_W_pE/s320/09.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Ahora ya podemos crear código que incluya la conexión a la base de datos, lea e inserte información en tablas, etc. Para ello, crea otra clase en la misma carpeta. Su nombre es <b>BaseDatos</b>:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoafp2IBhkaDo5oZPY9ccNo3VTb40WUBxw2cCE4aecMTfi_XzxfFS9mcI9qM5vp8eIrlNlDABmdvlQdmz8OEmQv43FtAfV9GzG8oaPhDm-XffBX_MdkOBXZ-E9J4bygQBe_odQOWaEMrg/s1600/05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="181" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoafp2IBhkaDo5oZPY9ccNo3VTb40WUBxw2cCE4aecMTfi_XzxfFS9mcI9qM5vp8eIrlNlDABmdvlQdmz8OEmQv43FtAfV9GzG8oaPhDm-XffBX_MdkOBXZ-E9J4bygQBe_odQOWaEMrg/s320/05.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
El código de la clase se presenta a continuación:</div>
<br />
<pre class="brush:csharp;first-line:1">using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
namespace XamarinSQL.Clases
{
public static class BaseDatos
{
static string cadenaConexion = @"data source=10.82.96.2;initial catalog=Empresa;user id=sa;password=tupassword;Connect Timeout=60";
public static List<empleados> ObtenerEmpleados()
{
List<empleados> listaEmpleados = new List<empleados>();
string sql = "SELECT * FROM Empleados";
using (SqlConnection con = new SqlConnection(cadenaConexion))
{
con.Open();
using (SqlCommand comando = new SqlCommand(sql, con))
{
using (SqlDataReader reader = comando.ExecuteReader())
{
while (reader.Read())
{
Empleados empleado = new Empleados()
{
ID = reader.GetInt32(0),
Nombre = reader.GetString(1),
Salario = reader.GetDecimal(2)
};
listaEmpleados.Add(empleado);
}
}
}
con.Close();
return listaEmpleados;
}
}
public static void AgregarEmpleado(Empleados empleado)
{
string sql = "INSERT INTO Empleados (Nombre,Salario) VALUES(@nombre, @salario)";
using (SqlConnection con = new SqlConnection(cadenaConexion))
{
con.Open();
using (SqlCommand comando = new SqlCommand(sql, con))
{
comando.Parameters.Add("@nombre", SqlDbType.VarChar, 100).Value = empleado.Nombre;
comando.Parameters.Add("@salario", SqlDbType.Decimal).Value = empleado.Salario;
comando.CommandType = CommandType.Text;
comando.ExecuteNonQuery();
}
con.Close();
}
}
public static void ModificarEmpleado(Empleados empleado)
{
string sql = "UPDATE Empleados set Nombre = @nombre, Salario = @salario WHERE ID = @id";
try
{
using (SqlConnection con = new SqlConnection(cadenaConexion))
{
con.Open();
using (SqlCommand comando = new SqlCommand(sql, con))
{
comando.Parameters.Add("@nombre", SqlDbType.VarChar, 100).Value = empleado.Nombre;
comando.Parameters.Add("@salario", SqlDbType.Decimal).Value = empleado.Salario;
comando.Parameters.Add("@id", SqlDbType.Int).Value = empleado.ID;
comando.CommandType = CommandType.Text;
comando.ExecuteNonQuery();
}
con.Close();
}
}
catch(Exception ex)
{
}
}
public static void EliminarEmpleado(Empleados empleado)
{
string sql = "DELETE FROM Empleados WHERE ID = @id";
using (SqlConnection con = new SqlConnection(cadenaConexion))
{
con.Open();
using (SqlCommand comando = new SqlCommand(sql, con))
{
comando.Parameters.Add("@id", SqlDbType.Int).Value = empleado.ID;
comando.CommandType = CommandType.Text;
comando.ExecuteNonQuery();
}
con.Close();
}
}
}
}
</pre>
<br />
<div style="text-align: justify;">
En el código anterior se establece la cadena de conexión, que contiene:</div>
<div style="text-align: justify;">
<br /></div>
<ul>
<li style="text-align: justify;">El <b>data source</b>: Representa el servidor (y su instancia, si es requerida). En este caso, se ha usado la IP del servidor (equipo). Si se tiene una instancia, se puede agregar con una diagonal invertida, por ejemplo, IP\SQLEXPRESS,</li>
<li style="text-align: justify;">El <b>initial catalog</b>: La base de datos de inicio </li>
<li style="text-align: justify;">El <b>user id</b>: El login de acceso a la base de datos</li>
<li style="text-align: justify;">El <b>password</b>: Su contraseña de acceso</li>
<li style="text-align: justify;"><b>Connect Timeout</b>: Es opcional, pero es deseable manejar un límite de tiempo de conexión en segundos.</li>
</ul>
<div>
<div style="text-align: justify;">
<br /></div>
</div>
<div style="text-align: justify;">
En la clase tienen 4 métodos estáticos que representan las operaciones CRUD (<b>Create, Read, Update and Delete</b>) sobre la tabla Empleados. En cada caso se hace uso de:</div>
<div>
<div style="text-align: justify;">
<br /></div>
</div>
<div>
<ul>
<li style="text-align: justify;">La clase <b>SqlConnection</b> para conectarse a la base de datos. </li>
<li style="text-align: justify;">Una vez conectado:</li>
<ul>
<li style="text-align: justify;">Se abre una conexión (<b>con.Open</b>)</li>
<li style="text-align: justify;">Se ejecuta una instrucción SQL mediante <b>SqlCommand</b>.</li>
<li style="text-align: justify;">El método <b>ObtenerEmpleados</b> utiliza un <b>SqlDataReader</b> para leer cada registro obtenido en la consulta y agregarlo a la lista que se retorna al final del método. Para leer el valor de cada campo se hace uso de los métodos Get: <b>GetInt32(index), GetString(index), GetDecimal(index), etc.</b>, donde index es la posición (comenzando desde cero) del campo a leer.</li>
<li style="text-align: justify;">Los otros 3 métodos utilizan <b>instrucciones parametrizadas</b>, lo que quiere decir que los valores se envían como parámetros del comando SQL.</li>
<li style="text-align: justify;">Se cierra la conexión (<b>con.Close</b>). </li>
</ul>
</ul>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Por cierto, como los métodos son estáticos, no requieres crear un objeto de la clase BaseDatos, sino que los métodos serán llamados directamente (BaseDatos.método).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Ahora vamos a crear una página para mostrar la información de los empleados de nuestra base de datos. En la carpeta <b>Paginas </b>da clic derecho y selecciona <b>Agregar > Nuevo elemento</b>. Localiza <b>Forms Xaml Page </b>dentro de la categoría <b>Cross Platform </b>para agregar una página de contenido (ContentPage) que incluye un archivo para el diseño (XAML) y otro para el código funcional (C#). El nombre de la página es <b>PaginaListaEmpleados</b>:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKjfAqtvZbgAvcG3f4Sr_CGEXXoAtNTv1vvqZJTKjTtivkdm8xt4tXbfpEuliesccnwT3dVwW46zPvJdxYAyak1X1FGnU8Gwd1IE3GuvElzAdjKNLxfflMkGhaCve1II4isiVliT_JHuc/s1600/06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKjfAqtvZbgAvcG3f4Sr_CGEXXoAtNTv1vvqZJTKjTtivkdm8xt4tXbfpEuliesccnwT3dVwW46zPvJdxYAyak1X1FGnU8Gwd1IE3GuvElzAdjKNLxfflMkGhaCve1II4isiVliT_JHuc/s320/06.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
El código XAML de esta página es:</div>
<br />
<pre class="brush:xml;first-line:1"><ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamarinSQL.Paginas.PaginaListaEmpleados">
<ContentPage.Content>
<StackLayout BackgroundColor="White">
<Label Text="Empleados" FontSize="40" HorizontalOptions="Center"/>
<ListView x:Name="lsvEmpleados" ItemSelected="lsvEmpleados_ItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Nombre}" TextColor="Blue" FontSize="16"/>
<Label Text="{Binding Salario}" TextColor="Green" FontSize="12" HorizontalOptions="EndAndExpand"/>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
<ContentPage.ToolbarItems>
<ToolbarItem x:Name="btnNuevo" Text="Nuevo" Priority="0" Clicked="btnNuevo_Click" Order="Primary" Icon="agregar.png"/>
</ContentPage.ToolbarItems>
</ContentPage>
</pre>
<br />
<div style="text-align: justify;">
Explicación: En esta página, el contenedor principal es un <b>StackLayout</b> que muestra 2 controles apilados (uno debajo del otro):</div>
<div style="text-align: justify;">
<br /></div>
<ul>
<li style="text-align: justify;"><b>Label</b>. Simplemente muestra el texto Empleados centrado en la parte superior a manera de título.</li>
<li style="text-align: justify;"><b>ListView</b>. Mostrará cada registro de la tabla y se podrá interactuar con cada elemento mediante el evento <b>ItemSelected</b>. Esta lista tiene un <b>ItemTemplate</b>, que define la presentación, es decir la información que se mostrará por cada registro. Para este caso, se muestra el nombre y el salario del empleado en un StackLayout (uno debajo del otro), pero se puede personalizar esta parte para mostrar más información si se desea.</li>
</ul>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Adicionalmente, esta página incluye una barra de herramientas (<b>ToolbarItems</b>) con un elemento (<b>ToolbarItem</b>) y que responde al evento <b>Clicked</b>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Para la funcionalidad de esta página (carga de información y manejo de los eventos ItemSelected y Clicked), se agrega código de C#, el cual se muestra a continuación:</div>
<div style="text-align: justify;">
<br /></div>
<pre class="brush:csharp;first-line:1">using System;
using Xamarin.Forms;
using XamarinSQL.Clases;
namespace XamarinSQL.Paginas
{
public partial class PaginaListaEmpleados : ContentPage
{
public PaginaListaEmpleados ()
{
InitializeComponent ();
}
protected override void OnAppearing()
{
base.OnAppearing();
lsvEmpleados.ItemsSource = BaseDatos.ObtenerEmpleados();
}
private void lsvEmpleados_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem != null)
NavegarEmpleado(e.SelectedItem as Empleados);
}
void btnNuevo_Click(object sender, EventArgs a)
{
NavegarEmpleado(new Empleados());
}
void NavegarEmpleado(Empleados empleado)
{
PaginaEmpleado pagina = new PaginaEmpleado();
pagina.Empleado = empleado;
Navigation.PushAsync(pagina);
}
}
}</pre>
<br />
<div style="text-align: justify;">
Explicación:</div>
<div style="text-align: justify;">
<br /></div>
<ul>
<li style="text-align: justify;">Cuando se carga la página (método <b>OnAppearing</b>), se asigna la propiedad <b>ItemsSource</b> del Listview <b>lsvEmpleados</b> para cargar los datos obtenidos al llamar al método <b>ObtenerEmpleados</b>.</li>
<li style="text-align: justify;">Cuando se selecciona un empleado (<b>ItemSelected</b>), se pasa de parámetro al método <b>NavegarEmpleado</b> el elemento seleccionado.</li>
<li style="text-align: justify;">Cuando se da clic en el botón de la barra de herramientas, se pasa de parámetro al método <b>NavegarEmpleado </b>un objeto Empleado vacío.</li>
<li style="text-align: justify;">El método <b>NavegarEmpleado </b>navega hacia una instancia de la página <b>PaginaEmpleado</b> (la crearás en el siguiente paso), enviándole además de parámetro un objeto <b>Empleados</b>.</li>
</ul>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Ahora, crea otro <b>Forms Xaml Page </b>en la misma carpeta <b>Paginas</b>. El nombre de este nuevo elemento es <b>PaginaEmpleado:</b></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBMejP-Bi4-jkBwkNU54MNgvNuSsgV-EG8HibtUD-nQOx69FfN7kzgPyM9scQQtaXq1Ny697-W9s016NhqQWkJPkdBM-0DyJFM0byffx8hIHpAFfR71nqkFOim4-D1mmldgppKoDXCuuo/s1600/07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBMejP-Bi4-jkBwkNU54MNgvNuSsgV-EG8HibtUD-nQOx69FfN7kzgPyM9scQQtaXq1Ny697-W9s016NhqQWkJPkdBM-0DyJFM0byffx8hIHpAFfR71nqkFOim4-D1mmldgppKoDXCuuo/s320/07.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
El código XAML de esta página es el siguiente:</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
</div>
<pre class="brush:xml;first-line:1"><ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamarinSQL.Paginas.PaginaEmpleado">
<ContentPage.Content>
<StackLayout Spacing="20" Padding="20">
<Entry x:Name="txtNombre" Text="{Binding Nombre, Mode=TwoWay}" Placeholder="Nombre" />
<Entry x:Name="txtSalario" Text="{Binding Salario, Mode=TwoWay}" Placeholder="Salario" Keyboard="Numeric" />
</StackLayout>
</ContentPage.Content>
<ContentPage.ToolbarItems>
<ToolbarItem x:Name="btnGuardar" Text="Guardar" Priority="0" Clicked="btnGuardar_Click" Order="Primary" Icon="guardar.png"/>
<ToolbarItem x:Name="btnEliminar" Text="Eliminar" Priority="1" Clicked="btnEliminar_Click" Order="Primary" Icon="eliminar.png"/>
</ContentPage.ToolbarItems>
</ContentPage>
</pre>
<br />
<div class="separator" style="clear: both; text-align: justify;">
El código anterior contiene un <b>StackLayout</b> como contenedor principal. Dentro de este control tenemos 2 controles <b>Entry</b>, que permitirán al usuario ingresar el nombre y salario del empleado. Finalmente, se incluye una Toolbar con 2 botones: uno para <b>Guardar </b>y otro para <b>Eliminar</b>. </div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Observa también que en los 2 controles Entry se hace uso del <b>Binding</b>. Esto significa que un objeto de la clase Empleados es enlazado a los controles de la página. Una modificación en la información de las cajas de texto automáticamente modificará el valor de sus propiedades (es decir, no necesitamos escribir código de C# parecido a txtNombre.Text = Empleado.Nombre o viceversa). </div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
El código C# que implementa la funcionalidad de esta página es el siguiente:</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<pre class="brush:csharp;first-line:1">using System;
using Xamarin.Forms;
using XamarinSQL.Clases;
namespace XamarinSQL.Paginas
{
public partial class PaginaEmpleado : ContentPage
{
public Empleados Empleado;
public PaginaEmpleado ()
{
InitializeComponent ();
}
protected override void OnAppearing()
{
base.OnAppearing();
BindingContext = this.Empleado;
}
void btnGuardar_Click(object sender, EventArgs a)
{
if (Empleado.ID == 0)
BaseDatos.AgregarEmpleado(Empleado);
else
BaseDatos.ModificarEmpleado(Empleado);
Navigation.PopAsync();
}
void btnEliminar_Click(object sender, EventArgs a)
{
if (Empleado.ID != 0)
{
BaseDatos.EliminarEmpleado(Empleado);
Navigation.PopAsync();
}
}
}
}
</pre>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Explicación del código anterior:</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
</div>
<ul>
<li>A nivel de clase existe un objeto <b>Empleado </b>de la clase <b>Empleados</b>.</li>
<li>Este objeto se asigna al <b>BindingContext </b>de la página en el método <b>OnAppearing</b>. Esto hace posible utilizar el <b>Binding </b>en el XAML previamente mostrado.</li>
<li>Los eventos <b>Click </b>de los botones (<b>btnGuardar_Click</b> y <b>btnEliminar_Click</b>) llaman a las funciones respectivas para realizar operaciones sobre la tabla Empleados: <b>AgregarEmpleado, ModificarEmpleado o EliminarEmpleado</b>. Existen algunas condiciones, por ejemplo si el <b>ID es diferente de cero </b>significa que <b>se seleccionó un empleado en la página anterior </b>y solo las operaciones <b>Modificar y Eliminar </b>estarán disponibles. <b>AgregarEmpleado </b>solo está disponible si se presionó el botón <b>Nuevo </b>en <b>PaginaListaEmpleados</b>.</li>
</ul>
<br />
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Ahora abre el archivo <b>App.cs </b>y modifica el constructor de la clase. <b>MainPage </b>será asignado a una instancia de <b>NavigationPage, </b>mandando llamar una nueva instancia de <b>PaginaListaEmpleados</b>:</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<pre class="brush:csharp;first-line:1">using Xamarin.Forms;
using XamarinSQL.Paginas;
namespace XamarinSQL
{
public class App : Application
{
public App ()
{
MainPage = new NavigationPage(new PaginaListaEmpleados());
}
//...
}
//...
}
</pre>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Para finalizar, asigna el permiso <b>Internet </b>al <b>AndroidManifest</b>. Para ello, da clic derecho en el nombre del proyecto y selecciona <b>Propiedades</b>:</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK5C_sSItIuAowQmBoLnX19fw1QRiTNXgq4vgtWlb6T0if7FegYTlbvC_raU6SzLHKsnH1P5UUEA1RORpNZcAPQi0z9iE3EONL_ZG21lt149gKHQWqcGJoIsptAAT8Z4Y5lt-G-ivJ3Ec/s1600/10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK5C_sSItIuAowQmBoLnX19fw1QRiTNXgq4vgtWlb6T0if7FegYTlbvC_raU6SzLHKsnH1P5UUEA1RORpNZcAPQi0z9iE3EONL_ZG21lt149gKHQWqcGJoIsptAAT8Z4Y5lt-G-ivJ3Ec/s320/10.png" width="287" /></a></div>
<br />
Selecciona <b>Android Manifest </b>y marca el permiso <b>INTERNET</b>. Guarda los cambios.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEWTl8OG0GeR7la1YpVb1nnU4vUq6jDW-yc-dXCgpRheRXImT3zQwqa4jx47plV_BOr_CiiHLPOexqn3g3hvIm-fHaYKwW2EOICS3dcbqRzsaTQUQ5z5XDjNV6FAWPhwkWJoQrPYgOHIU/s1600/11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="301" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEWTl8OG0GeR7la1YpVb1nnU4vUq6jDW-yc-dXCgpRheRXImT3zQwqa4jx47plV_BOr_CiiHLPOexqn3g3hvIm-fHaYKwW2EOICS3dcbqRzsaTQUQ5z5XDjNV6FAWPhwkWJoQrPYgOHIU/s320/11.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: justify;">
¡Listo! Compila y ejecuta, verificando que la aplicación se conecta a tu base de datos, mostrando los datos de la tabla Empleados y haciendo posible las operaciones de inserción, modificación y borrado. A continuación te comparto algunas imágenes de la aplicación funcionando en un dispositivo real.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Inicio:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDLOoIu5d4Li4lS8HpB8fFQpreF08GjdOUCbq6W7eoX9L6Xk5E9F0vZaH8EKM0K_oRyBI9bDF0edj4jalIQnGaCf4YTubZOJt4cpH1Zq-bq8UL0RDod6ys4qN7elIhVdCN_flqJGurMwc/s1600/Screenshot_2016-09-03-08-28-26.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDLOoIu5d4Li4lS8HpB8fFQpreF08GjdOUCbq6W7eoX9L6Xk5E9F0vZaH8EKM0K_oRyBI9bDF0edj4jalIQnGaCf4YTubZOJt4cpH1Zq-bq8UL0RDod6ys4qN7elIhVdCN_flqJGurMwc/s320/Screenshot_2016-09-03-08-28-26.png" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Agregando un nuevo empleado:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4VYvQOkW0BnsdMgxN81KX8ikjAeWCmdSx-8IRJqxv8vaZcyCddyPH724K-7gz16mgvs41k7e7or-1z8L2bIWZDUTWD4MK-MMJ29WtFf8Wcv2OqXcjIYQf4lvOwkPXNRJMi2ekHPOXA-8/s1600/Screenshot_2016-09-03-08-28-47.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4VYvQOkW0BnsdMgxN81KX8ikjAeWCmdSx-8IRJqxv8vaZcyCddyPH724K-7gz16mgvs41k7e7or-1z8L2bIWZDUTWD4MK-MMJ29WtFf8Wcv2OqXcjIYQf4lvOwkPXNRJMi2ekHPOXA-8/s320/Screenshot_2016-09-03-08-28-47.png" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Resultado:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDF1MXNj2XV54EXyDMor_vauuaOwT6DWKRNEVHxKSl6_tjaGceDTn18Qa9HPDPfK7TIGYYrnrJYGEMB4h64FDzjLcGQ766BdFwzaqtsktrgSSM7BxIMj-gL2AOaZy-rpNfsO11Y_94_tk/s1600/Screenshot_2016-09-03-08-28-53.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDF1MXNj2XV54EXyDMor_vauuaOwT6DWKRNEVHxKSl6_tjaGceDTn18Qa9HPDPfK7TIGYYrnrJYGEMB4h64FDzjLcGQ766BdFwzaqtsktrgSSM7BxIMj-gL2AOaZy-rpNfsO11Y_94_tk/s320/Screenshot_2016-09-03-08-28-53.png" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Vista de la base de datos:</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNfbnnuRCjvm2P9PuHvzzI-7YU9pW9NxGQLbqYCGJYt7R2GelXGA21TSuo_i_pt6foNIdOFYwF5s6avRYtLmQJR1wJ07vgaiUDSSA1trrzstw2mWf_nAKfU0tcwM_i7Gq6ytlzsyf5NuU/s1600/Screenshot_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNfbnnuRCjvm2P9PuHvzzI-7YU9pW9NxGQLbqYCGJYt7R2GelXGA21TSuo_i_pt6foNIdOFYwF5s6avRYtLmQJR1wJ07vgaiUDSSA1trrzstw2mWf_nAKfU0tcwM_i7Gq6ytlzsyf5NuU/s1600/Screenshot_1.png" /></a></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
El código fuente lo puedes descargar desde mi repo en <a href="https://github.com/icebeam7/XamarinSQL" target="_blank">GitHub</a>.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Espero que esta aportación te haya sido útil. Si así ha sido, dale like o compártela con tus amigos. Si llegas a realizar esta práctica, compárteme tus resultados, me agradará saber que alguien realizó la práctica :-) Si tienes algún problema, coméntalo y a la brevedad te responderé.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Gracias por tu tiempo y hasta la próxima.</div>
</div>
Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com103tag:blogger.com,1999:blog-8407795827837136717.post-63228169001018512562016-08-07T06:33:00.002-07:002016-08-07T06:55:09.130-07:00Concurso: Aporta tu contribución en la documentación de StackOverflow con Xamarin<div style="text-align: justify;">
<a href="http://stackoverflow.com/" target="_blank">StackOverflow</a> es el sitio por excelencia al que los programadores acudimos cuando tenemos alguna pregunta técnica sobre lenguajes de programación, plataformas de desarrollo y demás temas informáticos. Las respuestas son proporcionadas por otros programadores con la experiencia necesaria para resolver nuestras cuestiones, lo que significa que impera un ambiente de colaboración donde todos los miembros de la comunidad podemos aportar nuestro conocimiento y ayudar a otros programadores. Es gratis y muy fácil <a href="https://stackoverflow.com/users/signup" target="_blank">unirte</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
A mediados del mes pasado, StackOverflow introdujo <a href="http://blog.stackoverflow.com/2016/07/introducing-stack-overflow-documentation-beta/" target="_blank">la versión beta </a>de la sección <a href="http://stackoverflow.com/documentation" target="_blank">Documentación</a>. La idea es reunir en un solo sitio una documentación técnica basada en ejemplos y construida por la comunidad. En muchas ocasiones, al buscar un código sobre un tema específico obtenemos tantos resultados que se nos hace imposible encontrar "el que funciona" o "el mejor". También nos ha sucedido que algún código incluido en la documentación oficial no funciona, está obsoleto o incompleto. La documentación de StackOverflow es una propuesta para resolver estos problemas donde los mismos programadores podemos aportar códigos, ejemplos que funcionen o versiones actualizadas siempre en pro de otros programadores y en un solo lugar. Cualquiera de nosotros podemos crear un nuevo tema, proporcionar ejemplos, votar por las aportaciones, realizar sugerencias, etc).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Te recomiendo que sigas el <a href="http://stackoverflow.com/tour/documentation" target="_blank">tour</a> de la documentación para que te des una idea de cómo funciona, cuales son los beneficios, diferencias con otras propuestas y cómo puedes comenzar a aportar.</div>
<div style="text-align: justify;">
<br /></div>
<a name='more'></a><div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Relacionado con el lanzamiento de esta propuesta, Xamarin propone un pequeño <a href="https://blog.xamarin.com/contest-document-all-the-things/" target="_blank">concurso </a>para motivar a usuarios de su comunidad a aportar su conocimiento en la documentación de StackOverflow. El concurso "<a href="https://blog.xamarin.com/contest-document-all-the-things/" target="_blank">Document All the Things</a>" consiste en crear un nuevo tema en el sitio de documentación de StackOverflow proporcionando uno o más ejemplos (código) en cualquiera de los tags <a href="http://stackoverflow.com/documentation/xamarin.forms/" target="_blank">Xamarin.Forms</a>, <a href="http://stackoverflow.com/documentation/xamarin.ios/" target="_blank">Xamarin.iOS</a> o <a href="http://stackoverflow.com/documentation/xamarin.android" target="_blank">Xamarin.Android</a> y tweetear la URL de tu contribución con los hashtags <b>#Xamarin</b> y <b>#StackOverflow</b>. En realidad es un sencillo concurso porque no necesitas programar, ¡simplemente documentar! (Aunque claro, tienes que verificar que tu código funciona, así que tal vez sí tengas que programar un poco xD)</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
La fecha limite es el <b>15 de Agosto </b>a las <b>12 pm EST</b> (las 11 am hora de México).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Realmente vale la pena aportar. El conocimiento que compartes puede ayudar a otros en el futuro :-) pero si necesitas algo de motivación, pues una vez que hayas participado con una entrada y sea válida, entrarás a un sorteo donde hay 3 premios: una Apple TV, una Microsoft Band o un Microsoft Azure IoT Starter Kit.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Los pasos están indicados en la <a href="https://blog.xamarin.com/contest-document-all-the-things/" target="_blank">página del concurso</a>, pero si quieres una pequeña guía, aquí va:</div>
<div style="text-align: justify;">
<br /></div>
<ol>
<li style="text-align: justify;">Debes estar registrado en StackOverflow para poder aportar.</li>
<div style="text-align: justify;">
<br /></div>
<li style="text-align: justify;">Elige uno de los 3 tags participantes, dando clic en <a href="http://stackoverflow.com/documentation/xamarin.forms/" target="_blank">Xamarin.Forms</a>, <a href="http://stackoverflow.com/documentation/xamarin.android" target="_blank">Xamarin.Android</a> o <a href="http://stackoverflow.com/documentation/xamarin.ios/" target="_blank">Xamarin.iOS</a>, que corresponden a la sección donde realizarás tu aportación.</li>
<div style="text-align: justify;">
<br /></div>
<li style="text-align: justify;">Revisa los temas y ejemplos que ya existen para que tu aportación no sea un duplicado dando clic en los enlaces <b>Topics</b>, <b>Topic Requests</b> y <b>Proposed Changes </b>que se localizan en el panel izquierdo.</li>
<br />
<li style="text-align: justify;">Da clic en el botón <b>Create New Topic</b>.</li>
<ol><div style="margin-left: 1em; margin-right: 1em; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-guGStZ-fQUN1ETPFhcF_8s4JSLn5t9Ohby5RFbZtty90i_CYqqGdF3DtxwsKkGEmCs1C1AdUV05zS8xQQwKwC0fqdsMeL6WL3hZ1_ueLDro9Op70du79jz2WP-0aNeXB_OBQMfX1L3U/s1600/01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="185" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-guGStZ-fQUN1ETPFhcF_8s4JSLn5t9Ohby5RFbZtty90i_CYqqGdF3DtxwsKkGEmCs1C1AdUV05zS8xQQwKwC0fqdsMeL6WL3hZ1_ueLDro9Op70du79jz2WP-0aNeXB_OBQMfX1L3U/s320/01.png" width="320" /></a></div>
<ol style="margin-left: 1em; margin-right: 1em; text-align: justify;"><br /></ol>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-guGStZ-fQUN1ETPFhcF_8s4JSLn5t9Ohby5RFbZtty90i_CYqqGdF3DtxwsKkGEmCs1C1AdUV05zS8xQQwKwC0fqdsMeL6WL3hZ1_ueLDro9Op70du79jz2WP-0aNeXB_OBQMfX1L3U/s1600/01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;">
</a></ol>
<li style="text-align: justify;">Escribe el título del tema del cual quieres contribuir. La vista previa del titulo aparece en la sección superior.</li>
<ol><div style="margin-left: 1em; margin-right: 1em; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbQ3KMm8U3yVTYWMlCijti8XytiaP7bnHeaJrgUVzR6Fe0mvMBuBkqurZhJnWBkHErKGryRjOm2Iw6xCL9grBTJjzLnyBgQDWq67tVh1-3S8Nz_F86YF6Y4HFlgytr0dE8Moa6tjmQq9U/s1600/02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="136" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbQ3KMm8U3yVTYWMlCijti8XytiaP7bnHeaJrgUVzR6Fe0mvMBuBkqurZhJnWBkHErKGryRjOm2Iw6xCL9grBTJjzLnyBgQDWq67tVh1-3S8Nz_F86YF6Y4HFlgytr0dE8Moa6tjmQq9U/s320/02.png" width="320" /></a></div>
<ol style="margin-left: 1em; margin-right: 1em; text-align: justify;"><br /></ol>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbQ3KMm8U3yVTYWMlCijti8XytiaP7bnHeaJrgUVzR6Fe0mvMBuBkqurZhJnWBkHErKGryRjOm2Iw6xCL9grBTJjzLnyBgQDWq67tVh1-3S8Nz_F86YF6Y4HFlgytr0dE8Moa6tjmQq9U/s1600/02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;">
</a></ol>
<li style="text-align: justify;">Debajo de la sección Examples (vista previa) da clic en el botón <b>Add the First Example</b>.</li>
<ol><div style="margin-left: 1em; margin-right: 1em; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3BmvVFSZiXhyphenhyphen3kCO5I-Wnhzfq4JUvlwyDdC7L7JWJD8M8iGAeVQzPbFzyE7blqLuq3xEEnhl785HzhQRutvNUjUAxWZ4E-I63QHrK8tciILNeaNLEa9tLDPAdC2J6bHHAKg2EFVSx7FQ/s1600/03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="78" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3BmvVFSZiXhyphenhyphen3kCO5I-Wnhzfq4JUvlwyDdC7L7JWJD8M8iGAeVQzPbFzyE7blqLuq3xEEnhl785HzhQRutvNUjUAxWZ4E-I63QHrK8tciILNeaNLEa9tLDPAdC2J6bHHAKg2EFVSx7FQ/s320/03.png" width="320" /></a></div>
</ol>
<div style="text-align: justify;">
<br /></div>
<li style="text-align: justify;">Comienza a redactar tu aportación en el área de texto ubicado en la sección inferior. Nuevamente podrás observar la vista previa de tu contribución en la parte superior. <b>Mi sugerencia aquí es que te inspires en la documentación oficial o en tu propio código. Seguramente tienes algo que puedes compartir y que será de utilidad a la comunidad. </b>Eso sí, evita plagiar o copiar íntegramente el texto tal cual aparece en otro sitio. No es bien visto.</li>
<ol><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVx90FVB9LY3kqwztwqeeKXnWWRaOtmRyZflHLrlAxa354Q2R8OGvtNDx2DUqugBpD9gvARnY4KRF4wtENaCAdHd7K2_nc-MDqgFtxbdoNk8nKASyGmO97J34-4x5un5NnSJ9npgXl3r4/s1600/05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><ol style="text-align: justify;"><br /></ol>
</a><div style="margin-left: 1em; margin-right: 1em; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVx90FVB9LY3kqwztwqeeKXnWWRaOtmRyZflHLrlAxa354Q2R8OGvtNDx2DUqugBpD9gvARnY4KRF4wtENaCAdHd7K2_nc-MDqgFtxbdoNk8nKASyGmO97J34-4x5un5NnSJ9npgXl3r4/s1600/05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVx90FVB9LY3kqwztwqeeKXnWWRaOtmRyZflHLrlAxa354Q2R8OGvtNDx2DUqugBpD9gvARnY4KRF4wtENaCAdHd7K2_nc-MDqgFtxbdoNk8nKASyGmO97J34-4x5un5NnSJ9npgXl3r4/s1600/05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="195" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVx90FVB9LY3kqwztwqeeKXnWWRaOtmRyZflHLrlAxa354Q2R8OGvtNDx2DUqugBpD9gvARnY4KRF4wtENaCAdHd7K2_nc-MDqgFtxbdoNk8nKASyGmO97J34-4x5un5NnSJ9npgXl3r4/s320/05.png" width="320" /></a></div>
</ol>
<div style="text-align: justify;">
<br /></div>
<li style="text-align: justify;">El botón <b>Save Draft </b>te permite guardar un borrador de tu aportación (utilízalo a cada instante, recuerda que el botón de Guardar siempre es buen amigo del programador para evitar trabajo doble). <b>Discard </b>elimina por completo tu contribución. Cuando hayas terminado de redactar tu aportación, revísala bien. Da clic en el botón <b>Submit for Review </b>para que los demás usuarios puedan validar tu tema y ejemplo. .</li>
<ol><div style="text-align: justify;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_dU8xP9c0rRD3yaKmiLcb05r8UWLId9omcSHpZX5zx3HFcyhyphenhyphenVWqX7r9hqXECkgZy4YYBzs7Swptw0Y11lRcH91HJnqBr2lAc3rfMRYd5WvLtJtHZgI9kLdCNQh_1-kcboGGSB2v4PRk/s1600/06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_dU8xP9c0rRD3yaKmiLcb05r8UWLId9omcSHpZX5zx3HFcyhyphenhyphenVWqX7r9hqXECkgZy4YYBzs7Swptw0Y11lRcH91HJnqBr2lAc3rfMRYd5WvLtJtHZgI9kLdCNQh_1-kcboGGSB2v4PRk/s1600/06.png" /></a></div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_dU8xP9c0rRD3yaKmiLcb05r8UWLId9omcSHpZX5zx3HFcyhyphenhyphenVWqX7r9hqXECkgZy4YYBzs7Swptw0Y11lRcH91HJnqBr2lAc3rfMRYd5WvLtJtHZgI9kLdCNQh_1-kcboGGSB2v4PRk/s1600/06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><ol style="text-align: justify;"><br /></ol>
</a></ol>
<li style="text-align: justify;">Aparecerá la siguiente pantalla, indicando el éxito de la operación. <b>¡Tu aportación será revisada por otros miembros de la comunidad! </b></li>
<ol style="text-align: justify;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0pvZWnFXz7FD8w60R8llKbuTzlTwplzSS88U7FJJvWocHxm0OiyV4ry_1oA7H_LMcGBDeP3pdFmXHkYxJl3SvEizULmeorz873SoHW6dvukVRSik0RayD5ccB8l3v-nbrrV_1VDDPvXs/s1600/07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="127" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0pvZWnFXz7FD8w60R8llKbuTzlTwplzSS88U7FJJvWocHxm0OiyV4ry_1oA7H_LMcGBDeP3pdFmXHkYxJl3SvEizULmeorz873SoHW6dvukVRSik0RayD5ccB8l3v-nbrrV_1VDDPvXs/s320/07.png" width="320" /></a></ol>
<div style="text-align: justify;">
<br /></div>
<li style="text-align: justify;">Da clic en el enlace <b>Proposed Changes, </b>localizado en el panel izquierdo del dashboard.</li>
<ol style="text-align: justify;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjl-5RUvhnXSlFV_L7t9YhjrxwuuiHNvY5wLKwrdbufrvaOznW9fllFaH_T1OqVroYABfPmHfX5MqOW8jDAT8TsCG5Pb-0KDndNHbk3KH0fbhVequFLLF9QEvZoC336JWq9wbYlg2KVqZ0/s1600/08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjl-5RUvhnXSlFV_L7t9YhjrxwuuiHNvY5wLKwrdbufrvaOznW9fllFaH_T1OqVroYABfPmHfX5MqOW8jDAT8TsCG5Pb-0KDndNHbk3KH0fbhVequFLLF9QEvZoC336JWq9wbYlg2KVqZ0/s320/08.png" width="320" /></a></ol>
<div style="text-align: justify;">
<br /></div>
<li style="text-align: justify;">Copia la URL de tu cambio propuesto.</li>
<div class="separator" style="clear: both; text-align: justify;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2EmkecS2IhjlyiwaZdOtxadl3B962ozwV23F18WdvWGry7S601YjdP8Vok7JoF8QXijHrg48oY4q9yueEEkvmO846zTONC3D1CA3v_Bw2L3pt4ex4l7HuYblbTq6YzOKTMYuMuVaszII/s1600/10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2EmkecS2IhjlyiwaZdOtxadl3B962ozwV23F18WdvWGry7S601YjdP8Vok7JoF8QXijHrg48oY4q9yueEEkvmO846zTONC3D1CA3v_Bw2L3pt4ex4l7HuYblbTq6YzOKTMYuMuVaszII/s320/10.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<li style="text-align: justify;">¡Listo! Todo lo que necesitas hacer ahora es incluir <b>esta URL </b>en un tweet con los hashtags <b>#Xamarin</b> y <b>#StackOverflow</b>. Por ejemplo, esta es mi aportación (dale like si vale la pena :-))</li>
</ol>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<blockquote class="twitter-tweet" data-lang="en">
<div dir="ltr" lang="en">
<div style="text-align: justify;">
How to implement local databases in a Xamarin.Forms shared project with SQLite-NET. <a href="https://twitter.com/hashtag/StackOverflow?src=hash">#StackOverflow</a> <a href="https://twitter.com/hashtag/Xamarin?src=hash">#Xamarin</a> <a href="https://t.co/i41SMb1yLG">https://t.co/i41SMb1yLG</a></div>
</div>
<div style="text-align: justify;">
— Luis Beltran (@darkicebeam) <a href="https://twitter.com/darkicebeam/status/762279050358456324">August 7, 2016</a></div>
</blockquote>
<div style="text-align: justify;">
<script async="" charset="utf-8" src="//platform.twitter.com/widgets.js"></script><br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
¡Anímate a participar! Si tienes alguna duda, con gusto te puedo ayudar. ¡Mucha suerte y hasta la próxima!</div>
Luis Beltranhttp://www.blogger.com/profile/12650662987863126123noreply@blogger.com0