第12章 样式(三)

样式继承

Style的TargetType提供两种不同的功能:下一节隐式样式中描述了其中一种功能。 另一个函数是为了XAML解析器的好处。 XAML解析器必须能够解析Setter对象中的属性名称,并且为此需要TargetType提供的类名。
样式中的所有属性必须由Target?Type属性中指定的类定义或继承。 设置Style的可视元素的类型必须与TargetType或TargetType的派生类相同。
如果只需要为View定义的属性设置样式,则可以将TargetType设置为View,并仍然使用按钮上的样式或任何其他View派生,如在BasicStyle程序的此修改版本中:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="BasicStyle.BasicStylePage">
 
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="viewStyle" TargetType="View">
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
                 <Setter Property="BackgroundColor" Value="Pink" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout>
        <Button Text=" Carpe diem "
                Style="{StaticResource viewStyle}" />
        <Label Text ="A bit of text"
               Style="{StaticResource viewStyle}" />
 
        <Button Text=" Sapere aude "
                Style="{StaticResource viewStyle}" />
        <Label Text ="Another bit of text"
               Style="{StaticResource viewStyle}" />
        <Button Text=" Discere faciendo "
                Style="{StaticResource viewStyle}" />
    </StackLayout>
</ContentPage>

如您所见,相同的样式应用于StackLayout的所有Button和Label子项:
201808091953590364
但是假设你现在想要扩展这种风格,但对于Button和Label则不同。那可能吗?
是的。样式可以源自其他样式。 Style类包含一个名为BasedOn的属性Style。在代码中,您可以将此BasedOn属性直接设置为另一个Style对象。在XAML中,将BasedOn属性设置为引用先前创建的样式的StaticResource标记扩展。新样式可以包含新属性的Setter对象,或者使用它们覆盖早期样式中的属性。 BasedOn样式必须以新样式TargetType的相同类或祖先类为目标。
这是名为StyleInheritance的项目的XAML文件。该应用程序有两个目的引用Xamarin.FormsBook.Toolkit程序集:它使用HslColor标记扩展来证明标记扩展是Setter对象中的合法值设置,并且可以证明可以为自定义类定义样式,在这种情况下AltLabel。
ResourceDictionary包含四种样式:第一种具有“visualStyle”的字典键。带有“baseStyle”字典键的Style来自“visualStyle”。带有“la?belStyle”和“buttonStyle”键的样式来自“baseStyle”:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:toolkit=
                 "clr-namespace:Xamarin.FormsBook.Toolkit;assembly=Xamarin.FormsBook.Toolkit"
             x:Class="StyleInheritance.StyleInheritancePage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="visualStyle" TargetType="VisualElement">
                <Setter Property="BackgroundColor"
                        Value="{toolkit:HslColor H=0, S=1, L=0.8}" />
            </Style>
            <Style x:Key="baseStyle" TargetType="View"
                   BasedOn="{StaticResource visualStyle}">
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
            </Style>
            <Style x:Key="labelStyle" TargetType="toolkit:AltLabel"
                   BasedOn="{StaticResource baseStyle}">
                <Setter Property="TextColor" Value="Black" />
                <Setter Property="PointSize" Value="12" />
            </Style>
            <Style x:Key="buttonStyle" TargetType="Button"
                   BasedOn="{StaticResource baseStyle}">
                <Setter Property="TextColor" Value="Blue" />
                <Setter Property="FontSize" Value="Large" />
                <Setter Property="BorderColor" Value="Blue" />
                <Setter Property="BorderWidth" Value="2" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Style>
        <StaticResourceExtension Key="visualStyle" />
    </ContentPage.Style>
    <StackLayout>
        <Button Text=" Carpe diem "
                Style="{StaticResource buttonStyle}" />
        <toolkit:AltLabel Text ="A bit of text"
                          Style="{StaticResource labelStyle}" />
        <Button Text=" Sapere aude "
                Style="{StaticResource buttonStyle}" />
        <toolkit:AltLabel Text ="Another bit of text"
                          Style="{StaticResource labelStyle}" />
        <Button Text=" Discere faciendo "
                Style="{StaticResource buttonStyle}" />
    </StackLayout>
</ContentPage>

在参考资源部分之后,立即将页面本身的Style属性设置为“visualStyle”样式:

<ContentPage.Style>
    <StaticResourceExtension Key="visualStyle" />
</ContentPage.Style>

因为Page派生自VisualElement而不是View,所以这是可以应用于页面的资源词典中的唯一样式。 但是,在Re?sources部分之后才能将样式应用于页面,因此使用StaticResource的元素形式是一个很好的解决方案。 页面的整个背景基于此样式着色,并且样式也由所有其他样式继承:201808091956360365
如果AltLabel的样式仅包含Label定义的属性的Setter对象,则TargetType可以是Label而不是AltLabel。但Style具有PointSize属性的Setter。该属性由AltLabel定义,因此TargetType必须是toolkit:AltLabel。
可以为PointSize属性定义Setter,因为PointSize由可绑定属性支持。如果将AltLabel中BindableProperty对象的可访问性从公共更改为私有,则该属性仍可用于AltLabel的许多常规用法,但现在PointSize可以不在样式Setter中设置。 XAML解析器会抱怨它无法找到PointSizeProperty,它是支持PointSize属性的可绑定属性。
您在第10章中发现了StaticResource的工作原理:当XAML解析器遇到StaticResource标记扩展时,它会在可视化树中搜索匹配的字典键。这个过程对风格有影响。您可以在一个“资源”部分中定义样式,然后使用可视树中较低的“资源”部分中具有相同字典键的另一个样式覆盖该样式。将BasedOn属性设置为StaticResource标记扩展时,必须在相同的Resources部分(如StyleInheritance程序中演示)或可视树中较高的Resources部分中定义您派生的样式。
这意味着您可以使用两种分层方式在XAML中构建样式:您可以使用BasedOn从其他样式派生样式,并且可以在可视树中的不同级别定义样式,这些样式派生自可视树中较高的样式或替换它们完全。
对于具有多个页面和大量标记的大型应用程序,定义样式的建议非常简单 - 将样式定义为尽可能接近使用这些样式的元素。
遵循此建议有助于维护程序,并在使用隐式样式时变得特别重要。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值