Extensões de marcação XAML

Concluído

Grande parte da sua definição XAML será liquidada em tempo de compilação. Muitas vezes, você sabe onde os elementos devem ser posicionados, quais cores e fontes serão usadas e quais valores literais devem ser atribuídos às propriedades.

No entanto, às vezes você precisa definir um valor de propriedade para um valor que não pode ser determinado em tempo de compilação. Esses valores só são conhecidos quando o programa está em execução. Nessas situações, você pode criar um objeto que forneça um valor para XAML em tempo de execução. O XAML oferece suporte a Extensões de Marcação para essa finalidade.

Nesta unidade, você aprenderá a criar e usar extensões de marcação.

O que é uma extensão de marcação?

Uma extensão de marcação é uma classe que você usa em XAML para acessar valores de tempo de execução. Suponha que você tenha muitos rótulos definidos em sua interface do usuário XAML e queira definir a FontSize propriedade com o mesmo valor em todo o aplicativo para garantir que todo o estilo de rótulo seja consistente. Você pode definir a FontSize propriedade usando XAML como mostrado no exemplo a seguir:

<Label Text="Hello, World!"
            Grid.Row="0"
            SemanticProperties.HeadingLevel="Level1"
            FontSize="28"
            HorizontalOptions="CenterAndExpand"/>

Você pode repetir essa mesma configuração para todos os rótulos, mas e se quiser alterar esse valor mais tarde? Você precisa encontrar todas as instâncias dessa propriedade e fazer a alteração. Além disso, suponha que você não sabe qual valor usar; Ele pode ser calculado em tempo de execução com base em fatores como orientação do dispositivo, resolução da tela ou outras considerações. Nesses casos, você precisa de algo mais sofisticado do que um literal codificado. É aqui que uma extensão de marcação é útil. As extensões de marcação oferecem flexibilidade na forma como você obtém um valor que é usado em XAML.

Criando uma extensão de marcação

Uma extensão de marcação é uma classe que implementa a interface Microsoft.Maui.Controls.Xaml.IMarkupExtension . Esta interface define um método, chamado ProvideValue, com a seguinte assinatura:

public object ProvideValue(IServiceProvider serviceProvider)
{
    ...
}

A finalidade desse método é fornecer um valor para sua marcação XAML. Observe que o tipo de retorno é object, portanto, o valor pode ser de qualquer tipo, desde que seja apropriado para o local em que está sendo usado. Por exemplo, em uma extensão de marcação que calcula e retorna um tamanho de fonte, o tipo de retorno deve ser um doublearquivo .

O serviceProvider parâmetro contém informações contextuais sobre onde a extensão de marcação está sendo usada em seu código XAML, entre outras informações, identifica o controle ao qual a extensão está sendo aplicada.

Você pode manter a extensão de marcação para a FontSize propriedade simples. No exemplo a seguir, a MainPage classe expõe um double campo chamado MyFontSize. A GlobalFontSizeExtension classe implementa a IMarkupExtension interface e o ProvideValue método retorna o valor da MyFontSize variável:

namespace MyMauiApp;

public partial class MainPage : ContentPage
{
    public const double MyFontSize = 28;

    public MainPage()
    {
        InitializeComponent();
        ...
    }
    ...
}

public class GlobalFontSizeExtension : IMarkupExtension
{
    public object ProvideValue(IServiceProvider serviceProvider)
    {
        return MainPage.MyFontSize;
    }
}

Nota

O MyFontSize campo deve ser um static membro da MainPage classe para permitir que ele seja referenciado ProvideValue no método desta forma. As boas práticas implicam que, neste caso, a variável também deve ser uma constante. Um const valor é static.

O ProvideValue método também pode fazer ajustes no valor retornado, dependendo da orientação e do fator de forma do dispositivo.

Aplicando a extensão de marcação a um controle em XAML

Para usar a extensão de marcação em seu código XAML, adicione o namespace que contém a GlobalFontSizeExtension classe à lista de namespaces na ContentPage tag . No exemplo a seguir, esse namespace recebe o alias mycode:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:mycode="clr-namespace:MyMauiApp"
             x:Class="MyMauiApp.MainPage">

Você pode usar a extensão de marcação para definir a FontSize propriedade assim. Observe que a convenção é que uma extensão de marcação tem o sufixo Extension em seu nome. O XAML reconhece esse sufixo e você não precisa incluí-lo quando chama a extensão do seu código XAML. No exemplo a seguir, a GlobalFontSizeExtension classe é referenciada simplesmente como GlobalFontSize:

<Label Text="Hello, World!"
            Grid.Row="0"
            SemanticProperties.HeadingLevel="Level1"
            FontSize="{mycode:GlobalFontSize}"
            HorizontalOptions="CenterAndExpand"/>

Você pode aplicar a mesma extensão de marcação em todo o código XAML para qualquer controle que precise especificar o tamanho da fonte. Mais tarde, se você decidir alterar o tamanho da fonte, você só precisa modificar a MyFontSize definição da variável na MainPage classe.

A classe StaticExtension

Por mais útil que seja a extensão de GlobalFontSize marcação, é improvável que você crie tal extensão. A razão para isso é simples: o .NET MAUI já fornece uma extensão mais generalizada que permite fazer referência a qualquer valor estático em seu código. Esta extensão tem o nome StaticExtensionde , ou Static para abreviar. O código a seguir mostra o esboço básico dessa classe de extensão:

[ContentProperty ("Member")]
public class StaticExtension : IMarkupExtension
{
    public string Member {get; set;}
    public object ProvideValue (IServiceProvider serviceProvider)
    {
        ...
    }
}

Nota

O objetivo das extensões de marcação personalizadas é permitir que você lide com situações mais complexas em vez de um simples caso estático. Por exemplo, talvez seja necessário alterar dinamicamente o tamanho da fonte com base no fator forma do dispositivo.

Para usar essa classe em seu código XAML, forneça o nome da variável estática que você deseja referenciar na Member propriedade e o método retorna o ProvideValue valor nessa variável. O exemplo a seguir ilustra como usá-lo:

<Label Text="Hello, World!"
            Grid.Row="0"
            SemanticProperties.HeadingLevel="Level1"
            FontSize="{x:Static Member=mycode:MainPage.MyFontSize}"
            HorizontalOptions="CenterAndExpand"/>

O .NET MAUI fornece um conjunto de outras classes de extensão de marcação, que você pode usar para cenários como vinculação de dados, referência a recursos e estilos dinâmicos e manipulação de matrizes de dados.