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 对象。
-
Text、VerticalOptions、FontAttributes和FontSize是 属性属性。 它们是以 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 布局有名为 RowDefinitions 和 ColumnDefinitions 的属性,它们分别属于 RowDefinitionCollection 和 ColumnDefinitionCollection 类型。 这些类型是集合 RowDefinition 和 ColumnDefinition 对象,通常使用属性元素语法来设置它们:
<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.Row 和 Grid.Column 属性指定该子元素的行和列,它们的默认值均为 0。 还可以使用具有默认值1的Grid.RowSpan和Grid.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 会导致以下布局:
Grid.Row、Grid.Column、Grid.RowSpan 和 Grid.ColumnSpan 属性似乎是 Grid 类的属性,但此类没有定义名为 Row、Column、RowSpan 或 ColumnSpan 的任何内容。 相反,该Grid类定义了四个可绑定属性,这些属性是RowPropertyColumnPropertyRowSpanPropertyColumnSpanProperty称为附加属性的特殊类型的可绑定属性。 它们由 Grid 类定义,但设置在 Grid 的子项上。
注释
在代码中使用这些附加属性时,类Grid提供名为GetRow、、SetRow、GetColumn、、SetColumn、GetRowSpanSetRowSpan、、 GetColumnSpan和的SetColumnSpan静态方法。
在 XAML 中,附加属性可识别为一个以句点分隔类名和属性名称组成的属性。 它们被称为 附加属性,因为它们由一个类(在本例中为Grid)定义,但附加到其他对象(在本例中为Grid的子对象)。 在布局期间, Grid 可以询问这些附加属性的值,以了解放置每个子项的位置。
内容属性
在前面的示例中,对象 Grid 已设置为 Content 该 ContentPage对象的属性。 但是, 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 中使用 OnPlatform 和 On 类来实现。
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 对象都可以设置 Platform 和 Value 属性来定义 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 标记扩展对于共享对象以及引用整个应用中使用的常量尤其重要。
浏览示例