Consumo de extensiones de marcado XAML

Descargar ejemplo. Descarga del ejemplo

Las extensiones de marcado XAML ayudan a mejorar la eficacia y flexibilidad de XAML al permitir que los atributos de elemento se establezcan desde diversos 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 y se conocen normalmente x con este prefijo. En este artículo se de abordan las siguientes extensiones de marcado:

  • x:Static : hace referencia a propiedades estáticas, campos o miembros de enumeración.
  • x:Reference : hace referencia a elementos con nombre en la página.
  • x:Type : establece un atributo en un System.Type objeto .
  • x:Array : construye una matriz de objetos de un tipo determinado.
  • x:Null : establezca un atributo en un null valor.
  • OnPlatform : personalice la apariencia de la interfaz de usuario por plataforma.
  • OnIdiom : personalice 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 en DataTemplate .
  • FontImage : muestra un icono de fuente en cualquier vista que pueda mostrar un ImageSource .
  • AppThemeBinding : consume un recurso basado en el tema actual del sistema.

Históricamente, otras implementaciones xaml han admitido extensiones de marcado XAML adicionales y también son compatibles con Xamarin.Forms . Estos se describen de forma más completa 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 las plantillas de Xamarin.Forms control del artículo.
  • RelativeSource : establece el origen de enlace con respecto a la posición del destino de enlace, como se describe en el artículo Enlaces relativos.

El RelativeLayout diseño usa la extensión de marcado personalizada ConstraintExpression . Esta extensión de marcado se describe en el artículo RelativeLayout.

x:Static (extensión de marcado)

La x:Static extensión de marcado es compatible con la clase StaticExtension . La clase tiene una sola propiedad denominada de tipo que se establece en el nombre de una constante pública, una propiedad estática, un campo estático o Member string un miembro de enumeración.

Una manera común de usar es definir primero una clase con algunas constantes o variables estáticas, como esta pequeña clase en el programa x:Static AppConstants MarkupExtensions:

static class AppConstants
{
    public static double NormalFontSize = 18;
}

La página x:Static Demo muestra varias maneras de usar la extensión de x:Static marcado. El enfoque más detallado crea una instancia de la StaticExtension clase entre Label.FontSize etiquetas property-element:

<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 que StaticExtension la clase se abreviado 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 una nueva sintaxis: consiste en colocar la clase y la configuración de miembro entre StaticExtension llaves. La expresión resultante se establece directamente en el FontSize atributo :

<Label Text="Label No. 3"
       FontSize="{x:StaticExtension Member=local:AppConstants.NormalFontSize}" />

Observe que no hay comillas dentro de las llaves. La Member propiedad de ya no es un atributo StaticExtension XML. En su lugar, forma parte de la expresión de la extensión de marcado.

Del mismo modo que puede abreviar al usarlo como un elemento de objeto, también puede abreviar en la expresión entre x:StaticExtension x:Static llaves:

<Label Text="Label No. 4"
       FontSize="{x:Static Member=local:AppConstants.NormalFontSize}" />

La clase tiene un atributo que hace referencia a la propiedad , que marca esta propiedad como la propiedad de contenido predeterminada StaticExtension ContentProperty de la Member clase. Para las extensiones de marcado XAML expresadas con llaves, puede eliminar la Member= parte 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 x:Static de marcado.

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 System .NET:

xmlns:sys="clr-namespace:System;assembly=netstandard"

Esto permite establecer Label el tamaño de fuente en el campo estático Math.PI . Esto da como resultado un texto bastante pequeño, por lo Scale que la propiedad se establece en Math.E :

<Label Text="&#x03C0; &#x00D7; E sized text"
       FontSize="{x:Static sys:Math.PI}"
       Scale="{x:Static sys:Math.E}"
       HorizontalOptions="Center" />

En el ejemplo final se muestra el Device.RuntimePlatform valor . La Environment.NewLine propiedad estática se usa para insertar un carácter de nueva línea entre los dos Span objetos:

<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:

