Consumo de extensiones de marcado XAML
Las extensiones de marcado XAML ayudan a mejorar la eficacia y la flexibilidad de XAML al permitir que los atributos de elemento se establezcan desde una variedad de orígenes. Varias extensiones de marcado XAML forman parte de la especificación XAML 2009. Estos aparecen en archivos XAML con el prefijo de espacio de nombres habitual x
y se denominan normalmente con este prefijo. En este artículo se describen las siguientes extensiones de marcado:
x:Static
: referencia a propiedades estáticas, campos o miembros de enumeración.x:Reference
: referencia a elementos con nombre en la página.x:Type
: establece un atributo en un objetoSystem.Type
.x:Array
: crea una matriz de objetos de un tipo determinado.x:Null
: establece un atributo en un valornull
.OnPlatform
: personaliza la apariencia de la interfaz de usuario por plataforma.OnIdiom
: personaliza la apariencia de la interfaz de usuario en función de la expresión del dispositivo en el que se ejecuta la aplicación.DataTemplate
: convierte un tipo enDataTemplate
.FontImage
: muestra un icono de fuente en cualquier vista que pueda mostrar unImageSource
.AppThemeBinding
: consume un recurso basado en el tema actual del sistema.
Otras implementaciones de XAML admiten históricamente extensiones de marcado XAML adicionales y también son compatibles con Xamarin.Forms. Estos se describen más por completo en otros artículos:
StaticResource
: hace referencia a objetos de un diccionario de recursos, como se describe en el artículo Diccionarios de recursos.DynamicResource
: responde a los cambios en los objetos de un diccionario de recursos, como se describe en el artículo Estilos dinámicos.Binding
: establece un vínculo entre las propiedades de dos objetos, como se describe en el artículo Enlace de datos.TemplateBinding
: realiza el enlace de datos desde una plantilla de control, como se describe en el artículo Plantillas de control de Xamarin.Forms.RelativeSource
: establece el origen de enlace en relación con la posición del destino de enlace, como se describe en el artículo Enlaces relativos.
El diseño RelativeLayout
usa la extensión de marcado personalizada ConstraintExpression
. Esta extensión de marcado se describe en el artículo RelativeLayout.
Extensión de marcado x:Static
La extensión de marcado x:Static
es compatible con la clase StaticExtension
. La clase tiene una sola propiedad denominada Member
de tipo string
que se establece en el nombre de una constante pública, una propiedad estática, un campo estático o un miembro de enumeración.
Una manera común de usar x:Static
es definir primero una clase con algunas constantes o variables estáticas, como esta pequeña clase AppConstants
:
static class AppConstants
{
public static double NormalFontSize = 18;
}
En la página x:Demostración estática se muestran varias maneras de usar la extensión de marcado de x:Static
. El enfoque más detallado crea una instancia de la clase StaticExtension
entre etiquetas de elemento de propiedad Label.FontSize
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:sys="clr-namespace:System;assembly=netstandard"
xmlns:local="clr-namespace:MarkupExtensions"
x:Class="MarkupExtensions.StaticDemoPage"
Title="x:Static Demo">
<StackLayout Margin="10, 0">
<Label Text="Label No. 1">
<Label.FontSize>
<x:StaticExtension Member="local:AppConstants.NormalFontSize" />
</Label.FontSize>
</Label>
···
</StackLayout>
</ContentPage>
El analizador XAML también permite abreviar la clase StaticExtension
como x:Static
:
<Label Text="Label No. 2">
<Label.FontSize>
<x:Static Member="local:AppConstants.NormalFontSize" />
</Label.FontSize>
</Label>
Esto se puede simplificar aún más, pero el cambio introduce cierta sintaxis nueva: consiste en colocar la clase StaticExtension
y el valor de miembro en llaves. La expresión resultante se establece directamente en el atributo FontSize
:
<Label Text="Label No. 3"
FontSize="{x:StaticExtension Member=local:AppConstants.NormalFontSize}" />
Observe que no hay comillas dentro de las llaves. La propiedad Member
de StaticExtension
ya no es un atributo XML. En su lugar, forma parte de la expresión de la extensión de marcado.
Del mismo modo que puedes abreviar x:StaticExtension
a x:Static
cuando lo usas como elemento de objeto, también puedes abreviarlo en la expresión entre llaves:
<Label Text="Label No. 4"
FontSize="{x:Static Member=local:AppConstants.NormalFontSize}" />
La clase StaticExtension
tiene un atributo ContentProperty
que hace referencia a la propiedad Member
, que marca esta propiedad como la propiedad de contenido predeterminada de la clase. Para las extensiones de marcado XAML expresadas con llaves, puedes eliminar la parte Member=
de la expresión:
<Label Text="Label No. 5"
FontSize="{x:Static local:AppConstants.NormalFontSize}" />
Esta es la forma más común de la extensión de marcado x:Static
.
La página Demostración estática contiene otros dos ejemplos. La etiqueta raíz del archivo XAML contiene una declaración de espacio de nombres XML para el espacio de nombres de .NET System
:
xmlns:sys="clr-namespace:System;assembly=netstandard"
Esto permite establecer el tamaño de fuente Label
en el campo estático Math.PI
. El resultado es un texto bastante pequeño, por lo que la propiedad Scale
se establece en Math.E
:
<Label Text="π × E sized text"
FontSize="{x:Static sys:Math.PI}"
Scale="{x:Static sys:Math.E}"
HorizontalOptions="Center" />
En el ejemplo final se muestra el valor de Device.RuntimePlatform
. La propiedad estática Environment.NewLine
se usa para insertar un carácter de nueva línea entre los dos objetos Span
:
<Label HorizontalTextAlignment="Center"
FontSize="{x:Static local:AppConstants.NormalFontSize}">
<Label.FormattedText>
<FormattedString>
<Span Text="Runtime Platform: " />
<Span Text="{x:Static sys:Environment.NewLine}" />
<Span Text="{x:Static Device.RuntimePlatform}" />
</FormattedString>
</Label.FormattedText>
</Label>
Este es el ejemplo en ejecución:
Extensión de marcado x:Reference
La extensión de marcado x:Reference
es compatible con la clase ReferenceExtension
. La clase tiene una sola propiedad denominada Name
de tipo string
que se establece en el nombre de un elemento de la página a la que se le ha asignado un nombre con x:Name
. Esta propiedad Name
es la propiedad de contenido de ReferenceExtension
, por lo que Name=
no es obligatorio cuando x:Reference
aparece entre llaves.
La extensión de marcado x:Reference
se usa exclusivamente con enlaces de datos, que se describen con más detalle en el artículo Enlace de datos.
En la página x:Demostración de referencia se muestran dos usos de x:Reference
con enlaces de datos, el primero donde se usa para establecer la propiedad Source
del objeto Binding
y el segundo donde se usa para establecer la propiedad BindingContext
para dos enlaces de datos:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.ReferenceDemoPage"
x:Name="page"
Title="x:Reference Demo">
<StackLayout Margin="10, 0">
<Label Text="{Binding Source={x:Reference page},
StringFormat='The type of this page is {0}'}"
FontSize="18"
VerticalOptions="CenterAndExpand"
HorizontalTextAlignment="Center" />
<Slider x:Name="slider"
Maximum="360"
VerticalOptions="Center" />
<Label BindingContext="{x:Reference slider}"
Text="{Binding Value, StringFormat='{0:F0}° rotation'}"
Rotation="{Binding Value}"
FontSize="24"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage>
Ambas expresiones x:Reference
usan la versión abreviada del nombre de clase ReferenceExtension
y eliminan la parte Name=
de la expresión. En el primer ejemplo, la extensión de marcado x:Reference
se inserta en la extensión de marcado Binding
. Tenga en cuenta que la configuración de Source
y StringFormat
están separadas por comas. Esta es la ejecución del programa:
Extensión de marcado x:Type
La extensión de marcado x:Type
es el equivalente en XAML de la palabra clave de C# typeof
. Es compatible con la clase TypeExtension
, que define una propiedad denominada TypeName
de tipo string
que se establece en un nombre de clase o estructura. La extensión de marcado x:Type
devuelve el objeto System.Type
de esa clase o estructura. TypeName
es la propiedad de contenido de TypeExtension
, por lo que TypeName=
no es obligatorio cuando x:Type
aparece con llaves.
En Xamarin.Forms, hay varias propiedades que tienen argumentos de tipo Type
. Algunos ejemplos incluyen la propiedad TargetType
de Style
y el atributo x:TypeArguments usado para especificar argumentos en clases genéricas. Sin embargo, el analizador XAML realiza automáticamente la operación de typeof
y la extensión de marcado x:Type
no se usa en estos casos.
Un lugar donde x:Type
es necesario es con la x:Array
extensión de marcado, que se describe en la sección siguiente.
La extensión de marcado x:Type
también es útil al construir un menú donde cada elemento de menú corresponde a un objeto de un tipo determinado. Puede asociar un objeto Type
a cada elemento de menú y, a continuación, crear una instancia del objeto cuando se selecciona el elemento de menú.
Así es como funciona el menú de navegación en MainPage
del programa Extensiones de marcado. El archivo MainPage.xaml contiene un TableView
con cada TextCell
correspondiente a una página determinada del programa:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MarkupExtensions"
x:Class="MarkupExtensions.MainPage"
Title="Markup Extensions"
Padding="10">
<TableView Intent="Menu">
<TableRoot>
<TableSection>
<TextCell Text="x:Static Demo"
Detail="Access constants or statics"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:StaticDemoPage}" />
<TextCell Text="x:Reference Demo"
Detail="Reference named elements on the page"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:ReferenceDemoPage}" />
<TextCell Text="x:Type Demo"
Detail="Associate a Button with a Type"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:TypeDemoPage}" />
<TextCell Text="x:Array Demo"
Detail="Use an array to fill a ListView"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:ArrayDemoPage}" />
···
</TableRoot>
</TableView>
</ContentPage>
Esta es la página principal de apertura de extensiones de marcado:
Cada propiedad CommandParameter
se establece en una extensión de marcado x:Type
que hace referencia a una de las otras páginas. La propiedad Command
está enlazada a una propiedad denominada NavigateCommand
. Esta propiedad se define en el archivo de código subyacente MainPage
:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
NavigateCommand = new Command<Type>(async (Type pageType) =>
{
Page page = (Page)Activator.CreateInstance(pageType);
await Navigation.PushAsync(page);
});
BindingContext = this;
}
public ICommand NavigateCommand { private set; get; }
}
La propiedad NavigateCommand
es un objeto Command
que implementa un comando execute con un argumento de tipo Type
, el valor de CommandParameter
. El método usa Activator.CreateInstance
para crear instancias de la página y, a continuación, navegar a ella. El constructor concluye estableciendo el BindingContext
de la página en sí mismo, lo que permite que el Binding
en Command
funcione. Consulte el artículo Enlace de datos y, especialmente, el artículo Comandos para obtener más información sobre este tipo de código.
La página Demostración x:Type usa una técnica similar para crear instancias de elementos Xamarin.Forms y agregarlos a StackLayout
. El archivo XAML consta inicialmente de tres elementos Button
con sus propiedades de Command
establecidas en un Binding
y las propiedades de CommandParameter
establecidas en tipos de tres vistas de Xamarin.Forms:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.TypeDemoPage"
Title="x:Type Demo">
<StackLayout x:Name="stackLayout"
Padding="10, 0">
<Button Text="Create a Slider"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Slider}" />
<Button Text="Create a Stepper"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Stepper}" />
<Button Text="Create a Switch"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Switch}" />
</StackLayout>
</ContentPage>
El archivo de código subyacente define e inicializa la propiedad CreateCommand
:
public partial class TypeDemoPage : ContentPage
{
public TypeDemoPage()
{
InitializeComponent();
CreateCommand = new Command<Type>((Type viewType) =>
{
View view = (View)Activator.CreateInstance(viewType);
view.VerticalOptions = LayoutOptions.CenterAndExpand;
stackLayout.Children.Add(view);
});
BindingContext = this;
}
public ICommand CreateCommand { private set; get; }
}
El método que se ejecuta cuando se presiona una Button
crea una nueva instancia del argumento, establece su propiedad VerticalOptions
y la agrega al StackLayout
. A continuación, los tres elementos Button
comparten la página con vistas creadas dinámicamente:
Extensión de marcado x:Array
La extensión de marcado x:Array
permite definir una matriz en el marcado. Es compatible con la clase ArrayExtension
, que define dos propiedades:
Type
de tipoType
, que indica el tipo de los elementos de la matriz.Items
de tipoIList
, que es una colección de los elementos por sí solos. Es la propiedad de contenido deArrayExtension
.
La propia extensión de marcado x:Array
nunca aparece entre llaves. En su lugar, las etiquetas start y end x:Array
delimitan la lista de elementos. Establezca la propiedad Type
en una extensión de marcado x:Type
.
La página Demostración x:Array muestra cómo usar x:Array
para agregar elementos a ListView
mediante el establecimiento de la propiedad ItemsSource
en una matriz:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.ArrayDemoPage"
Title="x:Array Demo Page">
<ListView Margin="10">
<ListView.ItemsSource>
<x:Array Type="{x:Type Color}">
<Color>Aqua</Color>
<Color>Black</Color>
<Color>Blue</Color>
<Color>Fuchsia</Color>
<Color>Gray</Color>
<Color>Green</Color>
<Color>Lime</Color>
<Color>Maroon</Color>
<Color>Navy</Color>
<Color>Olive</Color>
<Color>Pink</Color>
<Color>Purple</Color>
<Color>Red</Color>
<Color>Silver</Color>
<Color>Teal</Color>
<Color>White</Color>
<Color>Yellow</Color>
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<BoxView Color="{Binding}"
Margin="3" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
ViewCell
crea un BoxView
simple para cada entrada de color:
Hay varias maneras de especificar los elementos Color
individuales de esta matriz. Puede usar una extensión de marcado x:Static
:
<x:Static Member="Color.Blue" />
O bien, puede usar StaticResource
para recuperar un color de un diccionario de recursos:
<StaticResource Key="myColor" />
Al final de este artículo, verá una extensión de marcado XAML personalizada que también crea un nuevo valor de color:
<local:HslColor H="0.5" S="1.0" L="0.5" />
Al definir matrices de tipos comunes como cadenas o números, use las etiquetas enumeradas en el artículo Paso de argumentos del constructor para delimitar los valores.
Extensión de marcado x:Null
La clase de marcado x:Null
es compatible con la clase NullExtension
. No tiene propiedades y es simplemente el equivalente en XAML de la palabra clave de C# null
.
La extensión de marcado x:Null
rara vez es necesaria y rara vez se usa, pero si encuentra una necesidad para ella, se alegrará de que exista.
En la página Demostración x:Null se muestra un escenario en el que x:Null
puede resultar conveniente. Supongamos que define un Style
implícito para Label
que incluye un Setter
que establece la propiedad FontFamily
en un nombre de familia dependiente de la plataforma:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.NullDemoPage"
Title="x:Null Demo">
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="Label">
<Setter Property="FontSize" Value="48" />
<Setter Property="FontFamily">
<Setter.Value>
<OnPlatform x:TypeArguments="x:String">
<On Platform="iOS" Value="Times New Roman" />
<On Platform="Android" Value="serif" />
<On Platform="UWP" Value="Times New Roman" />
</OnPlatform>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout Padding="10, 0">
<Label Text="Text 1" />
<Label Text="Text 2" />
<Label Text="Text 3"
FontFamily="{x:Null}" />
<Label Text="Text 4" />
<Label Text="Text 5" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
A continuación, descubre que para uno de los elementos Label
, quiere que todos los valores de propiedad del Style
implícito, excepto para el FontFamily
, que quiere que sea el valor predeterminado. Puede definir otro Style
para ese propósito, pero un enfoque más sencillo es simplemente establecer la propiedad FontFamily
del Label
particular en x:Null
, como se muestra en el Label
del centro.
Esta es la ejecución del programa:
Observe que cuatro de los elementos Label
tienen una fuente serif, pero el centro Label
tiene la fuente sans-serif predeterminada.
Extensión de marcado OnPlatform
La extensión de marcado OnPlatform
le permite personalizar el aspecto de la interfaz de usuario para cada plataforma. Ofrece la misma función que las clases OnPlatform
y On
, pero con una representación más concisa.
La clase OnPlatform
admite la extensión de marcado OnPlatformExtension
, que define las siguientes propiedades:
Default
de tipoobject
, que se establece en un valor predeterminado que se aplicará a las propiedades que representan las plataformas.Android
de tipoobject
, que se establece en un valor que se va a aplicar en Android.GTK
de tipoobject
, que se establece en un valor que se aplicará en plataformas GTK.iOS
de tipoobject
, que se establece en un valor que se va a aplicar en iOS.macOS
de tipoobject
, que se establece en un valor que se aplicará en macOS.Tizen
de tipoobject
, que se establece en un valor que se va a aplicar en la plataforma Tizen.UWP
de tipoobject
, que se establece en un valor que se aplicará en la Plataforma universal de Windows.WPF
de tipoobject
, que se establece en un valor que se aplicará en la plataforma de Windows Presentation Foundation.Converter
de tipoIValueConverter
, que se puede establecer en una implementaciónIValueConverter
.ConverterParameter
de tipoobject
, que se puede establecer en un valor para pasar a la implementaciónIValueConverter
.
Nota:
El analizador de XAML permite abreviar la clase OnPlatformExtension
como OnPlatform
.
La propiedad Default
es la propiedad de contenido de OnPlatformExtension
. Por lo tanto, para las expresiones de marcado XAML expresadas con llaves, puede eliminar la parte Default=
de la expresión, siempre que se trate del primer argumento. Si la propiedad Default
no está establecida, se establecerá de forma predeterminada en el valor de la propiedad BindableProperty.DefaultValue
, siempre que la extensión de marcado tenga como destino BindableProperty
.
Importante
El analizador XAML espera que los valores del tipo correcto se proporcionen a las propiedades que consumen la extensión de marcado OnPlatform
. Si es necesaria la conversión de tipos, la extensión de marcado OnPlatform
intentará realizarla mediante los convertidores predeterminados proporcionados por Xamarin.Forms. Pero, hay algunas conversiones de tipo que no se pueden realizar en los convertidores predeterminados y, en estos casos, la propiedad Converter
debe establecerse en una implementación IValueConverter
.
En la página Demostración de OnPlatform se muestra cómo usar la extensión de marcado OnPlatform
:
<BoxView Color="{OnPlatform Yellow, iOS=Red, Android=Green, UWP=Blue}"
WidthRequest="{OnPlatform 250, iOS=200, Android=300, UWP=400}"
HeightRequest="{OnPlatform 250, iOS=200, Android=300, UWP=400}"
HorizontalOptions="Center" />
En este ejemplo, las tres expresiones OnPlatform
usan la versión abreviada del nombre de clase OnPlatformExtension
. Las tres extensiones de marcado OnPlatform
establecen las propiedades Color
, WidthRequest
y HeightRequest
de BoxView
en valores diferentes en iOS, Android y UWP. Las extensiones de marcado también proporcionan valores predeterminados para estas propiedades en las plataformas que no se especifican, al tiempo que se elimina la parte de la expresión Default=
. Observe que las propiedades de la extensión de marcado que se establecen están separadas por comas.
Esta es la ejecución del programa:
Extensión de marcado OnIdiom
La extensión de marcado OnIdiom
le permite personalizar la apariencia de la interfaz de usuario en función de la expresión del dispositivo en el que se ejecuta la aplicación. La clase OnIdiomExtension
admite la extensión de marcado, que define las siguientes propiedades:
Default
de tipoobject
, que se establece en un valor predeterminado que se aplicará a las propiedades que representan los tipos de dispositivos.Phone
de tipoobject
, que se establece en un valor que se aplicará en teléfonos.Tablet
de tipoobject
, que se establece en un valor que se va a aplicar en tabletas.Desktop
de tipoobject
, que se establece en un valor que se aplicará en plataformas de escritorio.TV
de tipoobject
, que se establece en un valor que se va a aplicar en las plataformas de TV.Watch
de tipoobject
, que se establece en un valor que se va a aplicar en plataformas de relojes.Converter
de tipoIValueConverter
, que se puede establecer en una implementaciónIValueConverter
.ConverterParameter
de tipoobject
, que se puede establecer en un valor para pasar a la implementaciónIValueConverter
.
Nota:
El analizador de XAML permite abreviar la clase OnIdiomExtension
como OnIdiom
.
La propiedad Default
es la propiedad de contenido de OnIdiomExtension
. Por lo tanto, para las expresiones de marcado XAML expresadas con llaves, puede eliminar la parte Default=
de la expresión, siempre que se trate del primer argumento.
Importante
El analizador XAML espera que los valores del tipo correcto se proporcionen a las propiedades que consumen la extensión de marcado OnIdiom
. Si es necesaria la conversión de tipos, la extensión de marcado OnIdiom
intentará realizarla mediante los convertidores predeterminados proporcionados por Xamarin.Forms. Pero, hay algunas conversiones de tipo que no se pueden realizar en los convertidores predeterminados y, en estos casos, la propiedad Converter
debe establecerse en una implementación IValueConverter
.
En la página Demostración de OnIdiom se muestra cómo usar la extensión de marcado OnIdiom
:
<BoxView Color="{OnIdiom Yellow, Phone=Red, Tablet=Green, Desktop=Blue}"
WidthRequest="{OnIdiom 100, Phone=200, Tablet=300, Desktop=400}"
HeightRequest="{OnIdiom 100, Phone=200, Tablet=300, Desktop=400}"
HorizontalOptions="Center" />
En este ejemplo, las tres expresiones OnIdiom
usan la versión abreviada del nombre de clase OnIdiomExtension
. Las tres extensiones de marcadoOnIdiom
establecen las propiedades Color
, WidthRequest
y HeightRequest
de BoxView
en valores diferentes en las expresiones de teléfono, tableta y escritorio. Las extensiones de marcado también proporcionan valores predeterminados para estas propiedades en las expresiones que no se especifican, al tiempo que se elimina la parte Default=
de la expresión. Observe que las propiedades de la extensión de marcado que se establecen están separadas por comas.
Esta es la ejecución del programa:
Extensión de marcado DataTemplate
La extensión de marcado DataTemplate
te permite convertir un tipo en DataTemplate
. Es compatible con la clase DataTemplateExtension
, que define una propiedad TypeName
, de tipo string
, que se establece en el nombre del tipo que se va a convertir en DataTemplate
. La propiedad TypeName
es la propiedad de contenido de DataTemplateExtension
. Por lo tanto, para las expresiones de marcado XAML expresadas con llaves, puede eliminar la parte TypeName=
de la expresión.
Nota:
El analizador de XAML permite abreviar la clase DataTemplateExtension
como DataTemplate
.
Una utilización típica de esta extensión de marcado se encuentra en una aplicación de Shell, como se muestra en el ejemplo siguiente:
<ShellContent Title="Monkeys"
Icon="monkey.png"
ContentTemplate="{DataTemplate views:MonkeysPage}" />
En este ejemplo, MonkeysPage
se convierte de ContentPage
a DataTemplate
, que se establece como el valor de la propiedad ShellContent.ContentTemplate
. Esto garantiza que MonkeysPage
solo se crea cuando se navega a la página, no al iniciar la aplicación.
Para más información sobre las aplicaciones de Shell, consulte Xamarin.Forms Shell.
Extensión de marcado FontImage
La extensión de marcado FontImage
te permite mostrar un icono de fuente en cualquier vista que pueda mostrar un ImageSource
. Proporciona la misma funcionalidad que la clase FontImageSource
, pero con una representación más concisa.
La clase FontImage
admite la extensión de marcado FontImageExtension
, que define las siguientes propiedades:
FontFamily
de tipostring
, la familia de fuentes a la que pertenece el icono de fuente.Glyph
de tipostring
, el valor de carácter unicode del icono de fuente.Color
de tipoColor
, el color que se va a usar al mostrar el icono de fuente.Size
de tipodouble
, el tamaño, en unidades independientes del dispositivo, del icono de fuente representado. El valor predeterminado es 30. Además, esta propiedad se puede establecer en un tamaño de fuente con nombre.
Nota:
El analizador de XAML permite abreviar la clase FontImageExtension
como FontImage
.
La propiedad Glyph
es la propiedad de contenido de FontImageExtension
. Por lo tanto, para las expresiones de marcado XAML expresadas con llaves, puedes eliminar la parte Glyph=
de la expresión siempre que sea el primer argumento.
La página Demostración de FontImage muestra cómo usar la extensión de marcado FontImage
:
<Image BackgroundColor="#D1D1D1"
Source="{FontImage , FontFamily={OnPlatform iOS=Ionicons, Android=ionicons.ttf#}, Size=44}" />
En este ejemplo, la versión abreviada del nombre de clase FontImageExtension
se usa para mostrar un icono XBox, de la familia de fuentes Ionicons, en un Image
. La expresión también usa la extensión de marcado OnPlatform
para especificar valores de propiedad FontFamily
diferentes en iOS y Android. Además, se elimina la parte Glyph=
de la expresión y las propiedades de extensión de marcado que se establecen están separadas por comas. Tenga en cuenta que, aunque el carácter unicode del icono es \uf30c
, debe escaparse en XAML y, por tanto, se convierte en 
.
Esta es la ejecución del programa:
Para obtener información sobre cómo mostrar iconos de fuente especificando los datos del icono de fuente en un objeto FontImageSource
, consulta Visualización de iconos de fuente.
AppThemeBinding (extensión de marcado)
La extensión de marcado AppThemeBinding
permite especificar un recurso que se va a consumir, como una imagen o un color, en función del tema del sistema actual.
Importante
La extensión de marcado AppThemeBinding
tiene requisitos mínimos del sistema operativo. Para obtener más información, consulte Responder a los cambios del tema del sistema en las aplicaciones de Xamarin.Forms.
La clase AppThemeBinding
admite la extensión de marcado AppThemeBindingExtension
, que define las siguientes propiedades:
Default
, de tipoobject
, que se establece en el recurso que se va a usar de forma predeterminada.Light
, de tipoobject
, que se establece en el recurso que se va a usar cuando el dispositivo usa su tema claro.Dark
, de tipoobject
, que se establece en el recurso que se va a usar cuando el dispositivo usa su tema oscuro.Value
, de tipoobject
, que devuelve el recurso que está usando actualmente la extensión de marcado.
Nota:
El analizador de XAML permite abreviar la clase AppThemeBindingExtension
como AppBindingTheme
.
La propiedad Default
es la propiedad de contenido de AppThemeBindingExtension
. Por lo tanto, para las expresiones de marcado XAML expresadas con llaves, puedes eliminar la parte Default=
de la expresión siempre que sea el primer argumento.
En la página Demostración de AppThemeBinding se muestra cómo usar la extensión de marcado AppThemeBinding
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.AppThemeBindingDemoPage"
Title="AppThemeBinding Demo">
<ContentPage.Resources>
<Style x:Key="labelStyle"
TargetType="Label">
<Setter Property="TextColor"
Value="{AppThemeBinding Black, Light=Blue, Dark=Teal}" />
</Style>
</ContentPage.Resources>
<StackLayout Margin="20">
<Label Text="This text is green in light mode, and red in dark mode."
TextColor="{AppThemeBinding Light=Green, Dark=Red}" />
<Label Text="This text is black by default, blue in light mode, and teal in dark mode."
Style="{StaticResource labelStyle}" />
</StackLayout>
</ContentPage>
En este ejemplo, el color de texto del primer Label
se establece en verde cuando el dispositivo usa su tema claro y se establece en rojo cuando el dispositivo usa su tema oscuro. El segundo Label
tiene su propiedad TextColor
establecida a través de un Style
. Style
establece el color de texto de Label
en negro de forma predeterminada, en azul cuando el dispositivo usa su tema claro y en verde azulado cuando el dispositivo usa su tema oscuro.
Esta es la ejecución del programa:
Definición de extensiones de marcado
Si ha encontrado una necesidad de una extensión de marcado XAML que no está disponible en Xamarin.Forms, puede crear una propia.