Xamarin.Forms 中的隐式样式

隐式样式是同一 TargetType 的所有控件使用的样式,无需每个控件引用样式。

在 XAML 中创建隐式样式

若要在页面级别声明 Style,必须将 ResourceDictionary 添加到页面,之后可将一个或多个 Style 声明包含在 ResourceDictionary 中。 通过不指定 x:Key 特性的方式隐式表示 Style。 然后会将该样式应用于与 TargetType 完全匹配的视觉元素,而不是应用于从 TargetType 值派生的元素。

下面的代码示例显示在页面的 ResourceDictionary 中用 XAML 声明的并应用于页面的 Entry 实例的隐式样式:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:Styles;assembly=Styles" x:Class="Styles.ImplicitStylesPage" Title="Implicit" IconImageSource="xaml.png">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Entry">
                <Setter Property="HorizontalOptions" Value="Fill" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
                <Setter Property="BackgroundColor" Value="Yellow" />
                <Setter Property="FontAttributes" Value="Italic" />
                <Setter Property="TextColor" Value="Blue" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>
        <StackLayout Padding="0,20,0,0">
            <Entry Text="These entries" />
            <Entry Text="are demonstrating" />
            <Entry Text="implicit styles," />
            <Entry Text="and an implicit style override" BackgroundColor="Lime" TextColor="Red" />
            <local:CustomEntry Text="Subclassed Entry is not receiving the style" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

ResourceDictionary 定义应用于页面的 Entry 实例的单个隐式样式。 Style 用于在黄色背景上显示蓝色文本,同时还设置其他外观选项。 在无需指定 x:Key 特性的情况下,将 Style 添加到页面的 ResourceDictionary 中。 因此,Style 将隐式应用于所有 Entry 实例,因为它们与 StyleTargetType 属性完全匹配。 但是,Style 不应用于 CustomEntry 实例,该实例是子类化的 Entry。 这会导致如以下屏幕截图中所示的外观:

隐式样式示例

此外,第四个 Entry 将隐式样式的 BackgroundColorTextColor 属性重写为其他 Color 值。

在控件级别创建隐式样式

除了在页面级别上创建隐式样式外,还可以在控件级别上创建它们,如下面的代码示例所示:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:Styles;assembly=Styles" x:Class="Styles.ImplicitStylesPage" Title="Implicit" IconImageSource="xaml.png">
    <ContentPage.Content>
        <StackLayout Padding="0,20,0,0">
            <StackLayout.Resources>
                <ResourceDictionary>
                    <Style TargetType="Entry">
                        <Setter Property="HorizontalOptions" Value="Fill" />
                        ...
                    </Style>
                </ResourceDictionary>
            </StackLayout.Resources>
            <Entry Text="These entries" />
            ...
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

在此示例中,隐式Style分配给了 StackLayout 控件的 Resources 集合。 然后可以将隐式样式应用于该控件及其子级。

有关在应用程序的 ResourceDictionary 中创建样式的信息,请参阅全局样式

在 C 中创建隐式样式#

可以通过创建新的 ResourceDictionary 然后将 Style 实例添加到 ResourceDictionary,将 Style 实例添加到 C# 中页面的 Resources 集合,如以下代码示例所示:

public class ImplicitStylesPageCS : ContentPage
{
    public ImplicitStylesPageCS ()
    {
        var entryStyle = new Style (typeof(Entry)) {
            Setters = {
                ...
                new Setter { Property = Entry.TextColorProperty, Value = Color.Blue }
            }
        };

        ...
        Resources = new ResourceDictionary ();
        Resources.Add (entryStyle);

        Content = new StackLayout {
            Children = {
                new Entry { Text = "These entries" },
                new Entry { Text = "are demonstrating" },
                new Entry { Text = "implicit styles," },
                new Entry { Text = "and an implicit style override", BackgroundColor = Color.Lime, TextColor = Color.Red },
                new CustomEntry  { Text = "Subclassed Entry is not receiving the style" }
            }
        };
    }
}

构造函数定义应用于页面的 Entry 实例的单个隐式样式。 Style 用于在黄色背景上显示蓝色文本,同时还设置其他外观选项。 会将 Style 添加到页面的 ResourceDictionary 中,而无需指定 key 字符串。 因此,Style 将隐式应用于所有 Entry 实例,因为它们与 StyleTargetType 属性完全匹配。 但是,Style 不应用于 CustomEntry 实例,该实例是子类化的 Entry

将样式应用于派生类型

Style.ApplyToDerivedTypes 属性支持将样式应用于派生自 TargetType 属性引用的基类型的控件。 因此,如果类型派生自 TargetType 属性中指定的基类型,则将此属性设置为 true 可使单个样式面向多个类型。

以下示例显示将 Button 实例的背景色设置为红色的隐式样式:

<Style TargetType="Button"
       ApplyToDerivedTypes="True">
    <Setter Property="BackgroundColor"
            Value="Red" />
</Style>

将此样式置于页面级 ResourceDictionary 会使其应用于页面上的所有 Button 实例,同时应用于派生自 Button 的任何控件。 但是,如果 ApplyToDerivedTypes 属性保持未设置状态,则该样式将仅应用于 Button 实例。

等效 C# 代码如下:

var buttonStyle = new Style(typeof(Button))
{
    ApplyToDerivedTypes = true,
    Setters =
    {
        new Setter
        {
            Property = VisualElement.BackgroundColorProperty,
            Value = Color.Red
        }
    }
};

Resources = new ResourceDictionary { buttonStyle };