第12章 样式(五)

简介:

动态样式

Style通常是一个静态对象,它在XAML或代码中创建和初始化,然后在应用程序的持续时间内保持不变。 Style类不是从BindableOb?ject派生的,也不在内部响应其属性的变化。 例如,如果将Style对象分配给元素,然后通过为其设置新值来修改其中一个Setter对象,则新值将不会显示在元素中。 同样,如果添加Setter或从Setters集合中删除Setter,则target元素不会更改。 要使这些新属性设置器生效,您需要使用代码通过将Style属性设置为null来将该样式与该元素分离,然后将该样式重新附加到该元素。
但是,您的应用程序可以通过使用DynamicResource在运行时动态响应样式更改。您会记得DynamicResource类似于StaticResource,因为它使用字典键从资源字典中获取对象或值。不同之处在于Static?Resource是一次性字典查找,而DynamicResource维护到实际字干键的链接。如果与该键关联的词典条目被替换为新对象,则该更改为
传播到元素。
此工具允许应用程序实现有时称为动态样式的功能。例如,您可以在程序中包含一个用于样式主题的设施(涉及字体和颜色,每个人),您可以使这些主题可由用户选择。应用程序可以在这些主题之间切换,因为它们是使用样式实现的。
样式本身没有任何东西表明动态风格。样式仅通过使用DynamicResource而不是StaticResource引用而变为动态。
DynamicStyles项目演示了此过程的机制。这是DynamicStylesPage类的XAML文件:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DynamicStyles.DynamicStylesPage">
    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness"
                    iOS="0, 20, 0, 0"
                    Android="0"
                    WinPhone="0" />
    </ContentPage.Padding>
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="baseButtonStyle" TargetType="Button">
                <Setter Property="FontSize" Value="Large" />
            </Style>
 
            <Style x:Key="buttonStyle1" TargetType="Button"
                   BasedOn="{StaticResource baseButtonStyle}">
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
                <Setter Property="TextColor" Value="Red" />
            </Style>
            <Style x:Key="buttonStyle2" TargetType="Button"
                   BasedOn="{StaticResource baseButtonStyle}">
                <Setter Property="HorizontalOptions" Value="Start" />
                <Setter Property="VerticalOptions" Value="EndAndExpand" />
                <Setter Property="TextColor" Value="Green" />
                <Setter Property="FontAttributes" Value="Italic" />
            </Style>
            <Style x:Key="buttonStyle3" TargetType="Button"
                   BasedOn="{StaticResource baseButtonStyle}">
                <Setter Property="HorizontalOptions" Value="End" />
                <Setter Property="VerticalOptions" Value="StartAndExpand" />
                <Setter Property="TextColor" Value="Blue" />
                <Setter Property="FontAttributes" Value="Bold" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout>
        <Button Text=" Switch to Style #1 "
                Style="{DynamicResource buttonStyle}"
                Clicked="OnButton1Clicked" />
        <Button Text=" Switch to Style #2 "
                Style="{DynamicResource buttonStyle}"
                Clicked="OnButton2Clicked" />
 
        <Button Text=" Switch to Style #3 "
                Style="{DynamicResource buttonStyle}"
                Clicked="OnButton3Clicked" />
        <Button Text=" Reset "
                Style="{DynamicResource buttonStyle}"
                Clicked="OnResetButtonClicked" />
    </StackLayout> 
</ContentPage>

参考资料部分定义了四种样式:一个简单的样式,键为“baseButtonStyle”,然后是三个样式,派生自该样式,键为“buttonStyle1”,“buttonStyle2”和“buttonStyle3”。
但是,XAML文件底部的四个Button元素都使用DynamicResource来引用具有更简单键“buttonStyle”的样式。 带有那把钥匙的Style在哪里? 它不存在。 但是,因为使用DynamicResource设置了四个按钮样式属性,所以缺少的字典键不是问题。 没有例外。 但是没有应用Style,这意味着按钮具有默认外观:
201808112127010368
四个Button元素中的每一个都附加了一个Clicked处理程序,并且在代码隐藏文件中,前三个处理程序将一个字典条目与键“buttonStyle”设置为已在字典中定义的三个编号样式之一:

