Extensões de marcação XAML
Grande parte de sua definição de XAML será definida no tempo de compilação. Geralmente, você sabe onde os elementos devem ficar 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 da propriedade para um valor que não pode ser determinado em tempo de compilação. Esses valores são conhecidos apenas quando o programa está em execução. Nessas situações, você pode criar um objeto que fornece um valor para XAML em runtime. O XAML dá 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 runtime. Suponha que você tenha vários rótulos definidos em sua interface do usuário XAML e queira definir a propriedade FontSize
com o mesmo valor em todo o aplicativo para garantir que o estilo de todos os rótulos seja consistente. Você pode definir a propriedade FontSize
usando XAML, conforme 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 cada rótulo, mas e se quiser alterar esse valor posteriormente? Você precisa encontrar todas as instâncias dessa propriedade e fazer a alteração. Além disso, suponha que você não saiba qual valor usar; ele pode ser calculado em runtime com base em fatores como orientação do dispositivo, resolução de tela ou outras considerações. Nesses casos, você precisa de algo mais sofisticado do que um literal embutido em código. Aqui, uma extensão de marcação é útil. Extensões de marcação oferecem flexibilidade no modo de obter um valor 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. Essa 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 double
.
O parâmetro serviceProvider
contém informações contextuais sobre onde a extensão de marcação está sendo usada no código XAML. Entre outras informações, ele identifica o controle ao qual a extensão está sendo aplicada.
Você pode manter a extensão de marcação para a propriedade simples FontSize
. No exemplo a seguir, a classe MainPage
expõe um campo double
chamado MyFontSize
. A classe GlobalFontSizeExtension
implementa a interface IMarkupExtension
e o método ProvideValue
retorna o valor de 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;
}
}
Observação
O campo MyFontSize
deve ser um membro static
da classe MainPage
para permitir que ele seja referenciado no método ProvideValue
de sua maneira. Uma boa prática é que, nesse caso, a variável também deve ser uma constante. Um valor de const
é static
.
O método ProvideValue
também pode fazer ajustes no valor retornado dependendo da orientação e do fator forma do dispositivo.
Aplicando a extensão de marcação a um controle em XAML
Para usar a extensão de marcação no código XAML, adicione o namespace que contém a classe GlobalFontSizeExtension
à lista de namespaces na marca ContentPage
. 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 propriedade FontSize
dessa forma. Observe que a convenção é uma extensão de marcação tenha o sufixo Extension no nome. O XAML reconhece esse sufixo e você não precisa incluí-lo ao chamar a extensão do código XAML. No exemplo a seguir, a classe GlobalFontSizeExtension
é 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. Posteriormente, se você decidir alterar o tamanho da fonte, só precisará modificar a definição da variável MyFontSize
na classe MainPage
.
A classe StaticExtension
Por mais que a extensão de marcação GlobalFontSize
seja útil, é improvável que você crie essa extensão. O motivo para isso é simples; o .NET MAUI já fornece uma extensão mais generalizada que permite que você faça referência a qualquer valor estático em seu código. Essa extensão é nomeada StaticExtension
ou Static
para abreviar. O código a seguir mostra a estrutura de tópicos básica desta classe de extensão:
[ContentProperty ("Member")]
public class StaticExtension : IMarkupExtension
{
public string Member {get; set;}
public object ProvideValue (IServiceProvider serviceProvider)
{
...
}
}
Observação
A finalidade das extensões de marcação personalizadas é permitir que você lide com situações mais complexas em vez do caso estático simples. Por exemplo, talvez você precise alterar dinamicamente o tamanho da fonte com base no fator forma do dispositivo.
Para usar essa classe no código XAML, forneça o nome da variável estática que deseja referenciar na propriedade Member
, e o método ProvideValue
retornará o valor nessa variável. O seguinte exemplo 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 estilos e recursos dinâmicos e manipulação de matrizes de dados.