Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6642634
  • 博文数量: 915
  • 博客积分: 17977
  • 博客等级: 上将
  • 技术积分: 8846
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-26 09:59
个人简介

一个好老好老的老程序员了。

文章分类

全部博文(915)

文章存档

2022年(9)

2021年(13)

2020年(10)

2019年(40)

2018年(88)

2017年(130)

2015年(5)

2014年(12)

2013年(41)

2012年(36)

2011年(272)

2010年(1)

2009年(53)

2008年(65)

2007年(47)

2006年(81)

2005年(12)

分类: Android平台

2018-08-11 22:00:46

动态样式

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

点击(此处)折叠或打开

  1. <ContentPage xmlns=""
  2.              xmlns:x=""
  3.              x:Class="DynamicStyles.DynamicStylesPage">
  4.     <ContentPage.Padding>
  5.         <OnPlatform x:TypeArguments="Thickness"
  6.                     iOS="0, 20, 0, 0"
  7.                     Android="0"
  8.                     WinPhone="0" />
  9.     </ContentPage.Padding>
  10.     <ContentPage.Resources>
  11.         <ResourceDictionary>
  12.             <Style x:Key="baseButtonStyle" TargetType="Button">
  13.                 <Setter Property="FontSize" Value="Large" />
  14.             </Style>
  15.  
  16.             <Style x:Key="buttonStyle1" TargetType="Button"
  17.                    BasedOn="{StaticResource baseButtonStyle}">
  18.                 <Setter Property="HorizontalOptions" Value="Center" />
  19.                 <Setter Property="VerticalOptions" Value="CenterAndExpand" />
  20.                 <Setter Property="TextColor" Value="Red" />
  21.             </Style>
  22.             <Style x:Key="buttonStyle2" TargetType="Button"
  23.                    BasedOn="{StaticResource baseButtonStyle}">
  24.                 <Setter Property="HorizontalOptions" Value="Start" />
  25.                 <Setter Property="VerticalOptions" Value="EndAndExpand" />
  26.                 <Setter Property="TextColor" Value="Green" />
  27.                 <Setter Property="FontAttributes" Value="Italic" />
  28.             </Style>
  29.             <Style x:Key="buttonStyle3" TargetType="Button"
  30.                    BasedOn="{StaticResource baseButtonStyle}">
  31.                 <Setter Property="HorizontalOptions" Value="End" />
  32.                 <Setter Property="VerticalOptions" Value="StartAndExpand" />
  33.                 <Setter Property="TextColor" Value="Blue" />
  34.                 <Setter Property="FontAttributes" Value="Bold" />
  35.             </Style>
  36.         </ResourceDictionary>
  37.     </ContentPage.Resources>
  38.     <StackLayout>
  39.         <Button Text=" Switch to Style #1 "
  40.                 Style="{DynamicResource buttonStyle}"
  41.                 Clicked="OnButton1Clicked" />
  42.         <Button Text=" Switch to Style #2 "
  43.                 Style="{DynamicResource buttonStyle}"
  44.                 Clicked="OnButton2Clicked" />
  45.  
  46.         <Button Text=" Switch to Style #3 "
  47.                 Style="{DynamicResource buttonStyle}"
  48.                 Clicked="OnButton3Clicked" />
  49.         <Button Text=" Reset "
  50.                 Style="{DynamicResource buttonStyle}"
  51.                 Clicked="OnResetButtonClicked" />
  52.     </StackLayout>
  53. </ContentPage>

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

点击(此处)折叠或打开

  1. public partial class DynamicStylesPage : ContentPage
  2. {
  3.     public DynamicStylesPage()
  4.     {
  5.         InitializeComponent();
  6.     }
  7.     void OnButton1Clicked(object sender, EventArgs args)
  8.     {
  9.         Resources["buttonStyle"] = Resources["buttonStyle1"];
  10.     }
  11.     void OnButton2Clicked(object sender, EventArgs args)
  12.     {
  13.         Resources["buttonStyle"] = Resources["buttonStyle2"];
  14.     }
  15.     void OnButton3Clicked(object sender, EventArgs args)
  16.     {
  17.         Resources["buttonStyle"] = Resources["buttonStyle3"];
  18.     }
  19.     void OnResetButtonClicked(object sender, EventArgs args)
  20.     {
  21.         Resources["buttonStyle"] = null;
  22.     }
  23. }

按下前三个按钮之一时,所有四个按钮都将获得所选样式。 这是在所有三个平台上运行的程序,显示按下按钮1,2和3时的结果(从左到右):

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

点击(此处)折叠或打开

  1. <Style x:Key="newButtonStyle" TargetType="Button"
  2.        BasedOn="{StaticResource buttonStyle}">
  3.     ...
  4. </Style>
如果“buttonStyle”键不存在,StaticResource将引发异常,即使密钥确实存在,StaticResource的使用也不允许字典条目中的更改反映在此新样式中。
但是,将StaticResource更改为DynamicResource也不起作用:

点击(此处)折叠或打开

  1. <Style x:Key="newButtonStyle" TargetType="Button"
  2.        BasedOn="{DynamicResource buttonStyle}">
  3.     ...
  4. </Style>
DynamicResource仅适用于可绑定属性支持的属性,而这不是这种情况。 Style不是从BindableObject派生的,因此它不支持可绑定属性。
相反,Style定义了一个专门用于继承动态样式的属性。 该属性是BaseResourceKey,它旨在直接设置为可能尚不存在或其值可能动态更改的字典键,“buttonStyle”键就是这种情况:

点击(此处)折叠或打开

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

点击(此处)折叠或打开

  1. <ContentPage xmlns=""
  2.              xmlns:x=""
  3.              x:Class="DynamicStylesInheritance.DynamicStylesInheritancePage">
  4.     <ContentPage.Padding>
  5.         <OnPlatform x:TypeArguments="Thickness"
  6.                     iOS="0, 20, 0, 0"
  7.                     Android="0"
  8.                     WinPhone="0" />
  9.     </ContentPage.Padding>
  10.     <ContentPage.Resources>
  11.         <ResourceDictionary>
  12.             <Style x:Key="baseButtonStyle" TargetType="Button">
  13.                 <Setter Property="FontSize" Value="Large" />
  14.             </Style>
  15.             <Style x:Key="buttonStyle1" TargetType="Button"
  16.                    BasedOn="{StaticResource baseButtonStyle}">
  17.                 <Setter Property="HorizontalOptions" Value="Center" />
  18.                 <Setter Property="VerticalOptions" Value="CenterAndExpand" />
  19.                 <Setter Property="TextColor" Value="Red" />
  20.             </Style>
  21.             <Style x:Key="buttonStyle2" TargetType="Button"
  22.                    BasedOn="{StaticResource baseButtonStyle}">
  23.                 <Setter Property="HorizontalOptions" Value="Start" />
  24.                 <Setter Property="VerticalOptions" Value="EndAndExpand" />
  25.                 <Setter Property="TextColor" Value="Green" />
  26.                 <Setter Property="FontAttributes" Value="Italic" />
  27.             </Style>
  28.             <Style x:Key="buttonStyle3" TargetType="Button"
  29.                    BasedOn="{StaticResource baseButtonStyle}">
  30.                 <Setter Property="HorizontalOptions" Value="End" />
  31.                 <Setter Property="VerticalOptions" Value="StartAndExpand" />
  32.                 <Setter Property="TextColor" Value="Blue" />
  33.                 <Setter Property="FontAttributes" Value="Bold" />
  34.             </Style>
  35.             <!-- New style definition. -->
  36.             <Style x:Key="newButtonStyle" TargetType="Button"
  37.                    BaseResourceKey="buttonStyle">
  38.                 <Setter Property="BackgroundColor">
  39.                     <Setter.Value>
  40.                         <OnPlatform x:TypeArguments="Color"
  41.                                     iOS="#C0C0C0"
  42.                                     Android="#404040"
  43.                                     WinPhone="Gray" />
  44.                     </Setter.Value>
  45.                 </Setter>
  46.                 <Setter Property="BorderColor" Value="Red" />
  47.                 <Setter Property="BorderWidth" Value="3" />
  48.             </Style>
  49.         </ResourceDictionary>
  50.     </ContentPage.Resources>
  51.     <StackLayout>
  52.         <Button Text=" Switch to Style #1 "
  53.                 Style="{StaticResource newButtonStyle}"
  54.                 Clicked="OnButton1Clicked" />
  55.         <Button Text=" Switch to Style #2 "
  56.                 Style="{StaticResource newButtonStyle}"
  57.                 Clicked="OnButton2Clicked" />
  58.         <Button Text=" Switch to Style #3 "
  59.                 Style="{StaticResource newButtonStyle}"
  60.                 Clicked="OnButton3Clicked" />
  61.         <Button Text=" Reset "
  62.                 Style="{DynamicResource buttonStyle}"
  63.                 Clicked="OnResetButtonClicked" />
  64.     </StackLayout>
  65. </ContentPage>
请注意,前三个Button元素引用带有StaticResource的“newButtonStyle”字典条目。 这里不需要DynamicResource,因为与“newButtonStyle”关联的Style对象本身不会改变,除了它派生的Style。 具有键“newButtonStyle”的Style保持与“buttonStyle”的链接,并在该un-derlying样式发生变化时在内部改变。 当程序开始运行时,只有“newButtonStyle”中定义的属性才会应用于这三个按钮:

“重置”按钮继续引用“buttonStyle”条目。
与DynamicStyles程序一样,代码隐藏文件在您单击前三个按钮之一时设置该字典条目,因此所有按钮也会选择“buttonStyle”属性。 以下是按钮3,2和1的(从左到右)点击的结果:


阅读(5342) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~