C# en el browser .NET WebAssembley Blazor

Nota: Esta tecnologia aun es experimental.

Si eres un desarrollador web moderno, probablemente est√©s usando JavaScript. Hasta hace poco, era la √ļnica opci√≥n seria para desarrollo web. Para aquellos de nosotros que quiz√°s no tengamos JS como skill en nuestras habilidades principales (pero que todav√≠a estamos interesados en crear aplicaciones web), el mundo est√° empezando a cambiar. Hoy en d√≠a, tenemos WebAssembly (Wasm). WebAssembly es una forma alternativa de desarrollar aplicaciones web, y no requiere que usted conozca ning√ļn framework JavaScript. WebAssembly es un nuevo tipo de c√≥digo que se puede ejecutar en navegadores web modernos y proporciona nuevas funciones y mejoras importantes en el rendimiento.

El sue√Īo de todo desarrollador .NET

Como desarrollador .NET, tambi√©n podr√° usar su lenguaje y framework¬† favorito para crear aplicaciones del lado del cliente. Tambi√©n podr√° compartir sus modelos, c√≥digo, l√≥gica de negocios entre el c√≥digo del lado del servidor y el c√≥digo del lado del cliente, y esto es enorme. Tener un c√≥digo compartido entre el servidor y el cliente siempre ha sido un sue√Īo para muchos desarrolladores de .NET.

Como funciona el WASM.

Para entender se puede dividir en dos partes:

  • Una m√°quina virtual (VM) que ejecuta el c√≥digo de la aplicaci√≥n web, por ejemplo, El c√≥digo JavaScript que alimenta tus aplicaciones.
  • Un conjunto de API web a las que la aplicaci√≥n web puede llamar para controlar la funcionalidad del dispositivo / navegador web y hacer que sucedan las cosas (DOM, CSSOM, WebGL, IndexedDB, API de audio web, etc.).

Hist√≥ricamente, la m√°quina virtual solo ha podido cargar JavaScript. Esto nos ha funcionado bien, ya que JavaScript es lo suficientemente poderoso como para resolver la mayor√≠a de los problemas que las personas tienen hoy en la Web. Sin embargo, nos hemos encontrado con problemas de rendimiento cuando intentamos utilizar JavaScript para casos de uso m√°s intensivos, como juegos en 3D, realidad virtual y aumentada, visi√≥n de computadora, edici√≥n de im√°genes / video y una cantidad de otros dominios que exigen un rendimiento nativo para tener una idea mas clara puede consultar los siguientes casos de uso –> Aqui¬†.

Que hay de nuevo en Blazor 

El equipo de desarrollo de Blazor se centra en ejecutar código .NET, como C #, del lado del cliente en el navegador. Pero, aparentemente, los esfuerzos del lado del cliente no están listos para el .NET Core prime time, ya que hay más partes móviles y dependencias asociadas con el esfuerzo del lado del cliente, por lo que el progreso no solo lo determina el equipo de desarrollo de Blazor. Por ejemplo, para ejecutar Blazor en el navegador, el código debe compilarse a WebAssembly, otro trabajo en progreso completamente nuevo que básicamente es un código de bytes para la Web por lo cual aun no esta ready para produccion.

Las nuevas caracteristicas de  Blazor 0.6.0 seran entregadas en el release de Net Core 3.0

Mas informacion sobre el progreso aqui .

Construyendo tu primera aplicación Blazor y WebAssembly

Aqui les dejo un video donde muestro como crear nuestra primera aplicacion con Blazor. Nota para tener el ultimo update de Blazor solo debemos actualizar el SDK de Net Core.

Esta es la nueva promesa del gigante de Redmond .Net en el browser ! Me gustar√≠a saber tu impresi√≥n u opini√≥n en los comentarios !

Métodos en C# || Back to Basics

