Consumir extensões de marcação XAML

Browse sample. Navegue pelo exemplo

As extensões de marcação XAML da Interface do Usuário de Aplicativo Multiplataforma do .NET (.NET MAUI) ajudam a aprimorar o poder e a flexibilidade do XAML, permitindo que os atributos do elemento sejam definidos de várias fontes.

Por exemplo, você normalmente define a Color propriedade de BoxView assim:

<BoxView Color="Blue" />

No entanto, talvez você prefira definir o Color atributo de um valor armazenado em um dicionário de recursos ou do valor de uma propriedade estática de uma classe que você criou, ou de uma propriedade do tipo Color de outro elemento na página ou construída a partir de valores separados de matiz, saturação e luminosidade. Todas essas opções são possíveis usando extensões de marcação XAML.

Uma extensão de marcação é uma maneira diferente de expressar um atributo de um elemento. As extensões de marcação XAML do .NET MAUI geralmente são identificáveis por um valor de atributo que é incluído em chaves curvas:

<BoxView Color="{StaticResource themeColor}" />

Qualquer valor de atributo em chaves é sempre uma extensão de marcação XAML. No entanto, as extensões de marcação XAML também podem ser referenciadas sem o uso de chaves.

Observação

Várias extensões de marcação XAML fazem parte da especificação XAML 2009. Eles aparecem em arquivos XAML com o prefixo de x namespace habitual e são comumente referidos com esse prefixo.

Além das extensões de marcação discutidas neste artigo, as seguintes extensões de marcação estão incluídas no .NET MAUI e discutidas em outros artigos:

x:Extensão de marcação estática

A x:Static extensão de marcação é suportada StaticExtension pela classe. A classe tem uma única propriedade chamada Member do tipo string que você define como o nome de uma constante pública, propriedade estática, campo estático ou membro de enumeração.

Uma maneira de usar x:Static é primeiro definir uma classe com algumas constantes ou variáveis estáticas, como esta AppConstants classe:

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

O XAML a seguir demonstra a abordagem mais detalhada para instanciar a StaticExtension classe entre Label.FontSize marcas de elemento de propriedade:

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

O analisador XAML também permite que a StaticExtension classe seja abreviada como x:Static:

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

Essa sintaxe pode ser ainda mais simplificada colocando a classe e a StaticExtension configuração de membro em chaves. A expressão resultante é definida diretamente para o atributo FontSize :

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

Neste exemplo, nãoaspas dentro das chaves encaracoladas. A Member propriedade de StaticExtension não é mais um atributo XML. Em vez disso, faz parte da expressão para a extensão de marcação.

Assim como você pode abreviar x:StaticExtension para x:Static quando você usá-lo como um elemento de objeto, você também pode abreviar na expressão dentro de chaves:

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

A StaticExtension classe tem um ContentProperty atributo que faz referência à propriedade , que marca essa propriedade como a propriedade Memberde conteúdo padrão da classe. Para extensões de marcação XAML expressas com chaves, você pode eliminar a Member= parte da expressão:

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

Esta é a forma mais comum da extensão de x:Static marcação.

A marca raiz do exemplo XAML também contém uma declaração de namespace XML para o namespace .NET System . Isso permite que o tamanho da fonte seja definido para o Label campo Math.PIestático . Isso resulta em um texto bastante pequeno, portanto, a Scale propriedade é definida como Math.E:

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

A captura de tela a seguir mostra a saída XAML:

x:Static demo.

x:Extensão de marcação de referência

A x:Reference extensão de marcação é suportada ReferenceExtension pela classe. A classe tem uma única propriedade chamada Name do tipo string que você definiu como o nome de um elemento na página que recebeu um nome com x:Name. Essa Name propriedade é a propriedade content do ReferenceExtension, portanto Name= , não é necessária quando x:Reference aparece em chaves curvas. A x:Reference extensão de marcação é usada exclusivamente com associações de dados. Para obter mais informações sobre associações de dados, consulte Vinculação de dados.

O exemplo XAML a seguir mostra dois usos de com associações de dados, o primeiro onde ele é usado para definir a propriedade do objeto e o segundo onde é usado para definir a SourceBindingContext propriedade para duas associações de x:ReferenceBinding dados:

<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}&#x00B0; rotation'}"
               Rotation="{Binding Value}"
               FontSize="24"
               HorizontalOptions="Center"
               VerticalOptions="Center" />        
    </StackLayout>
</ContentPage>

