Este es el primer post de una serie sobre data binding avanzado. Veremos value converters, relative binding, {Binding .} y {Binding self}, constructores y mas.

Esperamos publicar un nuevo post semanal o quincenal.

Empezando

En breve publicaremos un post introductorio a data binding.

Ejemplos

Por cada tema a cubrir, proveeremos un ejemplo simple (tan simple como sea posible), el cual estara disponible en GitHub y enlazado en el post. Usaremos estos ejemplos para eliminar cualquier confusion y ayudar a comprender mejor los temas.

Algunos de los ejemplos de esta serie seran creados por nosotros y otros tomados de la documentacion oficial de Microsoft. Lo cual nos hace preguntarnos, porque utilizar estos posts en lugar de la documentacion oficial? Desde nuestro punto de vista, la documentacion de Microsoft es exhaustiva, pero a veces puede ser abrumadora. Ademas la utilizacion de multiples origenes, pueden ayudar a obtener un mejor entendimiento del tema.

Topico #1: Paths

El uso de la palabra clave path es un buen punto intermedio para comenzar. Puede ser usada de diferentes maneras. El uso mas frecuente es para apuntar a la propiedad de un objeto almacenado en un recurso, o para apuntar a la propiedad de un objeto miembro.

Ejemplo

Aqui tenemos un ejemplo que podemos analizar. Para crearlo, abrimos Visual Studio 2022 y creamos una nueva aplicacion cross platform de Xamarin.Forms, utilizando el template en blanco. Esto nos dara los archivos MainPage.xaml y MainPage.xaml.cs que es todo lo que necesitaremos en este caso.

Por ahora no tocaremos MainPage.xaml.cs, y haremos todo el trabajo en MainPage.xaml. Todos los usos de path seran realizados en forma declarativa.

Aqui esta el ejemplo completo:

<ContentPage
	x:Class="PathDemo.MainPage"
	xmlns="http://xamarin.com/schemas/2014/forms"
	xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
	xmlns:globe="clr-namespace:System.Globalization;assembly=netstandard"
	x:Name="page">

	<StackLayout Margin="10,50">

		<TimePicker x:Name="timePicker" Time="17:05" />

		<Label Text="{Binding Source={x:Reference timePicker}, Path=Time.TotalSeconds, StringFormat='{0} total seconds'}" />

		<Slider
			x:Name="slider"
			BackgroundColor="DarkSlateGray"
			Maximum="10"
			Minimum="0"
			ThumbColor="Red"
			Value="4" />

		<!--  Path and BindingContext set in the binding  -->
		<Label Text="{Binding Source={x:Reference slider}, Path=Value, StringFormat='The value of slider is {0}'}" />

		<!--  Path as content property  -->
		<Label Text="{Binding Value, Source={x:Reference slider}, StringFormat='The value of slider is {0}'}" />

		<!--  Path as content property & setting the binding context  -->
		<Label BindingContext="{x:Reference slider}" Text="{Binding Value, StringFormat='The value of slider is {0}'}" />

		<Label Text="{Binding Source={x:Static globe:CultureInfo.CurrentCulture}, Path=DateTimeFormat.DayNames[3], StringFormat='The middle day of the week is {0}'}" />

	</StackLayout>

</ContentPage>

El primer paso es declarar un control del tipo TimePicker y llamarlo timePicker (el nombre es importante). Inicializamos la hora con el valor 17:05 (5:05pm).

Ahora estamos listos para accedor a la propiedad del TimePicker llamada Time. Pero en nuestro caso, al valor que realmente queremos acceder es a la sub propiedad TotalSeconds. Esto no es un problema, establecemos el origen al TimePicker usando Reference y el nombre (timePicker), y establecemos el path a la sub propiedad en la cual estamos interesados. Podemos ademas usar la clasula StringFormat para agregar mas informacion al mostrar el total de segundos.

Using path to capture a sub-property

En la segunda parte de este ejemplo, declaramos un slider, y establecemos algunos de sus atributos, incluyendo la inicializacion de su valor en 4. Estamos ahora listos para acceder al slider y su valor. Al mover el slider el valor de la etiqueta se actualizara.

Tying the label to the value of the slider

Notese que en la siguiente parte (path como la propiedad content), enlazamos el valor y establecemos el origen utilizando el path en forma implicita. Esto quiere decir que podemos escribir:

<!--  Path as content property  -->
<Label Text="{Binding Value, Source={x:Reference slider}, StringFormat='The value of slider is {0}'}" />

En este caso, utilizar Path es redundante.

Tambien existe la posibilidad de establecer el BindingContext en forma explicita al slider, en lugar de utilizar la propiedad Source del binding.

En resumen, existen distintas maneras de establecer el BindingContext, las cuales revisaremos en un futuro post introductorio.

En la parte final de este ejemplo, vamos a enlazar a CurrentCulture para lo cual utilizaremos un indice. Prestemos atencion, ya que no es evidente que podemos hacer lo siguiente:

The complete example

Los proximos post seran algo mas complejos o avanzados, pero queriamos empezar con algo mas sencillo.

La documentacion oficial sobre path se encuentra aqui.

El codigo fuente para este ejemplo (y para todos los ejemplos de esta serie) se encuentra aqui.

Este post y los ejemplos fueron escritos por Jesse Liberty y Rodrigo Juarez.

Jesse Liberty tiene tres decadas de experiencia escribiendo y entregando proyectos de software y ha escrito dos docenas de libros y unas cuantas docenas de cursos en Pluralsight y LinkedIn Learning. Ha sido Senior Technical Evangelist en Microsoft, Distinguished Software Engineer en AT&T, VP en Information Services para Citibank y Software Architect en PBS. El es un Xamarin Certified Mobile Developer, Xamarin MVP y Microsoft MVP. Lo podemos encontrar en Jesse Liberty.