Un m√©todo, tambi√©n conocido como funci√≥n, es un m√≥dulo de c√≥digo que nosotros como¬† programador podemos crear y luego llamar m√°s adelante en el programa. Ya existen muchos m√©todos en lenguajes de programaci√≥n como C# pero¬† nosotros tambi√©n podemos hacer los propios. Un m√©todo generalmente realizar√° una √ļnica tarea. Muchos m√©todos pueden trabajar juntos para lograr un objetivo.

Los métodos deben tener nombres descriptivos (deben representar una acción y generalmente tienen la forma de un verbo). Los espacios no se pueden usar en nombres de métodos y siempre se debe evitar el uso de caracteres especiales, por ej. $% ^! @.

Los nombres de los métodos deben seguir una convención de nomenclatura consistente en todo nuestro código,  Entre los ejemplos de nombres de métodos adecuados se incluyen CalculateScore, AddNumbers, MultiplyNumbers, GetUserDetails, etc.

Descomponiendo la estructura de un método.

¬ŅQu√© es un modificador de acceso?

Los modificadores de acceso incluyen p√ļblicos y privados (o simplemente se dejan vac√≠os). P√ļblico significa que otras partes del programa pueden ver y usar este m√©todo. Si no queremos eso, usamos el modificador privado de acceso.

¬ŅQu√© es un¬†return type?

Los m√©todos pueden devolver una variable al c√≥digo que la llam√≥ conocida como el tipo de devoluci√≥n. Si un m√©todo devuelve un valor entero, entonces el tipo de devoluci√≥n es un int y si un m√©todo devuelve un valor verdadero o falso, el tipo de devoluci√≥n es un bool. Incluso si el m√©todo no devuelve ning√ļn valor, todav√≠a tiene un tipo de devoluci√≥n. Si el m√©todo no devuelve un valor, su tipo de devoluci√≥n es nulo (lo que no significa nada).

¬ŅQu√© son los par√°metros?

Estas variables se conocen como parámetros. Las variables que se pasan al método se identifican en la parte lista de parámetros del método (dentro de los corchetes). Cuando especifica un parámetro, debe especificar el tipo de variable y el nombre. Si no hay parámetros, entonces los corchetes se dejan vacíos.

A continuacion un ejemplo

public static string GetFullName(string name, string lastname)
 {
   string fullname = name + lastname;
   return fullname;
 }

La palabra static significa que este método particular está asociado con la clase, no una instancia específica (objeto) de esa clase. Lo que esto significa es que puede llamar a un método estático sin crear realmente un objeto de la clase.

Muchos m√©todos tienen la palabra void en su declaraci√≥n. La palabra void b√°sicamente significa que el m√©todo no devolver√° ning√ļn valor a la parte del programa que lo llam√≥.

Usando métodos

Una vez que hayamos  creado un método, lo próximo que debemos hacer es usarlo. El uso de un método se conoce como llamar o invocar un método. Para llamar a un método que se llamó AddNames, deberíamos escribir:


AddNames();

Código de ejemplo
Aquí  un ejemplo usando parámetros y un tipo de retorno de void. El método AddNames se llama desde el método Main.

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

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
          AddNames ("Yhorby", "Matias");
    }
    public static void AddNames (string name, string  lastname)
    {
     string fullname = name +" " + lastname;
      Console.WriteLine("El nombre completo es  " + fullname);
    }
  }
}

Esto es todo si tienes alguna pregunta no dudes en escribirme.

Microsoft Azure Storage Queues ( Colas de almacenamiento ) + C# Primera parte

Como¬†todos sabemos Microsoft Azure ofrece un sin n√ļmero de servicios ¬†en esta entrada vamos a aprender sobre Microsoft Azure Storage Queues.

¬ŅQue son colas?

En simples palabras es  un sistema de almacenamiento FIFO (First In First Out) donde podemos guardar mensajes que deben ser procesadas en segundo plano o en un momento concreto y diferente del proceso principal.

¬ŅQue Ofrece Queue Storage?

Ofrece almacenamiento en cola de mensajes asincrónicos para la comunicación entre componentes de aplicaciones, que pueden estar ejecutándose en la nube, en el escritorio, en el sistema local o en dispositivos móviles.

