Consumo de extensiones de marcado XAML
Las extensiones de marcado XAML de la interfaz de usuario de aplicaciones multiplataforma (.NET MAUI) de .NET ayudan a mejorar la eficacia y flexibilidad de XAML al permitir que los atributos de elemento se establezcan desde una variedad de orígenes.
Por ejemplo, normalmente se establece la Color propiedad de BoxView como esta:
<BoxView Color="Blue" />
Sin embargo, es posible que prefiera establecer el Color atributo a partir de un valor almacenado en un diccionario de recursos, o desde el valor de una propiedad estática de una clase que ha creado, o desde una propiedad de tipo Color de otro elemento de la página, o construido a partir de valores de tono, saturación y luminosidad independientes. Todas estas opciones son posibles mediante extensiones de marcado XAML.
Una extensión de marcado es una manera diferente de expresar un atributo de un elemento. Las extensiones de marcado XAML de .NET MAUI suelen ser identificables por un valor de atributo que se incluye entre llaves:
<BoxView Color="{StaticResource themeColor}" />
Cualquier valor de atributo en llaves siempre es una extensión de marcado XAML. Sin embargo, también se puede hacer referencia a las extensiones de marcado XAML sin usar llaves.
Nota:
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 conocen normalmente con este prefijo.
Además de las extensiones de marcado que se describen en este artículo, las siguientes extensiones de marcado se incluyen en .NET MAUI y se describen en otros artículos:
StaticResource: hace referencia a objetos de un diccionario de recursos. Para obtener más información, vea Diccionarios de recursos**.DynamicResource: responde a los cambios en los objetos de un diccionario de recursos. Para obtener más información, vea Estilos dinámicos**.Binding: establece un vínculo entre las propiedades de dos objetos. Para obtener más información, vea Enlace de datos**.TemplateBinding: realiza el enlace de datos desde una plantilla de control. Para obtener más información, vea Plantillas de control.RelativeSource: establece el origen de enlace en relación con la posición del destino de enlace. Para obtener más información, consulte Enlaces relativos.
x:Static (extensión de marcado)
La x:Static extensión de marcado es compatible con la StaticExtension clase . 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 de usar x:Static es definir primero una clase con algunas constantes o variables estáticas, como esta AppConstants clase:
static class AppConstants
{
public static double NormalFontSize = 18;
}
En el código XAML siguiente se muestra el enfoque más detallado para crear instancias de la StaticExtension clase entre Label.FontSize etiquetas de elemento de propiedad:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
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 la StaticExtension clase se abrevia como x:Static:
<Label Text="Label No. 2">
<Label.FontSize>
<x:Static Member="local:AppConstants.NormalFontSize" />
</Label.FontSize>
</Label>
Esta sintaxis se puede simplificar aún más colocando la StaticExtension clase y el valor de miembro en llaves. La expresión resultante se establece directamente en el FontSize atributo :
<Label Text="Label No. 3"
FontSize="{x:StaticExtension Member=local:AppConstants.NormalFontSize}" />
En este ejemplo, no hay comillas entre llaves. La Member propiedad de StaticExtension ya no es un atributo XML. En lugar de formar parte de la expresión para la extensión de marcado.
Al igual que se puede abreviar x:StaticExtension a x:Static cuando se usa como elemento de objeto, también se puede abreviar en la expresión dentro de llaves:
<Label Text="Label No. 4"
FontSize="{x:Static Member=local:AppConstants.NormalFontSize}" />
La StaticExtension clase tiene un ContentProperty atributo 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 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 x:Static extensión de marcado.
La etiqueta raíz del ejemplo XAML también contiene una declaración de espacio de nombres XML para el espacio de nombres .NET System . Esto permite establecer el Label tamaño de fuente en el campo Math.PIestático . Esto da como resultado texto bastante pequeño, por lo que la Scale propiedad se establece Math.Een :
<Label Text="π × E sized text"
FontSize="{x:Static sys:Math.PI}"
Scale="{x:Static sys:Math.E}"
HorizontalOptions="Center" />
En la captura de pantalla siguiente se muestra la salida XAML:
Extensión de marcado x:Reference
La x:Reference extensión de marcado es compatible con la ReferenceExtension clase . 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 Name propiedad es la propiedad content de ReferenceExtension, por lo que Name= no es necesaria cuando x:Reference aparece entre llaves. La x:Reference extensión de marcado se usa exclusivamente con enlaces de datos. Para obtener más información sobre los enlaces de datos, consulte Enlace de datos.
En el ejemplo XAML siguiente se muestran dos usos de con enlaces de x:Reference datos, el primero donde se usa para establecer la Source propiedad del Binding objeto y el segundo donde se usa para establecer la BindingContext propiedad para dos enlaces de datos:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
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="Center"
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="Center" />
</StackLayout>
</ContentPage>
En este ejemplo, ambas x:Reference expresiones usan la versión abreviada del nombre de clase ReferenceExtension y eliminan la Name= parte de la expresión. En el primer ejemplo, la x:Reference extensión de marcado se inserta en la Binding extensión de marcado y las Source propiedades y StringFormat están separadas por comas.
En la captura de pantalla siguiente se muestra la salida XAML:
x:Type (extensión de marcado)
La x:Type extensión de marcado es el equivalente XAML de la palabra clave de C# typeof . Es compatible con la TypeExtension clase , que define una propiedad denominada TypeName de tipo string que se debe establecer en un nombre de clase o estructura. La x:Type extensión de marcado devuelve el Type objeto de esa clase o estructura. TypeName es la propiedad content de TypeExtension, por lo que TypeName= no es necesario cuando x:Type aparece con llaves.
La x:Type extensión de marcado se usa normalmente con la extensión de x:Array marcado. Para obtener más información, vea extensión de marcado x:Array.
En el ejemplo XAML siguiente se muestra cómo usar la x:Type extensión de marcado para crear instancias de objetos MAUI de .NET y agregarlos a .StackLayout El XAML consta de tres Button elementos con sus Command propiedades establecidas en y Binding las CommandParameter propiedades establecidas en tipos de tres vistas MAUI de .NET:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
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="Center"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Slider}" />
<Button Text="Create a Stepper"
HorizontalOptions="Center"
VerticalOptions="Center"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Stepper}" />
<Button Text="Create a Switch"
HorizontalOptions="Center"
VerticalOptions="Center"
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 ICommand CreateCommand { get; private set; }
public TypeDemoPage()
{
InitializeComponent();
CreateCommand = new Command<Type>((Type viewType) =>
{
View view = (View)Activator.CreateInstance(viewType);
view.VerticalOptions = LayoutOptions.Center;
stackLayout.Add(view);
});
BindingContext = this;
}
}
Button Cuando se presiona una nueva instancia del CommandParameter argumento , se crea y se agrega a StackLayout. A continuación, los tres Button objetos comparten la página con vistas creadas dinámicamente:
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:
Typede tipoType, que indica el tipo de los elementos de la matriz. Esta propiedad debe establecerse en unax:Typeextensión de marcado.Itemsde tipoIList, que es una colección de los propios elementos. Esta es la propiedad content deArrayExtension.
La x:Array propia extensión de marcado nunca aparece entre llaves. En su lugar, las x:Array etiquetas start y end delimitan la lista de elementos.
En el ejemplo XAML siguiente se muestra cómo usar x:Array para agregar elementos a mediante ListView el establecimiento de la ItemsSource propiedad en una matriz:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
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>
En este ejemplo, crea ViewCell un elemento sencillo BoxView para cada entrada de color:
Nota:
Al definir matrices de tipos comunes como cadenas o números, use las etiquetas primitivas del lenguaje XAML enumeradas en Argumentos de paso.
x:Null (extensión de marcado)
La x:Null extensión de marcado es compatible con la NullExtension clase . No tiene propiedades y es simplemente el equivalente XAML de la palabra clave de C# null .
En el ejemplo XAML siguiente se muestra cómo usar la x:Null extensión de marcado:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.NullDemoPage"
Title="x:Null Demo">
<ContentPage.Resources>
<Style TargetType="Label">
<Setter Property="FontSize" Value="48" />
<Setter Property="FontFamily" Value="OpenSansRegular" />
</Style>
</ContentPage.Resources>
<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>
En este ejemplo, se define un implícito Style para Label que incluya un Setter objeto que establece la FontFamily propiedad en una fuente específica. Sin embargo, el tercero Label evita usar la fuente definida en el estilo implícito estableciendo su en FontFamilyx:Null:
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 On , pero con una representación más concisa.
La clase OnPlatformExtension admite la extensión de marcado OnPlatform, que define las siguientes propiedades:
Defaultde tipoobject, que se establece en un valor predeterminado que se aplicará a las propiedades que representan las plataformas.Androidde tipoobject, que se establece en un valor que se va a aplicar en Android.iOSde tipoobject, que se establece en un valor que se aplicará en iOS.MacCatalystde tipoobject, que establece en un valor que se aplicará en Mac Catalyst.Tizende tipoobject, que se establece en un valor que se aplicará en la plataforma Tizen.WinUIde tipoobject, que se establece en un valor que se va a aplicar en WinUI.Converterde tipoIValueConverter, que se puede establecer en unaIValueConverterimplementación.ConverterParameterde tipoobject, que se puede establecer en un valor para pasar a laIValueConverterimplementación.
Nota:
El analizador de XAML permite abreviar la clase OnPlatformExtension como OnPlatform.
La Default propiedad es la propiedad content de OnPlatformExtension. Por lo tanto, para las expresiones de marcado XAML expresadas con llaves, puedes eliminar la Default= parte de la expresión siempre que sea el primer argumento. Si la Default propiedad no está establecida, se establecerá de forma predeterminada en el valor de la BindableProperty.DefaultValue propiedad, siempre que la extensión de marcado tenga como destino un BindableProperty.
Importante
El analizador XAML espera que se proporcionen valores del tipo correcto a las propiedades que consumen la OnPlatform extensión de marcado. Si es necesaria la conversión de tipos, la OnPlatform extensión de marcado intentará realizarla mediante los convertidores predeterminados proporcionados por Xamarin.Forms. Sin embargo, hay algunas conversiones de tipos que no se pueden realizar en los convertidores predeterminados y, en estos casos, la Converter propiedad debe establecerse en una IValueConverter implementación.
En la página Demostración de OnPlatform se muestra cómo usar la OnPlatform extensión de marcado:
<BoxView Color="{OnPlatform Yellow, iOS=Red, Android=Green}"
WidthRequest="{OnPlatform 250, iOS=200, Android=300}"
HeightRequest="{OnPlatform 250, iOS=200, Android=300}"
HorizontalOptions="Center" />
En este ejemplo, las tres OnPlatform expresiones usan la versión abreviada del OnPlatformExtension nombre de clase. Las tres OnPlatform extensiones de marcado establecen las Colorpropiedades , WidthRequesty HeightRequest de en BoxView valores diferentes en iOS y Android. Las extensiones de marcado también proporcionan valores predeterminados para estas propiedades en las plataformas que no se especifican, a la vez que eliminan la Default= parte de la expresión.
Extensión de marcado OnIdiom
La OnIdiom extensión de marcado permite personalizar la apariencia de la interfaz de usuario en función del lenguaje del dispositivo en el que se ejecuta la aplicación. Es compatible con la OnIdiomExtension clase , que define las siguientes propiedades:
Defaultde tipoobject, que se establece en un valor predeterminado que se va a aplicar a las propiedades que representan expresiones del dispositivo.Phonede tipoobject, que se establece en un valor que se va a aplicar en los teléfonos.Tabletde tipoobject, que se establece en un valor que se va a aplicar en tabletas.Desktopde tipoobject, que se establece en un valor que se aplicará en plataformas de escritorio.TVde tipoobject, que se establece en un valor que se aplicará en las plataformas de TV.Watchde tipoobject, que se establece en un valor que se aplicará en las plataformas Watch.Converterde tipoIValueConverter, que se puede establecer en unaIValueConverterimplementación.ConverterParameterde tipoobject, que se puede establecer en un valor para pasar a laIValueConverterimplementación.
Nota:
El analizador de XAML permite abreviar la clase OnIdiomExtension como OnIdiom.
La Default propiedad es la propiedad content de OnIdiomExtension. Por lo tanto, para las expresiones de marcado XAML expresadas con llaves, puedes eliminar la Default= parte de la expresión siempre que sea el primer argumento.
Importante
El analizador XAML espera que se proporcionen valores del tipo correcto a las propiedades que consumen la OnIdiom extensión de marcado. Si es necesaria la conversión de tipos, la OnIdiom extensión de marcado intentará realizarla mediante los convertidores predeterminados proporcionados por .NET MAUI. Sin embargo, hay algunas conversiones de tipos que no se pueden realizar en los convertidores predeterminados y, en estos casos, la Converter propiedad debe establecerse en una IValueConverter implementación.
En el ejemplo XAML siguiente se muestra cómo usar la OnIdiom extensión 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 OnIdiomExtension nombre de clase. Las tres OnIdiom extensiones de marcado establecen las Colorpropiedades , WidthRequesty HeightRequest de en BoxView 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 eliminan la Default= parte de la expresión.
Extensión de marcado DataTemplate
La DataTemplate extensión de marcado permite convertir un tipo en .DataTemplate Es compatible con la DataTemplateExtension clase , que define una TypeName propiedad , de tipo string, que se establece en el nombre del tipo que se va a convertir en .DataTemplate La TypeName propiedad es la propiedad content 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 ContentPage , DataTemplateque se establece como el valor de la ShellContent.ContentTemplate propiedad . Esto garantiza que MonkeysPage solo se crea cuando se produce la navegación a la página, en lugar de al iniciar la aplicación.
Para obtener más información sobre las aplicaciones de Shell, consulte 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:
FontFamilyde tipostring, la familia de fuentes a la que pertenece el icono de fuente.Glyphde tipostring, el valor de carácter unicode del icono de fuente.Colorde tipoColor, el color que se usará al mostrar el icono de fuente.Sizede 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 Glyph propiedad es la propiedad content de FontImageExtension. Por lo tanto, para las expresiones de marcado XAML expresadas con llaves, puedes eliminar la Glyph= parte de la expresión siempre que sea el primer argumento.
En el ejemplo XAML siguiente se muestra cómo usar la FontImage extensión de marcado:
<Image BackgroundColor="#D1D1D1"
Source="{FontImage , FontFamily=Ionicons, Size=44}" />
En este ejemplo, la versión abreviada del nombre de FontImageExtension clase se usa para mostrar un icono XBox, de la familia de fuentes Ionicons, en un Image:
Aunque el carácter unicode del icono es \uf30c, debe escaparse en XAML y, por tanto, se convierte en .
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 AppThemeBinding extensión de marcado permite especificar un recurso que se va a consumir, como una imagen o un color, en función del tema del sistema actual.
La clase AppThemeBindingExtension admite la extensión de marcado AppThemeBinding, 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 usará cuando el dispositivo usa su tema oscuro.Value, de tipoobject, que devuelve el recurso que usa 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, puedes eliminar la Default= parte de la expresión siempre que sea el primer argumento.
En el ejemplo XAML siguiente se muestra cómo usar la AppThemeBinding extensión de marcado:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
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 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 TextColor propiedad establecida a través de .Style Esto Style establece el color de texto de en Label negro de forma predeterminada, en azul cuando el dispositivo usa su tema claro y en teal cuando el dispositivo usa su tema oscuro:
Examinar el ejemplo