public partial class DynamicStylesPage : ContentPage
{
    public DynamicStylesPage()
    {
        InitializeComponent();
    }
    void OnButton1Clicked(object sender, EventArgs args)
    {
        Resources["buttonStyle"] = Resources["buttonStyle1"];
    }
    void OnButton2Clicked(object sender, EventArgs args)
    {
        Resources["buttonStyle"] = Resources["buttonStyle2"];
    }
    void OnButton3Clicked(object sender, EventArgs args)
    {
        Resources["buttonStyle"] = Resources["buttonStyle3"];
    }
    void OnResetButtonClicked(object sender, EventArgs args)
    {
        Resources["buttonStyle"] = null;
    }
}

按下前三个按钮之一时,所有四个按钮都将获得所选样式。 这是在所有三个平台上运行的程序,显示按下按钮1,2和3时的结果(从左到右):
201808112131030369
按第四个按钮可将所有与“buttonStyle”键相关联的值设置为null,从而将所有内容返回到初始条件。 (您可能还会考虑在Re?sourceDictionary对象上调用Remove或Clear来完全删除密钥,但这在本章使用的Xama?rin.Forms版本中不起作用。)
假设您要使用键“buttonStyle”从样式派生另一个样式。 考虑到在按下前三个按钮之一后“buttonStyle”字典条目不存在,你如何在XAML中执行此操作?
你不能这样做:

<!-- This won't work! -->
<Style x:Key="newButtonStyle" TargetType="Button"
       BasedOn="{StaticResource buttonStyle}">
    __
</Style>

如果“buttonStyle”键不存在,StaticResource将引发异常,即使密钥确实存在,StaticResource的使用也不允许字典条目中的更改反映在此新样式中。
但是,将StaticResource更改为DynamicResource也不起作用:

<!-- This won't work either! -->
<Style x:Key="newButtonStyle" TargetType="Button"
       BasedOn="{DynamicResource buttonStyle}">
    __
</Style>

DynamicResource仅适用于可绑定属性支持的属性,而这不是这种情况。 Style不是从BindableObject派生的,因此它不支持可绑定属性。
相反,Style定义了一个专门用于继承动态样式的属性。 该属性是BaseResourceKey,它旨在直接设置为可能尚不存在或其值可能动态更改的字典键,“buttonStyle”键就是这种情况:

<!-- This works!! -->
<Style x:Key="newButtonStyle" TargetType="Button"
       BaseResourceKey="buttonStyle">
    __
</Style>