Que necesitamos antes de empezar

  • Necesitamos una cuenta en el ¬†Azure portal
  • Visual Studio 2015 +

Si no sabes como crear el recurso de almacenamiento en el portal de Azure les dejo este video para aprender cómo hacerlo.

¬ŅAhora que hago?

Para trabajar con Azure necesitamos agregar a nuestro proyecto los siguientes paquetes mediante nuget:

Microsoft Azure Storage Client Library for .NET

Microsoft Azure Configuration Manager library for .NET

El proceso se indica paso a paso en el siguiente video:

  • Si estas en Windows sigue estos pasos para agregar los paquetes de nuget a la soluci√≥n

Lo siguiente que debemos hacer es configurar la cadena de conexión de nuestro desarrollo el proceso se explica en el siguiente video.

 

Una vez configurada la cadena de conexión lo que debemos de hacer es obtener la cadena de conexión de nuestro app.config en el siguiente video se muestra como.

Una vez que ya tenemos sabemos como obtener nuestra cadena de conexión vamos a crear nuestra cola para lo cual seguimos los pasos del siguiente video.

Ya que tenemos nuestra cola creada vamos a agregar un mensaje a nuestra cola, para ello seguimos los pasos del siguiente video.

Y listo eso es todo en la primera parte en una segunda parte veremos c√≥mo enviar m√ļltiples mensajes en la cola y a leer dichos mensajes.

Referencia —->¬†https://docs.microsoft.com/en-us/dotnet/api/overview/azure/storage?view=azure-dotnet

Si te gusto o tienes alg√ļn comentario no dudes en escribirme.

 

ProgramacioŐĀn AsiŐĀncrona | Trabajando con Delegados Asincronos C#

Se ha venido hablando mucho en los √ļltimos a√Īos sobre la programaci√≥n As√≠ncrona, ya que este esquema de programaci√≥n puede mejorar mucho nuestros programas claro est√° si lo aplicamos correctamente.

En ocasiones nuestros programas nos dan la notificaci√≥n de que el programa no responde o se congela ¬†cuando el usuario interact√ļa con ellos. Esto ocurre porque hay algunas tareas pesadas que se est√°n ejecutando detr√°s, y como s√≥lo hay un hilo de ejecuci√≥n, ¬†entonces no le queda otra opci√≥n ¬†que esperar a que termine dicha tarea para estar nuevamente disponible. Mejorar este tipo de comportamientos les da un toque de profesionalidad a nuestro trabajo algo¬†¬†que siempre es importante.

En esta entrada veremos cómo aplicar la programación asíncrona usando delegados asíncronos, en otra ocasión hace tiempo escribí una entra sobre los delegados la puede leer en el siguiente enlace aquí y otro aquí.

Si con los enlaces no basta para comprender, a continuaci√≥n haremos un peque√Īo ejemplo de c√≥mo funcionan los delegados.

¬ŅQu√© es un Delegado?

Un delegado es la implementación de .NET de los punteros a funciones.

Ahora vamos al ejemplo “suuuuper” sencillo de un delegado.

Primero declaramos un delegado:

  delegate int delegadoProducto(int a, int b);

A continuación creamos una función con la misma estructura del delegado:

public class DelegadoProducto
    {
        public int Producto(int x, int y)
        {
            Console.WriteLine();
            Console.WriteLine("DelegadoProducto.Producto: Calculando el producto de {0} por {1}", x.ToString(), y.ToString());
            Console.WriteLine();
            return x * y;
        }
    }

Ahora instanciamos un objeto de nuestro delegado:

  public static void Main(string[] args)
        {
            // Instanciamos un delegado
            var objDelegado = new DelegadoProducto();
 
            // Asignamos el objeto recién creado a la función que creamos en la clase de apoyo
            delegadoProducto variableDelegadoProducto = new delegadoProducto(objDelegado.Producto);
 
            // Llamamos a la función a través del delegado
            var resultado = variableDelegadoProducto(4, 4);
 
            // Imprimimos el resultado de la ejecución
            Console.WriteLine("Resultado del producto es: {0}", resultado.ToString());
            Console.ReadLine();
        }

