Xamarin.Forms 样式简介
可以通过样式来自定义视觉对象元素的外观。 样式针对特定类型进行定义,它包含该类型上可用属性的值。
Xamarin.Forms 应用程序通常包含多个具有相同外观的控件。 例如,应用程序可能有多个具有相同字体选项和布局选项的 Label
实例,如以下 XAML 代码示例所示:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Styles.NoStylesPage"
Title="No Styles"
IconImageSource="xaml.png">
<ContentPage.Content>
<StackLayout Padding="0,20,0,0">
<Label Text="These labels"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
FontSize="Large" />
<Label Text="are not"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
FontSize="Large" />
<Label Text="using styles"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
FontSize="Large" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
以下代码示例演示了在 C# 中创建的等效页:
public class NoStylesPageCS : ContentPage
{
public NoStylesPageCS ()
{
Title = "No Styles";
IconImageSource = "csharp.png";
Padding = new Thickness (0, 20, 0, 0);
Content = new StackLayout {
Children = {
new Label {
Text = "These labels",
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.CenterAndExpand,
FontSize = Device.GetNamedSize (NamedSize.Large, typeof(Label))
},
new Label {
Text = "are not",
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.CenterAndExpand,
FontSize = Device.GetNamedSize (NamedSize.Large, typeof(Label))
},
new Label {
Text = "using styles",
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.CenterAndExpand,
FontSize = Device.GetNamedSize (NamedSize.Large, typeof(Label))
}
}
};
}
}
每个 Label
实例都有相同的属性值,用于控制通过 Label
显示的文本的外观。 这会导致如以下屏幕截图中所示的外观:
设置每个单独控件的外观可能是重复性的操作,容易出错。 相反,可以创建用于定义外观的样式,然后将其应用于所需控件。
创建样式
Style
类将属性值的集合分组到一个对象中,然后可以将该对象应用于多个视觉对象元素实例。 这有助于减少重复标记,可以更轻松地更改应用程序的外观。
尽管样式主要是为基于 XAML 的应用程序设计的,但它们也可以在 C# 中创建:
- 在 XAML 中创建的
Style
实例通常在分配给控件、页面的Resources
集合或应用程序的Resources
集合的ResourceDictionary
中定义。 - 在 C# 中创建的
Style
实例通常在页面的类中定义,或者在可以进行全局访问的类中定义。
选择在何处定义 Style
会影响其应用范围:
每个 Style
实例都包含一个或多个 Setter
对象的集合,其中每个 Setter
都具有 Property
和 Value
。 Property
是应用样式的元素的可绑定属性的名称,而 Value
是应用于属性的值。
每个 Style
实例都可以是显式的或隐式的:
- 通过指定值
TargetType
和x:Key
值以及将目标元素Style
的属性设置为x:Key
引用来定义显式Style
实例。 有关显式样式的详细信息,请参阅显式样式。 - 通过仅指定一个
TargetType
隐式实例来定义隐式Style
实例。Style
实例随后将自动应用于该类型的所有元素。 请注意,TargetType
的子类不会自动应用Style
。 有关隐式样式的详细信息,请参阅隐式样式。
创建 Style
时,始终需要 TargetType
属性。 以下代码示例显示了在 XAML 中创建的显式样式(请注意 x:Key
):
<Style x:Key="labelStyle" TargetType="Label">
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="VerticalOptions" Value="CenterAndExpand" />
<Setter Property="FontSize" Value="Large" />
</Style>
若要应用 Style
,目标对象必须是与 Style
的 TargetType
属性值匹配的 VisualElement
,如以下 XAML 代码示例所示:
<Label Text="Demonstrating an explicit style" Style="{StaticResource labelStyle}" />
视图层次结构中等级较低的样式优先于定义为较高等级的样式。 例如,在应用程序级别设置一个将 Label.TextColor
设置为 Red
的 Style
时,该操作会被将 Label.TextColor
设置为 Green
的页面级别样式覆盖。 同样,页面级别样式会被控件级别样式覆盖。 此外,如果直接在控件属性上设置 Label.TextColor
,则其优先于任何样式。
本部分的文章演示并解释了如何创建和应用显式和隐式样式、如何创建全局样式、样式继承、如何在运行时响应样式更改,以及如何使用 Xamarin.Forms 中包含的内置样式。
注意
什么是 StyleId?
在 Xamarin.Forms 2.2 之前,StyleId
属性用于识别应用程序中的各个元素,以便在 UI 测试和主题引擎(例如 Pixate)中进行识别。 不过,Xamarin.Forms 2.2 引入了 AutomationId
属性,它取代了 StyleId
属性。