DynamicStylesInheritance项目演示了BaseResourceKey的使用,它与DynamicStyles项目非常相似。 实际上,代码隐藏处理是相同的。 在Resources部分的底部,使用“newButtonStyle”键定义一个新Style,它使用BaseResourceKey引用“buttonStyle”条目并添加一些属性,包括使用OnPlatform的属性:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DynamicStylesInheritance.DynamicStylesInheritancePage">
    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness"
                    iOS="0, 20, 0, 0"
                    Android="0"
                    WinPhone="0" />
    </ContentPage.Padding>
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="baseButtonStyle" TargetType="Button">
                <Setter Property="FontSize" Value="Large" />
            </Style>
            <Style x:Key="buttonStyle1" TargetType="Button"
                   BasedOn="{StaticResource baseButtonStyle}">
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
                <Setter Property="TextColor" Value="Red" />
            </Style>
            <Style x:Key="buttonStyle2" TargetType="Button"
                   BasedOn="{StaticResource baseButtonStyle}">
                <Setter Property="HorizontalOptions" Value="Start" />
                <Setter Property="VerticalOptions" Value="EndAndExpand" />
                <Setter Property="TextColor" Value="Green" />
                <Setter Property="FontAttributes" Value="Italic" />
            </Style>
            <Style x:Key="buttonStyle3" TargetType="Button"
                   BasedOn="{StaticResource baseButtonStyle}">
                <Setter Property="HorizontalOptions" Value="End" />
                <Setter Property="VerticalOptions" Value="StartAndExpand" />
                <Setter Property="TextColor" Value="Blue" />
                <Setter Property="FontAttributes" Value="Bold" />
            </Style>
            <!-- New style definition. -->
            <Style x:Key="newButtonStyle" TargetType="Button"
                   BaseResourceKey="buttonStyle">
                <Setter Property="BackgroundColor">
                    <Setter.Value>
                        <OnPlatform x:TypeArguments="Color"
                                    iOS="#C0C0C0"
                                    Android="#404040"
                                    WinPhone="Gray" />
                    </Setter.Value>
                </Setter>
                <Setter Property="BorderColor" Value="Red" />
                <Setter Property="BorderWidth" Value="3" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout>
        <Button Text=" Switch to Style #1 "
                Style="{StaticResource newButtonStyle}"
                Clicked="OnButton1Clicked" />
        <Button Text=" Switch to Style #2 "
                Style="{StaticResource newButtonStyle}"
                Clicked="OnButton2Clicked" />
        <Button Text=" Switch to Style #3 "
                Style="{StaticResource newButtonStyle}"
                Clicked="OnButton3Clicked" />
        <Button Text=" Reset "
                Style="{DynamicResource buttonStyle}"
                Clicked="OnResetButtonClicked" />
    </StackLayout>
</ContentPage>

请注意,前三个Button元素引用带有StaticResource的“newButtonStyle”字典条目。 这里不需要DynamicResource,因为与“newButtonStyle”关联的Style对象本身不会改变,除了它派生的Style。 具有键“newButtonStyle”的Style保持与“buttonStyle”的链接,并在该un-derlying样式发生变化时在内部改变。 当程序开始运行时,只有“newButtonStyle”中定义的属性才会应用于这三个按钮:
201808112151310370
“重置”按钮继续引用“buttonStyle”条目。
与DynamicStyles程序一样,代码隐藏文件在您单击前三个按钮之一时设置该字典条目,因此所有按钮也会选择“buttonStyle”属性。 以下是按钮3,2和1的(从左到右)点击的结果:
201808112152460371

目录
相关文章
|
1月前
|
缓存 前端开发
样式
样式
21 3
|
3月前
|
前端开发
|
4天前
|
前端开发
css 字体渐变样式(设置字体渐变样式+附加实现源码)
css 字体渐变样式(设置字体渐变样式+附加实现源码)
7 0
|
8月前
|
前端开发
CSS样式设置颜色
做前端页面必备知识
|
前端开发
CSS边框样式详解
border-color属性用于定义边框的颜色 简写形式: 想要为一个元素定义边框,我们需要完整地给出border-width、border-style和bordercolor。这种写法代码量过多,费时费力。不过CSS为我们提供了一种简写形式
98 0
CSS边框样式详解
9、CSS3新增样式(边框圆角、阴影、形变)
9、CSS3新增样式(边框圆角、阴影、形变)
100 0
9、CSS3新增样式(边框圆角、阴影、形变)
|
前端开发
常用样式
常用样式
101 0
|
Web App开发 前端开发
如何自定义CSS滚动条的样式?
原文:如何自定义CSS滚动条的样式? 欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由前端林子发表 本文会介绍CSS滚动条选择器,并在demo中展示如何在Webkit内核浏览器和IE浏览器中,自定义一个横向以及一个纵向的滚动条。
1199 0
|
Android开发
第12章 样式(六)
设备样式 Xamarin.Forms包含六种内置动态样式。 这些被称为设备样式,它们是名为Styles的嵌套类的成员。 这个Styles类定义了12个静态和只读字段,有助于在代码中引用这六个样式: Style样式的BodyStyle。
1228 0

热门文章

最新文章