Si se fijan Sólo se puede asignar funciones a objetos que tienen la misma estructura que su delegado.

Esta es la salida de nuestro programa en consola en mi caso terminal puesto que estoy usando Mac OS.

Aplicando la programación Asíncrona a nuestros delegados.

Vamos con un ejemplo un poco más elaborado para entender mejor el concepto de llamada síncrona.

Para este ejemplo voy a usar a dos de mis amigas  Naiomi y Maria. Ellas harán un viaje hacia la ciudad de NEW YORK que demora 15 segundos aproximadamente. ( es solo un ejemplo)

El codigo el siguiente:

sing System;
using System.Diagnostics;
 
namespace ProgramacionAsincrona.Delegados
{
    class Program
    {
        delegate int DelegadoViajeNYC(string NombreViajero, Stopwatch temporizador);
 
        static void Main(string[] args)
        {
            // Se instancia un temporizador para calcular el tiempo de ejecución.
            var temporizador = Stopwatch.StartNew();
            
            // Se instancia la clase de apoyo
            var objViaje = new Viaje();
 
            // Se crea el primer delegado, que representará el primer viaje.
            DelegadoViajeNYC viajeNaiomi = new DelegadoViajeNYC(objViaje.ViajeNYC);
 
            // Se crea el segundo delegado, que representará el segundo viaje.
            DelegadoViajeNYC viajeMaria = new DelegadoViajeNYC(objViaje.ViajeNYC);
 
            // Ahora ejecutamos los delegados que harán los viajes
            viajeNaiomi("Naiomi", temporizador);
            viajeMaria("Maria", temporizador);
 
            // Hacemos una pequeña pausa y luego mostramos el mensaje de fin de viajes
            System.Threading.Thread.Sleep(1500);
            Console.WriteLine();
            Console.WriteLine("=> Finalizó las llamadas a los viajes, a los {0} segundos.", temporizador.Elapsed.TotalSeconds.ToString());
            Console.WriteLine();
 
            Console.ReadLine();
        }
    }
 
    public class Viaje
    {
        public int ViajeNYC(string NombreViajera, Stopwatch temporizador)
        {
            Console.WriteLine();
            Console.WriteLine("Inicio de viaje realizado por {0}.", NombreViajera);
            System.Threading.Thread.Sleep(15000);
            Console.WriteLine("Fin de viaje realizado por {0}, a los {1} segundos.", NombreViajera, temporizador.Elapsed.TotalSeconds.ToString());
            return 0;
        }
    }
 
}

Recapitulando

Si eres observador puedes notar que la ejecución del programa es lineal: se llama al primer viaje, cuando éste termina se llama al segundo viaje y cuando éste segundo termina se muestra el mensaje de fin de llamadas de viajes. Esto sucede porque estamos llamando a los delegados de forma síncrona, que es casi lo mismo que llamar directamente a la función. El tiempo total de ejecución de todo el programa es un poco más de 31 segundos.

Realizando llamada asíncrona a un delegado

Cambiamos las líneas 24 y 25 por llamadas asíncronas a los delegados.

            // Ahora ejecutamos los delegados que harán los viajes  (llamadas asíncronas)
            viajeNaiomi.BeginInvoke("Naiomi", temporizador, null, null);
            viajeMaria.BeginInvoke("Maria", temporizador, null, null);

Si ejecutamos nuestro codigo el resultado seria el siguiente:

El programa principal hace las llamadas (asíncronas) a los delegados y sigue su ejecución sin esperar a que estas llamadas terminen. Internamente la ejecución de dichas llamadas sucede en un hilo diferente al hilo del programa principal. Este manejo de hilos es interno, de forma transparente para nosotros.

Conclusiones

