使用 XAML 标记扩展
XAML 标记扩展支持从各种源设置元素属性,从而帮助增强 XAML 的功能和灵活性。 多个 XAML 标记扩展是 XAML 2009 规范的一部分。 它们出现在 XAML 文件中,带有惯用的 x
命名空间前缀,并且通常用此前缀来进行引用。 本文讨论以下标记扩展:
x:Static
- 引用静态属性、字段或枚举成员。x:Reference
- 引用页面上的命名元素。x:Type
- 将属性设置为System.Type
对象。x:Array
- 构造特定类型的对象的数组。x:Null
- 将属性设置为值null
。OnPlatform
- 基于每个平台自定义 UI 外观。OnIdiom
- 根据运行应用程序的设备的惯用法自定义 UI 外观。DataTemplate
- 将类型转换为DataTemplate
。FontImage
- 在任何可以显示ImageSource
的视图中显示字体图标。AppThemeBinding
- 根据当前系统主题使用资源。
其他 XAML 标记扩展历来受到其他 XAML 实现的支持,也受 Xamarin.Forms 的支持。 其他文章更全面地介绍了这些内容:
StaticResource
- 引用资源字典中的对象,如资源字典一文中所述。DynamicResource
- 响应资源字典中对象的更改,如动态样式一文中所述。Binding
- 在两个对象的属性之间建立链接,如数据绑定一文中所述。TemplateBinding
- 从控件模板执行数据绑定,如 Xamarin.Forms 控件模板一文中所述。RelativeSource
- 设置相对于绑定目标位置的绑定源,如相对绑定一文中所述。
RelativeLayout
布局使用自定义标记扩展 ConstraintExpression
。 此标记扩展在 RelativeLayout 一文中予以介绍。
x:Static 标记扩展
StaticExtension
类支持 x:Static
标记扩展。 该类具有类型为 string
的名为 Member
的单一属性,你可以将其设置为公共常量、静态属性、静态字段或枚举成员的名称。
使用 x:Static
的一种常见方法是首先定义具有某些常量或静态变量的类,例如这个微小的 AppConstants
类:
static class AppConstants
{
public static double NormalFontSize = 18;
}
“x:Static 演示”页面展示了多种使用 x:Static
标记扩展的方法。 最详细的方法是实例化 Label.FontSize
属性元素标记之间的 StaticExtension
类:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
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 命名空间声明:
xmlns:sys="clr-namespace:System;assembly=netstandard"
这可以让 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" />
最后一个示例显示 Device.RuntimePlatform
值。 Environment.NewLine
静态属性用于在两个 Span
对象之间插入一个新的换行符:
<Label HorizontalTextAlignment="Center"
FontSize="{x:Static local:AppConstants.NormalFontSize}">
<Label.FormattedText>
<FormattedString>
<Span Text="Runtime Platform: " />
<Span Text="{x:Static sys:Environment.NewLine}" />
<Span Text="{x:Static Device.RuntimePlatform}" />
</FormattedString>
</Label.FormattedText>
</Label>
下面是正在运行的示例:
x:Reference 标记扩展
ReferenceExtension
类支持 x:Reference
标记扩展。 该类具有 string
类型的名为 Name
的单一属性,可以将其设置为页面上已使用 x:Name
命名的元素的名称。 此 Name
属性是 ReferenceExtension
的内容属性,因此如果大括号中有 x:Reference
,则不需要 Name=
。
x:Reference
标记扩展专用于数据绑定,数据绑定一文对此进行了更详细的介绍。
“x:Reference 演示”页面显示了 x:Reference
在数据绑定中的两种用法,第一种是用于设置 Binding
对象的 Source
属性,第二种是用来设置两个数据绑定的 BindingContext
属性:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
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="CenterAndExpand"
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="CenterAndExpand" />
</StackLayout>
</ContentPage>
两个 x:Reference
表达式都使用 ReferenceExtension
类名的缩写版本,并消除了表达式的 Name=
部分。 在第一个示例中,x:Reference
标记扩展嵌入到 Binding
标记扩展中。 注意,Source
和 StringFormat
设置用逗号分隔。 下面是正在运行的程序:
x:Type 标记扩展
x:Type
标记扩展是 C# typeof
关键字的 XAML 等效项。 它受 TypeExtension
类支持,该类定义了一个类型为 string
的名为 TypeName
的属性,该属性设置为类名或结构名。 x:Type
标记扩展返回该类或结构的 System.Type
对象。 TypeName
是 TypeExtension
的内容属性,因此 x:Type
与大括号一起出现时,不需要 TypeName=
。
在 Xamarin.Forms 中,有几个属性具有类型为 Type
的参数。 示例包括 Style
的 TargetType
属性,以及用于在泛型类中指定参数的 x:TypeArguments 属性。 但是,XAML 分析程序会自动执行 typeof
操作,在这些情况下不会使用 x:Type
标记扩展。
需要的位置x:Type
之一是标记x:Array
扩展,下一部分将介绍。
x:Type
标记扩展在构造菜单时也很有用,在这种情况下,每个菜单项都对应特定类型的对象。 可以将 Type
对象与每个菜单项关联,然后在选中菜单项时实例化该对象。
这就是标记扩展程序中 MainPage
中的导航菜单的工作原理。 MainPage.xaml 文件包含 TableView
,每个 TextCell
对应于程序中的特定页面:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MarkupExtensions"
x:Class="MarkupExtensions.MainPage"
Title="Markup Extensions"
Padding="10">
<TableView Intent="Menu">
<TableRoot>
<TableSection>
<TextCell Text="x:Static Demo"
Detail="Access constants or statics"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:StaticDemoPage}" />
<TextCell Text="x:Reference Demo"
Detail="Reference named elements on the page"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:ReferenceDemoPage}" />
<TextCell Text="x:Type Demo"
Detail="Associate a Button with a Type"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:TypeDemoPage}" />
<TextCell Text="x:Array Demo"
Detail="Use an array to fill a ListView"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:ArrayDemoPage}" />
···
</TableRoot>
</TableView>
</ContentPage>
下面是标记扩展中打开的主页:
每个 CommandParameter
属性都设置为引用其他页面之一的 x:Type
标记扩展。 每个 Command
属性都绑定到一个名为 NavigateCommand
的属性。 此属性在 MainPage
代码隐藏文件中定义:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
NavigateCommand = new Command<Type>(async (Type pageType) =>
{
Page page = (Page)Activator.CreateInstance(pageType);
await Navigation.PushAsync(page);
});
BindingContext = this;
}
public ICommand NavigateCommand { private set; get; }
}
NavigateCommand
属性是一个 Command
对象,它使用类型为 Type
的参数(CommandParameter
的值)实现执行命令。 该方法使用 Activator.CreateInstance
实例化页面,然后导航到该页。 构造函数最后将页面的 BindingContext
设置为自身,使得 Command
上的 Binding
可以正常工作。 请参阅数据绑定一文,特别是命令文章,了解有关此类代码的更多详细信息。
“x:Type 演示”页面使用类似的技术实例化 Xamarin.Forms 元素并将它们添加到 StackLayout
。 XAML 文件最初由三个 Button
元素组成,它们的 Command
属性设置为 Binding
,CommandParameter
属性设置为三个 Xamarin.Forms 视图的类型:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
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="CenterAndExpand"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Slider}" />
<Button Text="Create a Stepper"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Stepper}" />
<Button Text="Create a Switch"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Switch}" />
</StackLayout>
</ContentPage>
代码隐藏文件定义并初始化 CreateCommand
属性:
public partial class TypeDemoPage : ContentPage
{
public TypeDemoPage()
{
InitializeComponent();
CreateCommand = new Command<Type>((Type viewType) =>
{
View view = (View)Activator.CreateInstance(viewType);
view.VerticalOptions = LayoutOptions.CenterAndExpand;
stackLayout.Children.Add(view);
});
BindingContext = this;
}
public ICommand CreateCommand { private set; get; }
}
在按下 Button
时执行的方法会创建参数的新实例,设置其 VerticalOptions
属性,并将其添加到 StackLayout
中。 然后,这三个 Button
元素与动态创建的视图共享页面:
x:Array 标记扩展
通过 x:Array
标记扩展,可以在标记中定义数组。 ArrayExtension
类对其提供支持,该类定义两个属性:
Type
类型的Type
,表示数组中元素的类型。IList
类型的Items
,它是项本身的集合。 这是ArrayExtension
的内容属性。
x:Array
标记扩展本身不会出现在大括号中。 但 x:Array
的开始标记和结束标记会分隔项列表。 将 Type
属性设置为 x:Type
标记扩展。
“x:Array 演示”页面显示了如何通过设置数组的 ItemsSource
属性来使用 x:Array
向 ListView
添加项:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
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
:
可通过多种方式指定此数组中的单个 Color
项。 可以使用 x:Static
标记扩展:
<x:Static Member="Color.Blue" />
或者,可使用 StaticResource
从资源字典中检索颜色:
<StaticResource Key="myColor" />
本文结束时,你将看到一个自定义 XAML 标记扩展,该扩展还会创建新的颜色值:
<local:HslColor H="0.5" S="1.0" L="0.5" />
定义常见类型的数组(如字符串或数字)时,请使用传递构造函数参数一文中列出的标记来分隔值。
x:Null 标记扩展
NullExtension
类支持 x:Null
标记扩展。 它没有属性,只是 C# null
关键字的 XAML 等效项。
x:Null
标记扩展很少需要,也很少使用,但如果确实需要它,你会庆幸有它。
“x:Null 演示”页面展示了一个场景,在该场景中 x:Null
可能很方便。 假设你为 Label
定义了一个隐式 Style
,其中包含一个 Setter
,它将 FontFamily
属性设置为与平台相关的系列名称:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.NullDemoPage"
Title="x:Null Demo">
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="Label">
<Setter Property="FontSize" Value="48" />
<Setter Property="FontFamily">
<Setter.Value>
<OnPlatform x:TypeArguments="x:String">
<On Platform="iOS" Value="Times New Roman" />
<On Platform="Android" Value="serif" />
<On Platform="UWP" Value="Times New Roman" />
</OnPlatform>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<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.Content>
</ContentPage>
然后你发现,对于其中一个 Label
元素,需要使用隐式 Style
中的所有属性设置,但 FontFamily
除外,你需要将其设置为默认值。 为此,可以另外定义一个 Style
,但更简单的方法是将特定 Label
的 FontFamily
属性设置为 x:Null
,如中间的 Label
所示。
下面是正在运行的程序:
注意,其中四个 Label
元素采用 serif 字体,但中间的 Label
元素采用默认的 sans-serif 字体。
OnPlatform 标记扩展
OnPlatform
标记扩展使你能够基于平台自定义 UI 外观。 它提供的功能与 OnPlatform
和 On
类相同,但表现形式更简洁。
OnPlatform
标记扩展由 OnPlatformExtension
类提供支持,该类定义以下属性:
object
类型的Default
,设置为默认值,以应用于表示平台的属性。object
类型的Android
,设置为在 Android 上应用的值。- 类型为
object
的GTK
,设置为要在 GTK 平台上应用的值。 object
类型为iOS
,设置为在 iOS 上应用的值。- 类型为
object
的macOS
,设置为要在 macOS 上应用的值。 object
类型的Tizen
,设置为在 Tizen 平台上应用的值。- 类型为
object
的UWP
,设置为要在通用 Windows 平台上应用的值。 - 类型为
object
的WPF
,设置为要在 Windows Presentation Foundation 平台上应用的值。 IValueConverter
类型的Converter
,可设置为IValueConverter
实现。object
类型的ConverterParameter
,可设置为传递给IValueConverter
实现的值。
注意
XAML 分析程序允许将 OnPlatformExtension
类缩写为 OnPlatform
。
Default
属性是 OnPlatformExtension
的内容属性。 因此,对于用大括号表示的 XAML 标记表达式,可以删除此类表达式的 Default=
部分(前提是它是第一个参数)。 如果未设置 Default
属性,则默认为 BindableProperty.DefaultValue
属性值,前提是标记扩展名的目标是 BindableProperty
。
重要说明
XAML 分析程序要求将正确类型的值提供给使用 OnPlatform
标记扩展的属性。 如果需要类型转换,OnPlatform
标记扩展将尝试使用 Xamarin.Forms 提供的默认转换器执行该转换。 但是,某些类型转换不能由默认转换器执行,在这些情况下,Converter
属性应设置为 IValueConverter
实现。
OnPlatform Demo 页显示如何使用 OnPlatform
标记扩展:
<BoxView Color="{OnPlatform Yellow, iOS=Red, Android=Green, UWP=Blue}"
WidthRequest="{OnPlatform 250, iOS=200, Android=300, UWP=400}"
HeightRequest="{OnPlatform 250, iOS=200, Android=300, UWP=400}"
HorizontalOptions="Center" />
在此示例中,所有三个 OnPlatform
表达式都使用 OnPlatformExtension
类名的简化版本。 三个 OnPlatform
标记扩展针对 iOS、Android 和 UWP 将 BoxView
的 Color
、WidthRequest
和 HeightRequest
属性设置不同的值。 标记扩展还为未指定平台上的这些属性提供默认值,同时删除表达式的 Default=
部分。 请注意,设置的标记扩展属性用逗号分隔。
下面是正在运行的程序:
OnIdiom 标记扩展
通过 OnIdiom
标记扩展,可以根据运行应用程序的设备的惯用法来自定义 UI 外观。 它受定义以下属性的 OnIdiomExtension
类支持:
object
类型的Default
,设置为要应用于表示设备风格的属性的默认值。object
类型的Phone
,设置为要在手机上应用的值。object
类型的Tablet
,设置为要在平板电脑上应用的值。object
类型的Desktop
,设置为要在桌面平台上应用的值。object
类型的TV
,设置为要在电视平台上应用的值。object
类型的Watch
,设置为要在 Watch 平台上应用的值。IValueConverter
类型的Converter
,可设置为IValueConverter
实现。object
类型的ConverterParameter
,可设置为传递给IValueConverter
实现的值。
注意
XAML 分析程序允许将 OnIdiomExtension
类缩写为 OnIdiom
。
Default
属性是 OnIdiomExtension
的内容属性。 因此,对于用大括号表示的 XAML 标记表达式,可以删除此类表达式的 Default=
部分(前提是它是第一个参数)。
重要说明
XAML 分析程序要求将正确类型的值提供给使用 OnIdiom
标记扩展的属性。 如果需要类型转换,OnIdiom
标记扩展将尝试使用 Xamarin.Forms 提供的默认转换器执行该转换。 但是,某些类型转换不能由默认转换器执行,在这些情况下,Converter
属性应设置为 IValueConverter
实现。
“OnIdiom 演示”页面显示了如何使用 OnIdiom
标记扩展:
<BoxView Color="{OnIdiom Yellow, Phone=Red, Tablet=Green, Desktop=Blue}"
WidthRequest="{OnIdiom 100, Phone=200, Tablet=300, Desktop=400}"
HeightRequest="{OnIdiom 100, Phone=200, Tablet=300, Desktop=400}"
HorizontalOptions="Center" />
在此示例中,所有三个 OnIdiom
表达式都使用 OnIdiomExtension
类名的简化版本。 这三个 OnIdiom
标记扩展会在手机、平板电脑和桌面惯例中将 BoxView
的 Color
、WidthRequest
和 HeightRequest
属性设置为不同的值。 标记扩展还为未指定惯例中的这些属性提供默认值,同时删除表达式的 Default=
部分。 请注意,设置的标记扩展属性用逗号分隔。
下面是正在运行的程序:
DataTemplate 标记扩展
通过 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 应用程序的详细信息,请参阅 Xamarin.Forms Shell。
FontImage 标记扩展
FontImage
标记扩展支持在任何可以显示 ImageSource
的视图中显示字体图标。 它提供与 FontImageSource
类相同的功能,但具有更简洁的表示形式。
FontImage
标记扩展由 FontImageExtension
类提供支持,该类定义以下属性:
FontFamily
,类型为string
,是字体图标所属的字体系列。Glyph
,类型为string
,是字体图标的 unicode 字符值。Color
,类型为Color
,是显示字体图标时要使用的颜色。Size
,类型为double
,是呈现字体图标的大小(使用设备无关单位)。 默认值为 30。 此外,可以将此属性设置为命名字体大小。
注意
XAML 分析程序允许将 FontImageExtension
类缩写为 FontImage
。
Glyph
属性是 FontImageExtension
的内容属性。 因此,对于用大括号表示的 XAML 标记表达式,可以删除此类表达式的 Glyph=
部分(前提是它是第一个参数)。
“FontImage 演示”页面显示了如何使用 FontImage
标记扩展:
<Image BackgroundColor="#D1D1D1"
Source="{FontImage , FontFamily={OnPlatform iOS=Ionicons, Android=ionicons.ttf#}, Size=44}" />
在本例中,FontImageExtension
类名的缩写版本用于在 Image
中显示来自 Ionicons 字体系列的 XBox 图标。 表达式还使用 OnPlatform
标记扩展在 iOS 和 Android 上指定不同的 FontFamily
属性值。 此外,表达式的 Glyph=
部分会被消除,设置的标记扩展属性用逗号分隔。 注意,虽然图标的 unicode 字符是 \uf30c
,但它必须在 XAML 中转义,因此变为 
。
下面是正在运行的程序:
有关通过在 FontImageSource
对象中指定字体图标数据来显示字体图标的信息,请参阅显示字体图标。
AppThemeBinding 标记扩展
AppThemeBinding
标记扩展使你能够根据当前系统主题指定要使用的资源,例如图像或颜色。
重要
AppThemeBinding
标记扩展具有最低操作系统要求。 有关详细信息,请参见响应 Xamarin.Forms 应用程序中的系统主题更改。
AppThemeBinding
标记扩展由 AppThemeBindingExtension
类提供支持,该类定义以下属性:
Default
,类型为object
,用户所设置的默认使用的资源。Light
,类型为object
,用户所设置的在设备使用其浅色主题时要使用的资源。Dark
,类型为object
,用户所设置的在设备使用其深色主题时要使用的资源。Value
,类型为object
,可返回标记扩展当前使用的资源。
注意
XAML 分析程序允许将 AppThemeBindingExtension
类缩写为 AppBindingTheme
。
Default
属性是 AppThemeBindingExtension
的内容属性。 因此,对于用大括号表示的 XAML 标记表达式,可以删除此类表达式的 Default=
部分(前提是它是第一个参数)。
“AppThemeBinding 演示”页面显示了如何使用 AppThemeBinding
标记扩展:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.AppThemeBindingDemoPage"
Title="AppThemeBinding Demo">
<ContentPage.Resources>
<Style x:Key="labelStyle"
TargetType="Label">
<Setter Property="TextColor"
Value="{AppThemeBinding Black, Light=Blue, Dark=Teal}" />
</Style>
</ContentPage.Resources>
<StackLayout Margin="20">
<Label Text="This text is green in light mode, and red in dark mode."
TextColor="{AppThemeBinding Light=Green, Dark=Red}" />
<Label Text="This text is black by default, blue in light mode, and teal in dark mode."
Style="{StaticResource labelStyle}" />
</StackLayout>
</ContentPage>
在此示例中,当设备使用其浅色主题时,Label
的文本颜色被设置为绿色,当设备使用其深色主题时,文本颜色被设置为红色。 第二个 Label
通过 Style
设置其 TextColor
属性。 默认情况下,此 Style
将 Label
的文本颜色设置为黑色,当设备使用浅色主题时设置为蓝色,在设备使用深色主题时设置为青色。
下面是正在运行的程序:
定义标记扩展
如果需要的 XAML 标记扩展在 Xamarin.Forms 中不可用,则可以创建自己的标记扩展。