! [x:Static Demo] (consuming-images/staticdemo-small.png "x:Static Demo".

Extensión de marcado x:Reference

La x:Reference extensión de marcado es compatible con la clase ReferenceExtension . La clase tiene una sola propiedad denominada de tipo que se establece en el nombre de un elemento de la página a la que se le ha dado Name string un nombre con x:Name . Esta Name propiedad es la propiedad de contenido de , por lo que no es necesario cuando aparece ReferenceExtension entre Name= x:Reference llaves.

La extensión de marcado se usa exclusivamente con enlaces de datos, que se describen con más detalle x:Reference en el artículo Enlace de datos.

La página x:Reference Demo muestra dos usos de con enlaces de datos, el primero donde se usa para establecer la propiedad del objeto y el segundo donde se usa para establecer la propiedad para dos enlaces de x:Reference Source Binding BindingContext 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}&#x00B0; rotation'}"
               Rotation="{Binding Value}"
               FontSize="24"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

    </StackLayout>
</ContentPage>

Ambas x:Reference expresiones usan la versión abreviada del nombre ReferenceExtension de clase y eliminan la parte de la Name= expresión. En el primer ejemplo, la extensión x:Reference de marcado se incrusta en la extensión de Binding marcado. Observe que la Source configuración StringFormat y están separadas por comas. Esta es la ejecución del programa:

