Introdução ao XAML
Em um aplicativo .NET Multi-platform App UI (.NET MAUI), o XAML é usado principalmente para definir o conteúdo visual de uma página e funciona em conjunto com um arquivo code-behind C#. O arquivo code-behind fornece suporte de código para a marcação. Juntos, esses dois arquivos contribuem para uma nova definição de classe que inclui exibições filho e inicialização de propriedade. No arquivo XAML, classes e propriedades são referenciadas com elementos e atributos XML, e os links entre a marcação e o código são estabelecidos.
Anatomia de um arquivo XAML
Um novo aplicativo .NET MAUI contém três arquivos XAML e seus arquivos code-behind associados:
O primeiro emparelhamento de arquivos é App.xaml, um arquivo XAML, e App.xaml.cs, um arquivo code-behind C# associado ao arquivo XAML. App.xaml e App.xaml.cs contribuem para uma classe chamada App
que deriva de Application
. O segundo emparelhamento de arquivos é AppShell.xaml e AppShell.xaml.cs, que contribuem para uma classe chamada AppShell
que deriva de Shell. A maioria das outras classes com arquivos XAML contribuem para uma classe que deriva de e definem a interface do usuário de ContentPageuma página. Isso é verdadeiro para os arquivos MainPage.xaml e MainPage.xaml.cs arquivos.
O arquivo MainPage.xaml tem a seguinte estrutura:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyMauiApp.MainPage">
...
</ContentPage>
As duas declarações de namespace XML (xmlns
) referem-se a URIs em microsoft.com. No entanto, não há conteúdo nesses URIs e eles funcionam basicamente como identificadores de versão.
A primeira declaração de namespace XML significa que as marcas definidas no arquivo XAML sem prefixo se referem a classes no .NET MAUI, por exemplo ContentPage. A segunda declaração de namespace define um prefixo de x
. Isso é usado para vários elementos e atributos que são intrínsecos ao próprio XAML e que são suportados por outras implementações de XAML. No entanto, esses elementos e atributos são ligeiramente diferentes dependendo do ano incorporado no URI. O .NET MAUI oferece suporte à especificação XAML de 2009.
No final da primeira tag, o prefixo x
é usado para um atributo chamado Class
. Como o uso desse x
prefixo é praticamente universal para o namespace XAML, atributos XAML como Class
são quase sempre chamados de x:Class
. O x:Class
atributo especifica um nome de classe .NET totalmente qualificado: a MainPage
classe no MyMauiApp
namespace. Isso significa que esse arquivo XAML define uma nova classe nomeada MainPage
no namespace que deriva MyMauiApp
de ContentPage (a marca na qual o x:Class
atributo aparece).
O x:Class
atributo só pode aparecer no elemento raiz de um arquivo XAML para definir uma classe C# derivada. Essa é a única nova classe definida no arquivo XAML. Todo o resto que aparece em um arquivo XAML é simplesmente instanciado a partir de classes existentes e inicializado.
O arquivo MainPage.xaml.cs é semelhante a este:
namespace MyMauiApp;
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
A MainPage
classe deriva de , e é uma definição de ContentPageclasse parcial.
Quando o Visual Studio cria o projeto, um gerador de código-fonte gera nova fonte C# que contém a InitializeComponent
definição do método que é chamado do MainPage
construtor e adiciona-lo ao objeto de compilação.
Em tempo de execução, o código na classe inicializa o aplicativo e executa o MauiProgram
construtor de classe, que instancia AppShell
.App
A AppShell
classe instancia a primeira página do aplicativo a ser exibida, que é MainPage
. O MainPage
construtor chama InitializeComponent
, que inicializa todos os objetos definidos no arquivo XAML, conecta-os todos juntos em relações pai-filho, anexa manipuladores de eventos definidos no código a eventos definidos no arquivo XAML e define a árvore resultante de objetos como o conteúdo da página.
Observação
A AppShell
classe usa o .NET MAUI Shell para definir a primeira página do aplicativo a ser exibida. No entanto, o Shell está além do escopo desta introdução ao XAML. Para obter mais informações, consulte .NET MAUI Shell.
Definir conteúdo da página
Um ContentPage deve conter um único filho, que pode ser um modo de exibição ou um layout com modos de exibição filho. O filho do ContentPage é definido automaticamente como o valor da ContentPage.Content
propriedade.
O exemplo a seguir mostra um contendo um ContentPage Label:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.HelloXamlPage"
Title="Hello XAML Page">
<Label Text="Hello, XAML!"
VerticalOptions="Center"
HorizontalTextAlignment="Center"
Rotation="-15"
FontSize="18"
FontAttributes="Bold"
TextColor="Blue" />
</ContentPage>
No exemplo acima, a relação entre classes, propriedades e XML deve ser evidente. Uma classe .NET Maui (como ContentPage ou Label) aparece no arquivo XAML como um elemento XML. As propriedades dessa classe — incluindo Title
on ContentPage e sete propriedades de Label geralmente aparecem como atributos XML.
Existem muitos atalhos para definir os valores dessas propriedades. Algumas propriedades são tipos de dados básicos. Por exemplo, as Title
propriedades e são do tipo , e Rotation
Text
é do tipo double
string
. A HorizontalTextAlignment
propriedade é do tipo TextAlignment
, que é uma enumeração. Para uma propriedade de qualquer tipo de enumeração, tudo o que você precisa fornecer é um nome de membro.
Para propriedades de tipos mais complexos, no entanto, os conversores são usados para analisar o XAML. Essas são classes no .NET MAUI que derivam de TypeConverter
. Para o exemplo acima, vários conversores .NET MAUI são aplicados automaticamente para converter valores de cadeia de caracteres para seu tipo correto:
LayoutOptionsConverter
para oVerticalOptions
imóvel. Esse conversor converte os nomes de campos estáticos públicos daLayoutOptions
estrutura em valores do tipoLayoutOptions
.ColorTypeConverter
para oTextColor
imóvel. Esse conversor converte os nomes de campos estáticos públicos da Colors classe ou valores RGB hexadecimais, com ou sem um canal alfa.
Navegação da página
Quando você executa um aplicativo .NET MAUI, o MainPage
normalmente é exibido. Para ver uma página diferente, você pode defini-la como a nova página de inicialização no arquivo AppShell.xaml ou navegar até a nova página a partir do MainPage
.
Para implementar a navegação, no construtor MainPage.xaml.cs você pode criar um simples Button e usar o manipulador de eventos para navegar até HelloXamlPage
:
public MainPage()
{
InitializeComponent();
Button button = new Button
{
Text = "Navigate!",
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center
};
button.Clicked += async (sender, args) =>
{
await Navigation.PushAsync(new HelloXamlPage());
};
Content = button;
}
Quando você compila e implanta a nova versão deste aplicativo, um botão aparece na tela. Pressionando-o navega para HelloXamlPage
:
Você pode navegar de volta para MainPage
usar a barra de navegação que aparece em cada plataforma.
Observação
Uma alternativa a esse modelo de navegação é usar o Shell MAUI do .NET. Para obter mais informações, consulte Visão geral do Shell do .NET MAUI.
XAML e interações de código
O filho da maioria ContentPage dos derivados é um layout, como um ou um StackLayout Grid, e o layout pode conter vários filhos. Em XAML, essas relações pai-filho são estabelecidas com hierarquia XML normal:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.XamlPlusCodePage"
Title="XAML + Code Page">
<StackLayout>
<Slider VerticalOptions="Center" />
<Label Text="A simple Label"
FontSize="18"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Button Text="Click Me!"
HorizontalOptions="Center"
VerticalOptions="Center" />
</StackLayout>
</ContentPage>
Esse arquivo XAML é sintaticamente completo e produz a seguinte interface do usuário:
No entanto, embora você possa interagir com o Slider e Button, a interface do usuário não é atualizada. O Slider deve fazer com que o exiba o valor atual e o Label Button deve fazer algo.
A exibição de um valor usando um pode ser obtida inteiramente em XAML com uma associação de Slider Label dados. No entanto, é útil ver a solução de código primeiro. Mesmo assim, lidar com o Button clique definitivamente requer código. Isso significa que o arquivo code-behind para deve conter manipuladores para XamlPlusCodePage
o evento do e o ValueChanged
Clicked
evento do Slider Button:
namespace XamlSamples
{
public partial class XamlPlusCodePage
{
public XamlPlusCodePage()
{
InitializeComponent();
}
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
valueLabel.Text = args.NewValue.ToString("F3");
}
async void OnButtonClicked(object sender, EventArgs args)
{
Button button = (Button)sender;
await DisplayAlert("Clicked!", "The button labeled '" + button.Text + "' has been clicked", "OK");
}
}
}
De volta ao arquivo XAML, as Slider marcas e precisam incluir atributos para os ValueChanged
eventos e Button Clicked
que fazem referência a esses manipuladores:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.XamlPlusCodePage"
Title="XAML + Code Page">
<StackLayout>
<Slider VerticalOptions="Center"
ValueChanged="OnSliderValueChanged" />
<Label x:Name="valueLabel"
Text="A simple Label"
FontSize="18"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Button Text="Click Me!"
HorizontalOptions="Center"
VerticalOptions="Center"
Clicked="OnButtonClicked" />
</StackLayout>
</ContentPage>
Observe que atribuir um manipulador a um evento tem a mesma sintaxe que atribuir um valor a uma propriedade. Além disso, para que o manipulador de eventos do use o para exibir o valor atual, o ValueChanged
Label manipulador precisa fazer referência a esse objeto a partir do Slider código. Portanto, o precisa de um nome, que é especificado com o Label x:Name
atributo. O x
prefixo x:Name
do atributo indica que esse atributo é intrínseco ao XAML. O nome atribuído ao atributo tem as mesmas regras que os x:Name
nomes de variáveis C#. Por exemplo, ele deve começar com uma letra ou sublinhado e não conter espaços incorporados.
O ValueChanged
manipulador de eventos agora pode definir o para exibir o Label novo Slider valor, que está disponível nos argumentos do evento:
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
valueLabel.Text = args.NewValue.ToString("F3");
}
Como alternativa, o manipulador pode obter o Slider objeto que está gerando esse evento a sender
partir do argumento e obter a propriedade a Value
partir dele:
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
valueLabel.Text = ((Slider)sender).Value.ToString("F3");
}
O resultado é que qualquer manipulação do Slider faz com que seu valor seja exibido no Label:
No exemplo acima, o Button simula uma resposta a um evento exibindo um Clicked
alerta com o Text
botão do botão. Portanto, o manipulador de eventos pode converter o sender
argumento em um Button e, em seguida, acessar suas propriedades:
async void OnButtonClicked(object sender, EventArgs args)
{
Button button = (Button)sender;
await DisplayAlert("Clicked!", "The button labeled '" + button.Text + "' has been clicked", "OK");
}
O OnButtonClicked
método é definido como async
porque o método é assíncrono e deve ser precedido com o operador, que retorna quando o DisplayAlert await
método é concluído. Como esse método obtém o disparo do evento do sender
argumento, o Button mesmo manipulador pode ser usado para vários botões.
Próximas etapas
O XAML foi projetado principalmente para instanciar e inicializar objetos. Mas, muitas vezes, as propriedades devem ser definidas como objetos complexos que não podem ser facilmente representados como cadeias de caracteres XML e, às vezes, as propriedades definidas por uma classe devem ser definidas em uma classe filha. Essas duas necessidades exigem os recursos essenciais de sintaxe XAML de elementos de propriedade e propriedades anexadas.