基本 XAML 语法

浏览示例。 浏览示例

XAML 主要用于实例化和初始化对象。 但通常,必须将属性设置为无法轻易表示为 XML 字符串的复杂对象,有时必须对子类设置由一个类定义的属性。 这两个需求需要 属性元素附加属性的基本 XAML 语法功能。

属性元素

在 .NET 多平台应用 UI (.NET MAUI) XAML 中,类的属性通常设置为 XML 属性:

<Label Text="Hello, XAML!"
       VerticalOptions="Center"
       FontAttributes="Bold"
       FontSize="18"
       TextColor="Aqua" />

但是,有一种在 XAML 中设置属性的替代方法:

<Label Text="Hello, XAML!"
       VerticalOptions="Center"
       FontAttributes="Bold"
       FontSize="18">
    <Label.TextColor>
        Aqua
    </Label.TextColor>
</Label>

这两个指定 TextColor 属性的示例在功能上是等效的,并启用一些基本术语的引入:

  • Label一个对象元素。 它是一个以 XML 元素表示的 .NET MAUI 对象。
  • TextVerticalOptionsFontAttributesFontSize属性属性。 它们是以 XML 属性表示的 .NET MAUI 属性。
  • 第二个示例中, TextColor 已成为 属性元素。 它是一个以 XML 元素表示的 .NET MAUI 属性。

注释

在属性元素中,属性的值始终定义为属性元素开始标记和结束标记之间的内容。

还可以对对象的多个属性使用 Property-element 语法:

<Label Text="Hello, XAML!"
       VerticalOptions="Center">
    <Label.FontAttributes>
        Bold
    </Label.FontAttributes>
    <Label.FontSize>
        Large
    </Label.FontSize>
    <Label.TextColor>
        Aqua
    </Label.TextColor>
</Label>

虽然属性元素语法似乎不必要,但当属性的值太复杂,无法表示为简单字符串时,这一点至关重要。 在属性元素标记中,可以实例化另一个对象并设置其属性。 例如,Grid 布局有名为 RowDefinitionsColumnDefinitions 的属性,它们分别属于 RowDefinitionCollectionColumnDefinitionCollection 类型。 这些类型是集合 RowDefinitionColumnDefinition 对象,通常使用属性元素语法来设置它们:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.GridDemoPage"
             Title="Grid Demo Page">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="100" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="100" />
        </Grid.ColumnDefinitions>
        ...
    </Grid>
</ContentPage>

附加属性

在前面的示例中,你看到 Grid 需要为 RowDefinitions 集合和 ColumnDefinitions 集合提供属性元素,以定义行和列。 这表明必须有一种方法来指示每个子元素 Grid 所在的行和列。

在每个 Grid 子标签中,您可以使用 Grid.RowGrid.Column 属性指定该子元素的行和列,它们的默认值均为 0。 还可以使用具有默认值1的Grid.RowSpanGrid.ColumnSpan属性指示子级是否跨越多个行或列。

以下示例演示将子级置于Grid中:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.GridDemoPage"
             Title="Grid Demo Page">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="100" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="100" />
        </Grid.ColumnDefinitions>

        <Label Text="Autosized cell"
               TextColor="White"
               BackgroundColor="Blue" />
        <BoxView Color="Silver"
                 Grid.Column="1" />
        <BoxView Color="Teal"
                 Grid.Row="1" />
        <Label Text="Leftover space"
               Grid.Row="1" Grid.Column="1"
               TextColor="Purple"
               BackgroundColor="Aqua"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />
        <Label Text="Span two rows (or more if you want)"
               Grid.Column="2" Grid.RowSpan="2"
               TextColor="Yellow"
               BackgroundColor="Blue"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />
        <Label Text="Span two columns"
               Grid.Row="2" Grid.ColumnSpan="2"
               TextColor="Blue"
               BackgroundColor="Yellow"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />
        <Label Text="Fixed 100x100"
               Grid.Row="2" Grid.Column="2"
               TextColor="Aqua"
               BackgroundColor="Red"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />

    </Grid>
</ContentPage>

此 XAML 会导致以下布局:

.NET MAUI 网格布局。