! [x:Reference Demo] (consuming-images/referencedemo-small.png "x:Reference Demo".

x:Type (extensión de marcado)

La x:Type extensión de marcado es el equivalente XAML de la palabra clave de typeof C#. Es compatible con la clase , que define una propiedad TypeExtension denominada de tipo que se establece en un nombre de clase o TypeName string estructura. La x:Type extensión de marcado devuelve el objeto de esa clase o System.Type estructura. TypeName es la propiedad de contenido de TypeExtension , por lo que no es necesario cuando aparece con TypeName= x:Type llaves.

Dentro Xamarin.Forms de , hay varias propiedades que tienen argumentos de tipo Type . Algunos ejemplos son TargetType la propiedad de y el atributo Style x:TypeArguments usado para especificar argumentos en clases genéricas. Sin embargo, el analizador XAML realiza la operación automáticamente y la extensión typeof de marcado no se usa en estos x:Type 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 también es útil al crear un menú donde cada elemento de x:Type menú corresponde a un objeto de un tipo determinado. Puede asociar un objeto a cada elemento de menú y, a continuación, crear una instancia del objeto cuando se selecciona Type el elemento de menú.

Así es como funciona el menú de navegación MainPage de en el programa Extensiones de marcado. El archivo MainPage.xaml contiene un elemento TableView con cada correspondiente a una página determinada del TextCell 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 en Extensiones de marcado:

! [Página principal] (consuming-images/mainpage-small.png "Página principal".

Cada CommandParameter propiedad se establece en una extensión de marcado que hace referencia a una de las x:Type otras páginas. La Command propiedad está enlazada a una propiedad denominada NavigateCommand . Esta propiedad se define en el MainPage archivo de código subyacente:

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 NavigateCommand propiedad es un objeto que implementa un comando execute con un argumento de tipo el valor Command de TypeCommandParameter . El método usa Activator.CreateInstance para crear una instancia de la página y, a continuación, navega a ella. El constructor concluye estableciendo el de BindingContext la página en sí mismo, lo que permite que funcione Binding Command . Consulte el artículo Enlace de datos y, especialmente, el artículo Comandos para obtener más detalles sobre este tipo de código.

La página de demostración x:Type usa una técnica similar para crear instancias de los elementos Xamarin.Forms y agregarlos a StackLayout . Inicialmente, el archivo XAML consta de tres elementos con sus propiedades establecidas en y las propiedades Button Command Binding CommandParameter establecidas en tipos de tres Xamarin.Forms vistas:

<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 CreateCommand propiedad :

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 crea una nueva instancia del argumento , establece su propiedad y Button VerticalOptions la agrega a StackLayout . A Button continuación, los tres elementos comparten la página con vistas creadas dinámicamente:

! [x:Type Demo] (consuming-images/typedemo-small.png "x:Type Demo".

x:Array (extensión de marcado)

La x:Array extensión de marcado permite definir una matriz en el marcado. Es compatible con la ArrayExtension clase , que define dos propiedades:

  • Type de tipo Type , que indica el tipo de los elementos de la matriz.
  • Items de tipo IList , que es una colección de los propios elementos. Esta es la propiedad de contenido de ArrayExtension .

La x:Array propia extensión de marcado nunca aparece entre llaves. En su lugar, x:Array las etiquetas start y end delimitan la lista de elementos. Establezca la Type propiedad en una extensión de x:Type marcado.

La página demostración x:Array muestra cómo usar para agregar elementos a mediante el establecimiento x:Array de la propiedad en una ListView ItemsSource 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>        

crea ViewCell un objeto simple para cada entrada de BoxView color:

! [x:Array Demo] (consuming-images/arraydemo-small.png "x:Array Demo".

Hay varias maneras de especificar los elementos Color individuales de esta matriz. Puede usar una extensión x:Static de marcado:

<x:Static Member="Color.Blue" />

O bien, puede usar StaticResource para recuperar un color de un diccionario de recursos:

<StaticResource Key="myColor" />

Hacia el 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 Pasar argumentos de constructor para delimitar los valores.

x:Null (extensión de marcado)

La x:Null extensión de marcado es compatible con la clase NullExtension . No tiene ninguna propiedad y es simplemente el equivalente XAML de la palabra clave de null C#.

La extensión de marcado rara vez es necesaria y rara vez se usa, pero si encuentra una necesidad para ella, estará encantado x:Null de que exista.

La página de demostración x:Null muestra un escenario en el x:Null que podría ser conveniente. Supongamos que define un implícito para que incluye un que establece la propiedad en un nombre de familia dependiente de Style Label la Setter FontFamily 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, desea que todos los valores de propiedad en el implícito excepto para , que desea que Label Style sea el valor FontFamily predeterminado. Podría definir otro para ese propósito, pero un enfoque más sencillo es simplemente establecer la propiedad del particular en , como se muestra Style en el centro de FontFamily Label x:Null Label .

Esta es la ejecución del programa:

! [x:Null Demo] (consuming-images/nulldemo-small.png "x:Null Demo".

Observe que cuatro de los elementos tienen una fuente serif, pero el Label centro tiene la fuente Label sans-serif predeterminada.

Extensión de marcado OnPlatform

La extensión de marcado OnPlatform le permite personalizar la apariencia de la interfaz de usuario para cada plataforma. Proporciona la misma funcionalidad que las OnPlatform clases y , pero con una representación más On concisa.

La OnPlatform extensión de marcado es compatible con la clase , que define las siguientes OnPlatformExtension propiedades:

  • Default de tipo object , que establece en un valor predeterminado que se va a aplicar a las propiedades que representan plataformas.
  • Android de tipo object , que establece en un valor que se va a aplicar en Android.
  • GTK de tipo object , que establece en un valor que se va a aplicar en plataformas GTK.
  • iOS de tipo object , que establece en un valor que se va a aplicar en iOS.
  • macOS de tipo object , que establece en un valor que se va a aplicar en macOS.
  • Tizen de tipo object , que establece en un valor que se va a aplicar en la plataforma Tizen.
  • UWPde tipo object , que establece en un valor que se va a aplicar en la plataforma Windows universal.
  • WPFde tipo object , que establece en un valor que se va a aplicar en la plataforma Windows Presentation Foundation datos.
  • Converter de tipo IValueConverter , que se puede establecer en una IValueConverter implementación.
  • ConverterParameter de tipo object , que se puede establecer en un valor que se va a pasar a la IValueConverter implementación.

Nota

El analizador XAML permite que OnPlatformExtension la clase se abreviado como OnPlatform .

La Default propiedad es la propiedad de contenido de OnPlatformExtension . Por lo tanto, para las expresiones de marcado XAML expresadas con llaves, puede eliminar la parte de la expresión siempre que Default= sea el primer argumento. Si no se establece la propiedad, se establecerá de forma predeterminada en el valor de propiedad, siempre que la extensión de Default marcado tenga como destino BindableProperty.DefaultValue BindableProperty .

Importante

El analizador XAML espera que se proporcionan valores del tipo correcto a las propiedades que consumen la OnPlatform extensión de marcado. Si es necesaria la conversión de tipos, la extensión OnPlatform de marcado intentará realizarla con los convertidores predeterminados proporcionados por Xamarin.Forms . Sin embargo, hay algunas conversiones de tipos que los convertidores predeterminados no pueden realizar y, en estos casos, la propiedad Converter debe establecerse en una IValueConverter implementación.

La página OnPlatform Demo (Demostración de OnPlatform) muestra cómo usar la extensión OnPlatform de marcado:

<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 OnPlatform expresiones usan la versión abreviada del nombre OnPlatformExtension de clase. Las tres extensiones de marcado establecen las propiedades , y de en valores diferentes en OnPlatform Color WidthRequest HeightRequest BoxView 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 Default= la parte de la expresión. Observe que las propiedades de extensión de marcado que se establecen están separadas por comas.

Esta es la ejecución del programa:

! [Demostración de OnPlatform] (consuming-images/onplatformdemo-small.png "OnPlatform Demo".

Extensión de marcado OnIdiom

La extensión de marcado permite personalizar la apariencia de la interfaz de usuario en función de la expresión del dispositivo en el OnIdiom que se ejecuta la aplicación. Es compatible con la clase OnIdiomExtension , que define las siguientes propiedades:

  • Default de tipo , que establece en un valor predeterminado que object se va a aplicar a las propiedades que representan expresiones de dispositivo.
  • Phone de tipo object , que establece en un valor que se va a aplicar en teléfonos.
  • Tablet de tipo object , que se establece en un valor que se va a aplicar en tabletas.
  • Desktop de tipo object , que establece en un valor que se va a aplicar en las plataformas de escritorio.
  • TV de tipo object , que establece en un valor que se va a aplicar en plataformas de televisión.
  • Watch de tipo object , que establece en un valor que se va a aplicar en las plataformas watch.
  • Converter de tipo IValueConverter , que se puede establecer en una IValueConverter implementación.
  • ConverterParameter de tipo object , que se puede establecer en un valor que se va a pasar a la IValueConverter implementación.

Nota

El analizador XAML permite que OnIdiomExtension la clase se abreviado como OnIdiom .

La Default propiedad es la propiedad de contenido de OnIdiomExtension . Por lo tanto, para las expresiones de marcado XAML expresadas con llaves, puede eliminar la parte de la expresión siempre que Default= sea el primer argumento.

Importante

El analizador XAML espera que se proporcionan valores del tipo correcto a las propiedades que consumen la OnIdiom extensión de marcado. Si es necesaria la conversión de tipos, la extensión OnIdiom de marcado intentará realizarla con los convertidores predeterminados proporcionados por Xamarin.Forms . Sin embargo, hay algunas conversiones de tipos que los convertidores predeterminados no pueden realizar y, en estos casos, la propiedad Converter debe establecerse en una IValueConverter implementación.

En la página OnIdiom Demo (Demostración de OnIdiom) se muestra cómo usar la extensión OnIdiom de marcado:

<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 OnIdiom expresiones usan la versión abreviada del nombre OnIdiomExtension de clase. Las tres extensiones de marcado establecen las propiedades , y de en valores diferentes en las expresiones de teléfono, tableta OnIdiom Color y WidthRequest HeightRequest BoxView 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 Default= parte de la expresión. Observe que las propiedades de extensión de marcado que se establecen están separadas por comas.

Esta es la ejecución del programa:

! [Demostración de OnIdiom] (consuming-images/onidiomdemo-small.png "OnIdiom Demo".

Extensión de marcado DataTemplate

La DataTemplate extensión de marcado permite convertir un tipo en DataTemplate . Es compatible con la clase , que define una propiedad, de tipo , que se establece en el nombre del tipo que se va DataTemplateExtension TypeName a convertir en string DataTemplate . La TypeName propiedad 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.

Un uso típico 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 a , que se establece como el valor de la propiedad ContentPage DataTemplate ShellContent.ContentTemplate . Esto garantiza que solo se crea cuando se produce la navegación a MonkeysPage la página, en lugar de 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 FontImage extensión de marcado permite mostrar un icono de fuente en cualquier vista que pueda mostrar un ImageSource . Proporciona la misma funcionalidad que la FontImageSource clase , pero con una representación más concisa.

La clase FontImageExtension admite la extensión de marcado FontImage, que define las siguientes propiedades:

  • FontFamily de tipo string , la familia de fuentes a la que pertenece el icono de fuente.
  • Glyph de tipo string , el valor de carácter Unicode del icono de fuente.
  • Color de tipo Color , color que se va a usar al mostrar el icono de fuente.
  • Size de tipo double , 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 Glyph propiedad es la propiedad de contenido de FontImageExtension . Por lo tanto, para las expresiones de marcado XAML expresadas con llaves, puede eliminar la parte de la expresión siempre que Glyph= sea el primer argumento.

En la página Demostración de FontImage se muestra cómo usar la extensión FontImage de marcado:

<Image BackgroundColor="#D1D1D1"
       Source="{FontImage &#xf30c;, FontFamily={OnPlatform iOS=Ionicons, Android=ionicons.ttf#}, Size=44}" />

En este ejemplo, la versión abreviada del nombre de clase se usa para mostrar un icono XBox, de la familia de fuentes FontImageExtension Ionicons, en Image un . La expresión también usa la extensión OnPlatform de marcado para especificar distintos valores de propiedad en FontFamily iOS y Android. Además, se elimina la parte de la expresión y las propiedades de extensión de marcado que se establecen Glyph= están separadas por comas. Tenga en cuenta que, aunque el carácter Unicode del icono es , tiene que \uf30c escaparse en XAML y, por tanto, se convierte en &#xf30c; .

Esta es la ejecución del programa:

! [Captura de pantalla de la extensión de marcado FontImage] (consuming-images/fontimagedemo.png "FontImage Demo".

Para obtener información sobre cómo mostrar iconos de fuente especificando los datos del icono de fuente en un FontImageSource objeto , vea Mostrar iconos de fuente.

AppThemeBinding (extensión de marcado)

La extensión de marcado permite especificar un recurso que se va a consumir, como una imagen o un color, en AppThemeBinding función del tema actual del sistema.

Importante

La AppThemeBinding extensión de marcado tiene requisitos mínimos del sistema operativo. Para obtener más información, vea Responder a los cambios de tema del sistema en las Xamarin.Forms aplicaciones.

La clase AppThemeBindingExtension admite la extensión de marcado AppThemeBinding, que define las siguientes propiedades:

  • Default, de tipo object , que establece en el recurso que se va a usar de forma predeterminada.
  • Light, de tipo , que establece en el recurso que se va a object usar cuando el dispositivo usa su tema claro.
  • Dark, de tipo , que establece en el recurso que se va a object usar cuando el dispositivo usa su tema oscuro.
  • Value, de tipo object , que devuelve el recurso que está utilizando actualmente la extensión de marcado.

Nota

El analizador de XAML permite abreviar la clase AppThemeBindingExtension como AppBindingTheme.

La Default propiedad es la propiedad content de AppThemeBindingExtension . Por lo tanto, para las expresiones de marcado XAML expresadas con llaves, puede eliminar la parte de la expresión siempre que Default= sea el primer argumento.

La página Demostración de AppThemeBinding muestra cómo usar la extensión AppThemeBinding de marcado:

<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 primero se establece en verde cuando el dispositivo usa su tema claro y se establece en rojo cuando el dispositivo usa su Label tema oscuro. El segundo Label tiene su propiedad establecida a través de TextColor Style . Esto establece el color de texto de en negro de forma predeterminada, en azul cuando el dispositivo usa su tema claro y en teal cuando el dispositivo usa Style Label su tema oscuro.

Esta es la ejecución del programa:

Demostración de AppThemeBinding.

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 su propio.