Ya puedes imaginar el potencial de esta técnica, cómo implementar este tipo de llamadas para algunos procesos que demanden muchos recursos y poder reducir los tiempos de ejecución dividiendo las tareas a través de llamadas asíncronas. Espero que la apliquen en sus próximos desarrollos.

 

 

 

 

Subete a la nube con los #AzureSkills!

Saludos es hora de aprender Azure y gratis, desarrolla habilidades que te brinden mejores oportunidades laborales y la posibilidad de acceder a salarios m√°s altos de manera flexible y a tu propio ritmo.

Casi el 80% de las empresas ya utilizan la tecnología en la nube. ¡Es el momento perfecto para adquirir habilidades de #AzureSkills y transformarte en el protagonista de la 4ta revolución industrial! Regístrate ahora y entrénate con los cursos gratuitos en línea: https://aka.ms/azureskillsdx

Xamarin y otras especias | Charla

Saludos mi buen amigo¬†Cristopher Junior Vivieca Ramos¬†de ¬†viviecar.com¬†me invito a dar una charla en el Instituto Polit√©cnico Padre Segri en Santiago, Rep. Dominicana. donde estuve hablando sobre “Xamarin y otras especias”

Fotos del evento.

Presentación del evento.

Te gustaria que sea ponente en alguna charla ?

Si te gustaria que diera una charla sobre el mismo tema o otras tecnologías Microsoft no dudes en ponerte en contacto conmigo.

Bug DisplayAlert Xamarin.Forms

Solución para Bug DisplayAlert Xamarin.Forms

Disclaimer: Si alguno considera que no es un bug y es mas una mala pr√°ctica por parte de algunos developers dejo aca el link del bug aca.

Bug

Este sucede cuando implementamos DisplayAlert  en Xamarin.Forms  se traduce en dos ventanas emergentes, lo que obviamente no se espera, y este es el bug.

Estoy hablando de este bloque de código:

var resp = await DisplayAlert("","Seguro quieres salir?","Si", "No");
if (resp)
{ 
   //Hacer algo
}

Solucion

Lo que debemos hacer es  invocar el Display Alert  en el hilo de interfaz de usuario principal usando Xamarin.Forms.Device.BeginInvokeOnMainThread. Tenemos que pasar la acción que  ejecutará el DisplayAlert al hilo principal de la UI:

Device.BeginInvokeOnMainThread(new Action(async () =>
  {
       if(await DisplayAlert("", "Seguro quieres salir?", "Si", "No"))
       {
         //Hacer algo
       }
  }));

Que hace la solución?

Esto soluciona el problema, porque ahora estamos invocando el hilo principal de la interfaz de usuario. Nuestra DisplayAlert ahora se ejecuta solo una vez. Así que, sí, por ahora, podemos utilizar esta solución.

Sin embargo, es de esperar, que corrijan el error, por lo que sólo pueden ejecutar sin el método BeginInvokeOnMainThread. Espero que esto les puede ayudar con su desarrollos.

Si tienen algo que a√Īadir, dudas comentarios no duden en escribirme.

Documentacion: https://developer.xamarin.com/api/member/Xamarin.Forms.Device.BeginInvokeOnMainThread/p/System.Action

Aplicaciones bonitas con Xamarin Forms | Pt. 1

Aplicaciones bonitas con Xamarin Forms

Hace algunos días un developer me escribió y me contaba que Xamarin forms era asombroso que para el las aplicaciones era algo feas en cuanto a la UI, yo le respondí y le dije que si se puede solo que se necesita un poquito más de esfuerzo. Pues en la play store o en cualquiera de las tiendas se engancha mucho mas rápido al futuro usuario de nuestra app si tiene una interfaz atractiva y amigable.

Que necesito para comenzar ?

1) Visual Studio 2015 Community (gratis  o una version superior ) o Visual Studio for MAC.

Vamos a hablar de interfaces bonitas

 

XFParallax by DevsDNA

Super pero que es XFParallax by DevsDNA, pues XFParallax by DevsDNA busca implementar el muy popular efecto efecto Parallax muy famoso en la plataforma ios.

