使用 XAML 標記擴充功能
.NET 多平臺應用程式 UI (.NET MAUI) XAML 標記延伸可藉由允許從各種來源設定元素屬性,協助增強 XAML 的功能和彈性。
例如,您通常會設定 BoxView 的 Color
屬性,如下所示:
<BoxView Color="Blue" />
不過,建議您改為從儲存在資源字典中的值,或從您所建立類別的靜態屬性值,或從頁面上另一個元素類型 Color 的屬性,或從個別色調、飽和度和亮度值建構的屬性,來設定 Color
屬性。 所有這些選項都可以使用 XAML 標記擴充。
標記延伸是表示項目屬性的不同方式。 .NET MAUI XAML 標記延伸通常透過大括弧括住的屬性值來辨識:
<BoxView Color="{StaticResource themeColor}" />
大括弧中的任何屬性值 一律 XAML 標記延伸。 不過,XAML 標記延伸也可以不使用大括弧進行參考。
注意
數個 XAML 標記延伸是 XAML 2009 規格的一部分。 這些命名空間會出現在具有習慣的 x
命名空間前置詞的 XAML 檔案中,常以此為前置詞參考。
除了本文所討論的標記延伸之外,.NET MAUI 中還包含下列標記延伸,並在其他文章中討論:
-
AppThemeBinding
- 指定要根據目前系統主題取用的資源。 如需詳細資訊,請參閱 AppThemeBinding 標記擴充。 -
Binding
- 建立兩個物件屬性之間的連結。 如需詳細資訊,請參閱 資料系結。 -
DynamicResource
- 回應資源字典中對象的變更。 如需詳細資訊,請參閱 動態樣式。 -
FontImage
- 在任何可顯示 ImageSource的檢視中顯示字型圖示。 如需詳細資訊,請參閱 載入字型圖示。 -
OnIdiom
- 根據應用程式執行裝置的語氣自定義UI外觀。 如需詳細資訊,請參閱 根據裝置語自定義 UI 外觀。 -
OnPlatform
- 根據每個平臺自定義UI外觀。 如需詳細資訊,請參閱 根據平臺自定義 UI 外觀。 -
RelativeSource
- 設定系結來源相對於系結目標的位置。 如需詳細資訊,請參閱 相對繫結。 -
StaticResource
- 參考資源字典中的物件。 如需詳細資訊,請參閱 資源字典。 -
TemplateBinding
- 從控件範本執行數據系結。 如需詳細資訊,請參閱 控制項範本。
x:Static 標記擴充
x:Static
標記延伸由 StaticExtension 類別支援。 類別有一個名為 Member
、類型為 string
的單一屬性,您可以將其設為公共常數、靜態屬性、靜態欄位或列舉成員的名稱。
使用 x:Static
的其中一種方法是先定義具有某些常數或靜態變數的類別,例如這個 AppConstants
類別:
static class AppConstants
{
public static double NormalFontSize = 18;
}
下列 XAML 示範在 Label.FontSize
屬性元素標籤之間具現化 StaticExtension 類別的最詳盡方法:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:sys="clr-namespace:System;assembly=netstandard"
xmlns:local="clr-namespace:MarkupExtensions"
x:Class="MarkupExtensions.StaticDemoPage"
Title="x:Static Demo">
<StackLayout Margin="10, 0">
<Label Text="Label No. 1">
<Label.FontSize>
<x:StaticExtension Member="local:AppConstants.NormalFontSize" />
</Label.FontSize>
</Label>
···
</StackLayout>
</ContentPage>
XAML 剖析器也允許將 StaticExtension 類別縮寫為 x:Static
:
<Label Text="Label No. 2">
<Label.FontSize>
<x:Static Member="local:AppConstants.NormalFontSize" />
</Label.FontSize>
</Label>
藉由將 StaticExtension 類別和成員設定放在大括弧中,即可進一步簡化此語法。 產生的表達式會直接設定為 FontSize
屬性:
<Label Text="Label No. 3"
FontSize="{x:StaticExtension Member=local:AppConstants.NormalFontSize}" />
在此範例中,大括弧內沒有 引號。
StaticExtension 的 Member
屬性不再是 XML 屬性。 它反而是標記擴展表達式的一部分。
就像當您使用 x:StaticExtension
作為物件元素時可以縮寫為 x:Static
,您也可以在大括弧內的表達式中縮寫它:
<Label Text="Label No. 4"
FontSize="{x:Static Member=local:AppConstants.NormalFontSize}" />
StaticExtension 類別具有參考屬性 Member
的 ContentProperty
屬性,此屬性會將此屬性標示為類別的預設內容屬性。 針對以大括弧表示的 XAML 標記延伸,您可以排除表達式 Member=
部分:
<Label Text="Label No. 5"
FontSize="{x:Static local:AppConstants.NormalFontSize}" />
這是最常見的 x:Static
標記延伸形式。
XAML 範例的根標記也包含 .NET System
命名空間的 XML 命名空間宣告。 這可讓 Label 字型大小設定為靜態字段 Math.PI
。 這會產生相當小的文字,因此 Scale
屬性會設定為 Math.E
:
<Label Text="π × E sized text"
FontSize="{x:Static sys:Math.PI}"
Scale="{x:Static sys:Math.E}"
HorizontalOptions="Center" />
下列螢幕快照顯示 XAML 輸出:
x:Reference markup extension
x:Reference
標記延伸由 ReferenceExtension 類別支援。 類別具有一個類型為 string
的單一屬性 Name
,該屬性會被設定為頁面上具有 x:Name
名稱的元素的名稱。 這個 Name
屬性是 ReferenceExtension的內容屬性,因此當 x:Reference
出現在大括弧時,不需要 Name=
。
x:Reference
標記延伸專門用於數據繫結。 如需資料系結的詳細資訊,請參閱 資料系結。
下列 XAML 範例示範兩個搭配數據系結 x:Reference
用法,第一個是用來設定 Binding
物件的 Source
屬性,第二個用來設定兩個數據系結的 BindingContext
屬性:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.ReferenceDemoPage"
x:Name="page"
Title="x:Reference Demo">
<StackLayout Margin="10, 0">
<Label Text="{Binding Source={x:Reference page},
StringFormat='The type of this page is {0}'}"
FontSize="18"
VerticalOptions="Center"
HorizontalTextAlignment="Center" />
<Slider x:Name="slider"
Maximum="360"
VerticalOptions="Center" />
<Label BindingContext="{x:Reference slider}"
Text="{Binding Value, StringFormat='{0:F0}° rotation'}"
Rotation="{Binding Value}"
FontSize="24"
HorizontalOptions="Center"
VerticalOptions="Center" />
</StackLayout>
</ContentPage>
在此範例中,這兩個 x:Reference
表示式都會使用 ReferenceExtension 類別名稱的縮寫版本,並消除表達式 Name=
部分。 在第一個範例中,x:Reference
標記延伸會內嵌在 Binding
標記延伸中,而 Source
和 StringFormat
屬性則以逗號分隔。
下列螢幕快照顯示 XAML 輸出:
x:Type 標記擴展
x:Type
標記擴充是 XAML 中相當於 C# typeof
關鍵字的對應功能。 由 TypeExtension 類別支援,該類別定義了一個名為 TypeName
、類型為 string
的屬性,該屬性應設置為類別或結構的名稱。
x:Type
標記延伸會傳回該類別或結構的 Type
物件。
TypeName
是 TypeExtension的內容屬性,因此當 x:Type
出現大括弧時,不需要 TypeName=
。
x:Type
標記延伸通常與 x:Array
標記延伸搭配使用。 如需詳細資訊,請參閱 x:Array 標記延伸。
下列 XAML 範例示範如何使用 x:Type
標記延伸來具現化 .NET MAUI 物件,並將其新增至 StackLayout。 XAML 包含三個 Button 元素,其 Command
屬性設定為 Binding
,而 CommandParameter
屬性則設定為三種 .NET MAUI 檢視的類型:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.TypeDemoPage"
Title="x:Type Demo">
<StackLayout x:Name="stackLayout"
Padding="10, 0">
<Button Text="Create a Slider"
HorizontalOptions="Center"
VerticalOptions="Center"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Slider}" />
<Button Text="Create a Stepper"
HorizontalOptions="Center"
VerticalOptions="Center"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Stepper}" />
<Button Text="Create a Switch"
HorizontalOptions="Center"
VerticalOptions="Center"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Switch}" />
</StackLayout>
</ContentPage>
程式代碼後置檔案會定義並初始化 CreateCommand
屬性:
public partial class TypeDemoPage : ContentPage
{
public ICommand CreateCommand { get; private set; }
public TypeDemoPage()
{
InitializeComponent();
CreateCommand = new Command<Type>((Type viewType) =>
{
View view = (View)Activator.CreateInstance(viewType);
view.VerticalOptions = LayoutOptions.Center;
stackLayout.Add(view);
});
BindingContext = this;
}
}
按下 Button 時,會建立 CommandParameter
自變數的新實例,並將其新增至 StackLayout。 三個 Button 對象接著會與動態建立的檢視共享頁面:
泛型型別可以使用 x:Type
標記延伸來指定,方法是在括弧中將泛型條件約束指定為前置字串自變數:
<x:Array Type="{x:Type local:MyType(local:MyObject)}">
...
</x:Array>
多個類型自變數可以指定為前置字串自變數,並以逗號分隔:
<x:Array Type="{x:Type local:MyType(local:MyObject,x:Boolean)}">
...
</x:Array>
如需 XAML 中泛型的詳細資訊,請參閱 泛型。
x:Array 標記擴展
x:Array
標記延伸可讓您在標記中定義陣列。
ArrayExtension 類別支援,其定義兩個屬性:
-
Type
類型的Type
,表示陣列中的項目類型。 此屬性應該設定為x:Type
標記延伸。 -
IList
類型的Items
,這是一個項目本身的集合。 這是 ArrayExtension的內容屬性。
x:Array
標記延伸本身永遠不會出現在大括弧中。 相反地,x:Array
開始和結束標記會分隔專案清單。
下列 XAML 範例示範如何使用 x:Array
,透過將 ItemsSource
屬性設定為陣列,將項目新增到 ListView:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.ArrayDemoPage"
Title="x:Array Demo Page">
<ListView Margin="10">
<ListView.ItemsSource>
<x:Array Type="{x:Type Color}">
<Color>Aqua</Color>
<Color>Black</Color>
<Color>Blue</Color>
<Color>Fuchsia</Color>
<Color>Gray</Color>
<Color>Green</Color>
<Color>Lime</Color>
<Color>Maroon</Color>
<Color>Navy</Color>
<Color>Olive</Color>
<Color>Pink</Color>
<Color>Purple</Color>
<Color>Red</Color>
<Color>Silver</Color>
<Color>Teal</Color>
<Color>White</Color>
<Color>Yellow</Color>
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<BoxView Color="{Binding}"
Margin="3" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
在此範例中,ViewCell 會為每個色彩項目建立簡單的 BoxView:
注意
定義字串或數位等常見類型的數位時,請使用 Pass 自變數中所列的 XAML 語言基本標記。
x:Null 標記擴展
x:Null
標記延伸由 NullExtension 類別支援。 它沒有任何屬性,而且只是 C# null
關鍵詞的 XAML 對等專案。
下列 XAML 範例示範如何使用 x:Null
標記延伸:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.NullDemoPage"
Title="x:Null Demo">
<ContentPage.Resources>
<Style TargetType="Label">
<Setter Property="FontSize" Value="48" />
<Setter Property="FontFamily" Value="OpenSansRegular" />
</Style>
</ContentPage.Resources>
<StackLayout Padding="10, 0">
<Label Text="Text 1" />
<Label Text="Text 2" />
<Label Text="Text 3"
FontFamily="{x:Null}" />
<Label Text="Text 4" />
<Label Text="Text 5" />
</StackLayout>
</ContentPage>
在此範例中,為 Label 定義了一個隱含的 Style,其中包括一個將 FontFamily
屬性設定為特定字型的 Setter。 不過,第三個 Label 以避免使用隱含樣式中定義的字型,將其 FontFamily
設定為 x:Null
。
資料模板標記擴展
DataTemplate 標記延伸可讓您將類型轉換成 DataTemplate。
DataTemplateExtension 類別支援,該類別會定義類型為 string
的 TypeName
屬性,該屬性會設定為要轉換成 DataTemplate的類型名稱。
TypeName
屬性是 DataTemplateExtension的內容屬性。 因此,對於以大括弧表示的 XAML 標記表示式,您可以排除表示式 TypeName=
部分。
注意
XAML 剖析器可讓 DataTemplateExtension 類別縮寫為 DataTemplate。
此標記延伸的一般用法是在Shell應用程式中,如下列範例所示:
<ShellContent Title="Monkeys"
Icon="monkey.png"
ContentTemplate="{DataTemplate views:MonkeysPage}" />
在這裡範例中,MonkeysPage
會從 ContentPage 轉換成 DataTemplate,而 ShellContent.ContentTemplate
屬性的值會設定為 。 這可確保只有在瀏覽至頁面時,才會建立 MonkeysPage
,而不是在應用程式啟動時建立。
如需 Shell 應用程式的詳細資訊,請參閱 Shell。