Grid.RowGrid.ColumnGrid.RowSpanGrid.ColumnSpan 属性似乎是 Grid 类的属性,但此类没有定义名为 RowColumnRowSpanColumnSpan 的任何内容。 相反,该Grid类定义了四个可绑定属性,这些属性是RowPropertyColumnPropertyRowSpanPropertyColumnSpanProperty称为附加属性的特殊类型的可绑定属性。 它们由 Grid 类定义,但设置在 Grid 的子项上。

注释

在代码中使用这些附加属性时,类Grid提供名为GetRow、、SetRowGetColumn、、SetColumnGetRowSpanSetRowSpan、、 GetColumnSpan和的SetColumnSpan静态方法。

在 XAML 中,附加属性可识别为一个以句点分隔类名和属性名称组成的属性。 它们被称为 附加属性,因为它们由一个类(在本例中为Grid)定义,但附加到其他对象(在本例中为Grid的子对象)。 在布局期间, Grid 可以询问这些附加属性的值,以了解放置每个子项的位置。

内容属性

在前面的示例中,对象 Grid 已设置为 ContentContentPage对象的属性。 但是, Content 该属性未在 XAML 中引用,但可以是:

<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">
    <ContentPage.Content>
        <Grid>
            ...
        </Grid>
    </ContentPage.Content>
</ContentPage>

XAML 中不需要该 Content 属性,因为定义为在 .NET MAUI XAML 中使用的元素允许在类上指定 ContentProperty 一个属性:

[ContentProperty("Content")]
public class ContentPage : TemplatedPage
{
    ...
}

指定为 ContentProperty 类的任何属性意味着不需要属性的属性元素标记。 因此,上面的示例指定在 ContentPage 开始标记和结束标记之间显示的任何 XAML 内容都被分配给 Content 属性。

许多类也具有 ContentProperty 属性定义。 例如,Label 的内容属性是 Text.

平台差异

.NET MAUI 应用可以基于每个平台自定义 UI 外观。 这可以在 XAML 中使用 OnPlatformOn 类来实现。

Platform类的属性On接受以下字符串值:

  • iOS - iOS 设备
  • Android - Android 设备
  • WinUI - Windows 设备
  • MacCatalyst - Mac Catalyst(运行 iOS 应用的 macOS 设备)

重要

平台值区分大小写。 对于 Windows 设备,请使用 WinUI,而不是 Windows

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">
    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <On Platform="iOS" Value="0,20,0,0" />
            <On Platform="Android" Value="10,20,20,10" />
        </OnPlatform>
    </ContentPage.Padding>
    ...
</ContentPage>

OnPlatform 是泛型类,因此需要指定泛型类型参数( Thickness在本例中为属性的类型 Padding )。 这是通过 XAML 属性 x:TypeArguments 实现的。 该 OnPlatform 类定义一个 Default 属性,该属性可设置为将应用于所有平台的值:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">
    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness" Default="20">
            <On Platform="iOS" Value="0,20,0,0" />
            <On Platform="Android" Value="10,20,20,10" />
            <On Platform="WinUI" Value="5,10,5,10" />
        </OnPlatform>
    </ContentPage.Padding>
    ...
</ContentPage>

在此示例中,该 Padding 属性设置为 iOS、Android 和 Windows 上的不同值,其他平台设置为默认值。

注释

使用属性PaddingMargin定位控件时,如果提供了四个值,则顺序为左、上、右、下。 有关详细信息,请参阅 位置控件

OnPlatform类还定义了一个Platforms属性,该属性是IList类型的On对象。 每个 On 对象都可以设置 PlatformValue 属性来定义 Thickness 特定平台的值。 此外,该 Platform 属性 On 的类型如下 IList<string>,因此,如果值相同,则可以包含多个平台:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">
    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness" Default="20">
            <On Platform="iOS, MacCatalyst" Value="0,20,0,0" />
            <On Platform="Android, WinUI" Value="10,20,20,10" />
        </OnPlatform>
    </ContentPage.Padding>
    ...
</ContentPage>

这是在 XAML 中设置依赖于 Padding 平台的属性的标准方法。

注释

Value如果对象的On属性不能由单个字符串表示,则可以为其定义属性元素。

有关详细信息,请参阅 基于平台自定义 UI 外观

后续步骤

.NET MAUI XAML 标记扩展允许属性设置为从其他来源间接引用的对象或值。 XAML 标记扩展对于共享对象以及引用整个应用中使用的常量尤其重要。