Pero Yhorby que te digo que quiero hacer apps bonitas en Xamarin Forms, calma colega que se puede implementar en Xamarin forms.

Como lo hago?

Pues puedes encontrar un proyecto de ejemplo en su repositorio de Github aquí. 

Con esta librer√≠a podemos crear el efecto¬†parallax en las tres plataformas : Android, iOS and Windows ‚Äď con ¬†Xamarin Forms

Pasamos a explicar como funciona la librería.

1. Primero debemos crear ¬†el codigo responsable para crear¬†¬†la vista efecto parallax . Creamos un¬†nuevo ‚ÄúContentView‚ÄĚ llamado ‚ÄúParallaxView‚ÄĚ:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="DevsDNA.XFParallax.ParallaxView">
  <ContentView.Content>
    <Grid>
      <ContentView x:Name="Header" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" BackgroundColor="Blue"/>
      <ScrollView x:Name="ParentScroll" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
        <ContentView x:Name="Body"/>
      </ScrollView>
    </Grid>
  </ContentView.Content>
</ContentView>

2. EL Code behind para ‚ÄúParallaxView.xaml.cs‚ÄĚ deberia lucir como este :

namespace DevsDNA.XFParallax
{
    using Xamarin.Forms;
 
    public partial class ParallaxView : ContentView
    {
        private double lastScroll = 0;
 
        public static readonly BindableProperty HeaderContentProperty = BindableProperty.Create(nameof(HeaderContent), typeof(ContentView), typeof(ParallaxView), coerceValue: HeaderContentCoerceValue);
        public static readonly BindableProperty HeaderScrollSpeedProperty = BindableProperty.Create(nameof(HeaderScrollSpeed), typeof(int), typeof(ParallaxView), 2);
        public static readonly BindableProperty BodyContentProperty = BindableProperty.Create(nameof(BodyContent), typeof(ContentView), typeof(ParallaxView), coerceValue: BodyContentCoerceValue);
        public static readonly BindableProperty BodyMarginProperty = BindableProperty.Create(nameof(BodyMargin), typeof(Thickness), typeof(ParallaxView), new Thickness(0), coerceValue: BodyMarginCoerceValue);
 
        public ParallaxView()
        {
            InitializeComponent();
            ParentScroll.Scrolled += ParentScroll_Scrolled;
        }
 
        public ContentView HeaderContent
        {
            get { return (ContentView)GetValue(HeaderContentProperty); }
            set { SetValue(HeaderContentProperty, value); }
        }
 
        public int HeaderScrollSpeed
        {
            get { return (int)GetValue(HeaderScrollSpeedProperty); }
            set { SetValue(HeaderScrollSpeedProperty, value); }
        }
 
        public ContentView BodyContent
        {
            get { return (ContentView)GetValue(BodyContentProperty); }
            set { SetValue(BodyContentProperty, value); }
        }
 
        public Thickness BodyMargin
        {
            get { return (Thickness)GetValue(BodyMarginProperty); }
            set { SetValue(BodyMarginProperty, value); }
        }
        /// 
        <summary>
        /// Important to call this method from Page OnDissapearing to remove event handlers and avoid memory leaks.
        /// </summary>
 
        public void DestroyParallaxView()
        {
            ParentScroll.Scrolled -= ParentScroll_Scrolled;
        }
 
        private static object HeaderContentCoerceValue(BindableObject bindableObject, object value)
        {
            if (bindableObject != null && value != null && value is ContentView)
            {
                ParallaxView instance = (ParallaxView)bindableObject;
 
                instance.Header.Content = (ContentView)value;
            }
            return value;
        }
 
        private static object BodyContentCoerceValue(BindableObject bindableObject, object value)
        {
            if (bindableObject != null && value != null && value is ContentView)
            {
                ParallaxView instance = (ParallaxView)bindableObject;
 
                instance.Body.Content = (ContentView)value;
 
                if (instance.BodyMargin != null)
                {
                    instance.Body.Margin = instance.BodyMargin;
                }
            }
            return value;
        }
 
