Resumen del capítulo 10. Extensiones de marcado XAML

Nota:

Este libro se publicó en la primavera de 2016 y no se ha actualizado desde entonces. Gran parte del libro sigue siendo útil, pero algunos de los materiales están anticuados y algunos temas ya no son completamente correctos o completos.

Normalmente, el analizador de XAML convierte cualquier cadena establecida como un valor de atributo en el tipo de la propiedad basándose en las conversiones estándar de los tipos de datos de .NET básicos, o en un derivado de TypeConverter asociado a la propiedad o su tipo con TypeConverterAttribute.

Pero a veces es conveniente establecer un atributo de un origen diferente, por ejemplo, un elemento de un diccionario, el valor de un campo o una propiedad estática o un cálculo de algún tipo.

Este es el trabajo de una extensión de marcado XAML. A pesar del nombre, las extensiones de marcado XAML no son una extensión a XML. XAML es siempre XML válido.

Infraestructura de código

Una extensión de marcado XAML es una clase que implementa la interfaz IMarkupExtension. Una clase de este tipo suele tener la palabra Extension al final de su nombre, pero normalmente aparece en XAML sin ese sufijo.

Todas las implementaciones de XAML admiten las siguientes extensiones de marcado XAML:

Estas cuatro extensiones de marcado XAML son compatibles con muchas implementaciones de XAML, entre las que se incluyen Xamarin.Forms:

En Xamarin.Forms se incluye una extensión de marcado XAML adicional en conexión con RelativeLayout:

Acceso a miembros estáticos

Use el elemento x:Static para establecer un atributo en el valor de una propiedad, un campo o un miembro de enumeración estáticos públicos. Establezca la propiedad Member en el miembro estático. Normalmente es más fácil especificar x:Static y el nombre del miembro entre llaves. No es necesario incluir el nombre de la propiedad Member, solo el propio miembro. Esta sintaxis común se muestra en el ejemplo SharedStatics. Los propios campos estáticos se definen en la clase AppConstants. Esta técnica permite establecer constantes usadas en un programa.

Con una declaración de espacio de nombres XML adicional, puede hacer referencia a propiedades, campos o miembros de enumeración estáticos públicos definidos en .NET Framework, tal como se muestra en el ejemplo SystemStatics.

Diccionarios de recursos

La clase VisualElement define una propiedad denominada Resources que se puede establecer en un objeto de tipo ResourceDictionary. Dentro de XAML, puede almacenar los elementos de este diccionario e identificarlos con el atributo x:Key. Los elementos almacenados en el diccionario de recursos se comparten entre todas las referencias al elemento.

StaticResource para la mayoría de los fines

En la mayoría de los casos, usará la extensión de marcado StaticResource para hacer referencia a un elemento del diccionario de recursos, tal y como se muestra en el ejemplo ResourceSharing. Puede usar un elemento StaticResourceExtension o StaticResource entre llaves:

Captura de pantalla triple de uso compartido de recursos

No confunda la extensión de marcadox:Static y la extensión de marcado StaticResource.

Árbol de diccionarios

Cuando el analizador XAML encuentra StaticResource, comienza a buscar una clave coincidente en el árbol visual y, a continuación, busca ResourceDictionary en la clase App de la aplicación. Esto permite profundizar en los elementos de un diccionario de recursos en el árbol visual para reemplazar un diccionario de recursos situado más arriba en el árbol visual. Esto se muestra en el ejemplo ResourceTrees.

DynamicResource para fines especiales

La extensión de marcado StaticResource hace que un elemento se recupere del diccionario cuando se compila un árbol visual durante la llamada de InitializeComponent. Una alternativa a StaticResource es DynamicResource, que mantiene un vínculo a la clave del diccionario y actualiza el destino cuando cambia el elemento al que hace referencia la clave.

La diferencia entre StaticResource y DynamicResource se muestra en el ejemplo DynamicVsStatic.

Una propiedad establecida por DynamicResource debe estar respaldada por una propiedad enlazable, tal y como se describe en Capítulo 11l. La infraestructura enlazable.

Extensiones de marcado de menor uso

Use la extensión de marcado x:Null para establecer una propiedad en null.

Use la extensión de marcado x:Type para establecer una propiedad en un objeto Type de .NET.

Utilice x:Array para definir una matriz. Especifique el tipo de los miembros de la matriz estableciendo la propiedad [Type] en una extensión de marcado x:Type.

Extensión de marcado personalizada

Puede crear sus propias extensiones de marcado XAML escribiendo una clase que implemente la interfaz IMarkupExtension con un método ProvideValue.

La clase HslColorExtension cumple esos requisitos. Crea un valor de tipo Color basándose en los valores de las propiedades denominadas H, S, L y A. Esta clase es el primer elemento de una biblioteca de Xamarin.Forms denominada Xamarin.FormsBook.Toolkit que se crea y usa en el transcurso de este libro.

En el ejemplo CustomExtensionDemo se muestra cómo hacer referencia a esta biblioteca y utilizar la extensión de marcado personalizada.