Neste exemplo, ambas as x:Reference expressões usam a versão abreviada do nome da classe e eliminam a ReferenceExtensionName= parte da expressão. No primeiro exemplo, a extensão de x:Reference marcação é incorporada na extensão de Binding marcação e as propriedades e StringFormat são separadas por vírgulasSource.

A captura de tela a seguir mostra a saída XAML:

x:Reference demo.

x:Extensão de marcação de tipo

A x:Type extensão de marcação é o equivalente XAML da palavra-chave C# typeof . Ele é suportado TypeExtension pela classe, que define uma propriedade chamada TypeName de tipo string que deve ser definida como um nome de classe ou estrutura. A x:Type extensão de marcação retorna o Type objeto dessa classe ou estrutura. TypeName é a propriedade de conteúdo do TypeExtension, por isso TypeName= não é necessário quando x:Type aparece com chaves encaracoladas.

A x:Type extensão de marcação é comumente usada com a extensão de x:Array marcação. Para obter mais informações, consulte x:Array markup extension.

O exemplo XAML a seguir demonstra o uso da extensão de x:Type marcação para instanciar objetos .NET MAUI e adicioná-los a um StackLayoutarquivo . O XAML consiste em três elementos com suas Command propriedades definidas como um Binding e as CommandParameter propriedades definidas como tipos de três Button modos de exibição MAUI do .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>

O arquivo code-behind define e inicializa a CreateCommand propriedade:

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;
    }
}

Quando um Button é pressionado, uma nova instância do CommandParameter argumento é criada e adicionada StackLayoutao . Os três Button objetos compartilham a página com modos de exibição criados dinamicamente:

x:Type demo.

x:Extensão de marcação de matriz

A x:Array extensão de marcação permite que você defina uma matriz na marcação. Ele é suportado ArrayExtension pela classe, que define duas propriedades:

  • Type do tipo , que indica o tipo Typedos elementos na matriz. Essa propriedade deve ser definida como uma extensão de x:Type marcação.
  • Items do tipo IList, que é uma coleção dos próprios itens. Esta é a propriedade de conteúdo do ArrayExtension.

A x:Array extensão de marcação em si nunca aparece em chaves encaracoladas. Em vez disso, x:Array as tags start e end delimitam a lista de itens.

O exemplo XAML a seguir mostra como usar x:Array para adicionar itens a um ListView definindo a ItemsSource propriedade como uma 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>     

Neste exemplo, o ViewCell cria um simples BoxView para cada entrada de cor:

x:Array demo.

Observação

Ao definir matrizes de tipos comuns, como cadeias de caracteres ou números, use as marcas primitivas da linguagem XAML listadas em Argumentos Pass.

x:Extensão de marcação nula

A x:Null extensão de marcação é suportada NullExtension pela classe. Ele não tem propriedades e é simplesmente o equivalente XAML da palavra-chave C# null .

O exemplo XAML a seguir mostra como usar a extensão de x:Null marcação:

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

Neste exemplo, um implícito Style é definido para que inclui um Setter que define a FontFamily propriedade para Label uma fonte específica. No entanto, o terceiro Label evita usar a fonte definida no estilo implícito, definindo-a FontFamily como x:Null:

x:Null demo.

Extensão de marcação DataTemplate

A DataTemplate extensão de marcação permite converter um tipo em um DataTemplatearquivo . Ele é suportado DataTemplateExtension pela classe, que define uma TypeName propriedade, do tipo , que é definida como o nome do tipo stringa ser convertido em um DataTemplatearquivo . A TypeName propriedade é a propriedade content de DataTemplateExtension. Portanto, para expressões de marcação XAML expressas com chaves curvas, você pode eliminar a TypeName= parte da expressão.

Observação

O analisador XAML permite que a DataTemplateExtension classe seja abreviada como DataTemplate.

Um uso típico dessa extensão de marcação está em um aplicativo Shell, conforme mostrado no exemplo a seguir:

<ShellContent Title="Monkeys"
              Icon="monkey.png"
              ContentTemplate="{DataTemplate views:MonkeysPage}" />

Neste exemplo, é convertido de um para um ContentPageDataTemplate, MonkeysPage que é definido como o valor da ShellContent.ContentTemplate propriedade. Isso garante que MonkeysPage seja criado somente quando a navegação para a página ocorrer, em vez de na inicialização do aplicativo.

Para obter mais informações sobre aplicativos do Shell, consulte Shell.