        private static object BodyMarginCoerceValue(BindableObject bindableObject, object value)
        {
            if (bindableObject != null && value != null && value is Thickness)
            {
                ParallaxView instance = (ParallaxView)bindableObject;
 
                if (instance.Body != null)
                {
                    instance.Body.Margin = instance.BodyMargin;
                }
            }
            return value;
        }
 
        private void ParentScroll_Scrolled(object sender, ScrolledEventArgs e)
        {
            if (lastScroll == 0)
                lastScroll = e.ScrollY;
            else
            {
                CalculateHeaderTranslation(e);
            }
        }
 
        private void CalculateHeaderTranslation(ScrolledEventArgs e)
        {
            double translation = 0;
 
            if (lastScroll < e.ScrollY) { translation = 0 - ((e.ScrollY / HeaderScrollSpeed)); if (translation > 0)
                    translation = 0;
            }
            else
            {
                translation = 0 + ((e.ScrollY / HeaderScrollSpeed));
                if (translation > 0)
                    translation = 0;
            }
            Header.TranslateTo(Header.TranslationX, translation);
            lastScroll = e.ScrollY;
        }
    }
}

3. Ahora podemos usar Parallax en una de nuestras  Content Pages, como se muestra a  continuación:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:DevsDNA.XFParallax.Sample" xmlns:parallax="clr-namespace:DevsDNA.XFParallax;assembly=DevsDNA.XFParallax" x:Class="DevsDNA.XFParallax.Sample.MainPage">
 
  <parallax:ParallaxView x:Name="MainParallax" BodyMargin="0,180,0,0" HeaderScrollSpeed="4">
    <parallax:ParallaxView.HeaderContent>
      <ContentView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="Blue">
        <Image Source="https://www.windowscentral.com/sites/wpcentral.com/files/styles/large/public/field/image/2016/02/microsoft-xamirin.jpg?itok=M_JRL3qE" Aspect="AspectFill" VerticalOptions="Start"/>
      </ContentView>
    </parallax:ParallaxView.HeaderContent> 
    <parallax:ParallaxView.BodyContent>
      <ContentView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="White" HeightRequest="500">
        <ContentView.Margin>
          <!-- need to add specific margin to Windows to show header.-->
          <OnPlatform x:TypeArguments="Thickness" WinPhone="0,180,0,0"/>
        </ContentView.Margin>
        <Grid BackgroundColor="White">
                    <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition />
                </Grid.RowDefinitions>
                     
                <Image HorizontalOptions="Center" VerticalOptions="Start" Margin="0,-50,0,0" HeightRequest="100" WidthRequest="100" Grid.Row="0" Source="http://students.stmaryschs.org.uk/Y9_Scratch_To_VB/images/VS_Logo.png" Aspect="AspectFit"/>
                <Label Text="Xamarin Parallax Effect!" Grid.Row="1" HorizontalOptions="Center"/>
                     
        </Grid>
      </ContentView>
    </parallax:ParallaxView.BodyContent>
  </parallax:ParallaxView>
 
</ContentPage>

4. Ahora en el ¬†code behind invocamos¬†‚ÄúDestroyParallaxView‚ÄĚ en el m√©todo llamado ¬†MainParallax¬†en el metodo ‚ÄúOnDisappearing‚ÄĚ :

public partial class MainPage : ContentPage
  {
      public MainPage()
      {
          InitializeComponent();
      }
 
      protected override void OnDisappearing()
      {
          base.OnDisappearing();
          // To avoid memory leak:
          MainParallax.DestroyParallaxView();
      }
  }

Y así es como tenemos el hermoso efecto Parrallax en nuestra aplicacion Xamarin Forms.

Quieres verlo funcionando ?

Ejecuta tu codigo y dejame saber que tal !!

Cualquier duda o comentario puedes escribirme o dejar un comentario en la entrada !