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

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

文章分类

全部博文(855)

文章存档

2019年(12)

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-07-25 22:21:36

资源词典

Xamarin.Forms还支持第二种共享对象和值的方法,虽然这种方法比x:静态标记扩展稍微有点开销,但它更通用 - 因为所有东西 - 共享对象和使用的可视元素 它们 - 可以用XAML表示。
VisualElement定义了一个名为Resources的属性,它属于ResourceDictionary类型 - 一个带有字符串键和类型为object的值的字典。 可以在XAML中将项添加到此词典中,并且可以使用StaticResource和DynamicResource标记扩展在XAML中访问它们。
虽然x:Static和StaticResource有一些相似的名称,但它们完全不同:x:Static引用常量,静态字段,静态属性或枚举成员,而StaticResource从ResourceDictionary检索对象。
虽然x:Static标记扩展是XAML固有的(因此出现在带有x前缀的XAML中),但StaticResource和DynamicResource标记扩展不是。 它们是Windows Presentation Foundation中原始XAML实现的一部分,Silverlight,Windows Phone 7和8以及Windows 8和10也支持StaticResource。
你将使用StaticResource用于大多数目的,并为一些特殊的应用程序保留DynamicResource,所以让我们从StaticResource开始。
StaticResource用于大多数目的
假设您已在StackLayout中定义了三个按钮:


点击(此处)折叠或打开

  1. <StackLayout>
  2.     <Button Text=" Carpe diem "
  3.             HorizontalOptions="Center"
  4.             VerticalOptions="CenterAndExpand"
  5.             BorderWidth="3"
  6.             TextColor="Red"
  7.             FontSize="Large">
  8.         <Button.BackgroundColor>
  9.             <OnPlatform x:TypeArguments="Color"
  10.                         Android="#404040" />
  11.         </Button.BackgroundColor>
  12.         <Button.BorderColor>
  13.             <OnPlatform x:TypeArguments="Color"
  14.                         Android="White"
  15.                         WinPhone="Black" />
  16.         </Button.BorderColor>
  17.     </Button>
  18.     <Button Text=" Sapere aude "
  19.             HorizontalOptions="Center"
  20.             VerticalOptions="CenterAndExpand"
  21.             BorderWidth="3"
  22.             TextColor="Red"
  23.             FontSize="Large">
  24.         <Button.BackgroundColor>
  25.             <OnPlatform x:TypeArguments="Color"
  26.                         Android="#404040" />
  27.         </Button.BackgroundColor>
  28.         <Button.BorderColor>
  29.             <OnPlatform x:TypeArguments="Color"
  30.                         Android="White"
  31.                         WinPhone="Black" />
  32.         </Button.BorderColor>
  33.     </Button>
  34.     <Button Text=" Discere faciendo "
  35.             HorizontalOptions="Center"
  36.             VerticalOptions="CenterAndExpand"
  37.             BorderWidth="3"
  38.             TextColor="Red"
  39.             FontSize="Large">
  40.         <Button.BackgroundColor>
  41.             <OnPlatform x:TypeArguments="Color"
  42.                         Android="#404040" />
  43.         </Button.BackgroundColor>
  44.         <Button.BorderColor>
  45.             <OnPlatform x:TypeArguments="Color"
  46.                         Android="White"
  47.                         WinPhone="Black" />
  48.         </Button.BorderColor>
  49.     </Button>
  50. </StackLayout>

当然,这有点不切实际。 没有为这些按钮设置Clicked事件,并且通常按钮文本不是拉丁文。 但这是他们的样子:

除文本外,所有三个按钮都具有相同的属性设置为相同的值。 像这样的重复标记往往会错误地影响程序员。 这是对眼睛的冒犯,难以维持和改变。
最终你会看到如何使用样式来真正减少重复标记。 现在,怎么样?目标不是缩短标记,而是将值合并到一个地方,这样如果你想将TextColor属性从Red更改为Blue,你可以用一次编辑而不是三次编辑。
显然,您可以通过在代码中定义值来为此作业使用x:Static。 但是,让我们通过将值存储在资源字典中来完成XAML中的所有操作。 从VisualEle?衍生的每个类都有一个ResourceDictionary类型的Resources属性。 整个页面中使用的资源通常存储在ContentPage的Resources集合中。
第一步是将ContentPage的Resources属性表示为属性元素:

点击(此处)折叠或打开

  1. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
  2.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
  3.              x:Class="ResourceSharing.ResourceSharingPage">
  4.     <ContentPage.Resources>

  5.     </ContentPage.Resources>
  6.     ...
  7. </ContentPage>

如果您还使用property-element标记在页面上定义Padding属性,则顺序无关紧要。
出于性能目的,默认情况下Resources属性为null,因此您需要显式实例化ResourceDictionary:

点击(此处)折叠或打开

  1. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
  2.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
  3.              x:Class="ResourceSharing.ResourceSharingPage">
  4.     <ContentPage.Resources>
  5.         <ResourceDictionary>
  6.  
  7.         </ResourceDictionary>
  8.     </ContentPage.Resources>
  9.     ...
  10. </ContentPage>
在ResourceDictionary标记之间,您可以定义一个或多个对象或值。 必须使用您使用XAML x:Key属性指定的字典键来标识字典中的每个项目。 例如,下面是在字典中包含LayoutOptions值的语法,其中包含一个描述键,指示此值是为设置水平选项定义的:

点击(此处)折叠或打开

  1. <LayoutOptions x:Key="horzOptions">Center</LayoutOptions>
因为这是一个LayoutOptions值,所以XAML解析器访问LayoutOptionsConverter类以转换标记的内容,即文本“Center”。
在字典中存储LayoutOptions值的第二种方法是让XAML解析器实例化结构并从您指定的属性设置LayoutOptions属性:

点击(此处)折叠或打开

  1. <LayoutOptions x:Key="vertOptions"
  2.                Alignment="Center"
  3.                Expands="True" />
BorderWidth属性的类型为double,因此XAML 2009规范中定义的x:Double数据类型元素是理想的:

点击(此处)折叠或打开

  1. <x:Double x:Key="borderWidth">3</x:Double>
您可以将颜色值存储在资源字典中,并将颜色的文本表示作为内容。 XAML解析器使用普通的ColorTypeConverter进行文本转换:

点击(此处)折叠或打开

  1. <Color x:Key="textColor">Red</Color>
您还可以在哈希符号后面指定十六进制ARGB值。
您无法通过设置其R,G和B属性来初始化Color值,因为这些属性是get-only。 但是您可以使用x:Arguments或使用x:FactoryMethod和x:Arguments的Color工厂方法之一调用Color构造函数。

点击(此处)折叠或打开

  1. <Color x:Key="textColor"
  2.        x:FactoryMethod="FromHsla">
  3.     <x:Arguments>
  4.         <x:Double>0</x:Double>
  5.         <x:Double>1</x:Double>
  6.         <x:Double>0.5</x:Double>
  7.         <x:Double>1</x:Double>
  8.     </x:Arguments>
  9. </Color>

注意x:Key和x:FactoryMethod属性。
上面显示的三个按钮的BackgroundColor和BorderColor属性设置为OnPlatform类的值。 幸运的是,您可以在字典中放置OnPlatform对象:

点击(此处)折叠或打开

  1. <OnPlatform x:Key="backgroundColor"
  2.             x:TypeArguments="Color"
  3.             Android="#404040" />
  4. <OnPlatform x:Key="borderColor"
  5.             x:TypeArguments="Color"
  6.             Android="White"
  7.             WinPhone="Black" />
注意x:Key和x:TypeArguments属性。
FontSize属性的字典项有些问题。 FontSize属性的类型为double,因此如果您在字典中存储实际的数值,那就没问题了。 但是你不能在字典中存储单词“Large”,就好像它是双重的一样。 仅当“Large”字符串设置为FontSize属性时,XAML解析器才使用FontSizeConverter。 因此,您需要将FontSize项存储为字符串:

点击(此处)折叠或打开

  1. <x:String x:Key="fontSize">Large</x:String>
这是完整的字典:

点击(此处)折叠或打开

  1. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
  2.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
  3.              x:Class="ResourceSharing.ResourceSharingPage">
  4.     <ContentPage.Resources>
  5.         <ResourceDictionary>
  6.             <LayoutOptions x:Key="horzOptions">Center</LayoutOptions>
  7.  
  8.             <LayoutOptions x:Key="vertOptions"
  9.                            Alignment="Center"
  10.                            Expands="True" />
  11.             <x:Double x:Key="borderWidth">3</x:Double>
  12.             <Color x:Key="textColor">Red</Color>
  13.             <OnPlatform x:Key="backgroundColor"
  14.                         x:TypeArguments="Color"
  15.                         Android="#404040" />
  16.             <OnPlatform x:Key="borderColor"
  17.                        x:TypeArguments="Color"
  18.                        Android="White"
  19.                        WinPhone="Black" />
  20.             <x:String x:Key="fontSize">Large</x:String>
  21.         </ResourceDictionary>
  22.     </ContentPage.Resources>
  23.     ...
  24. </ContentPage>
这有时被称为页面的资源部分。 在现实生活中,很多XAML文件都以资源部分开头。
您可以使用StaticResourceExtension支持的StaticResource标记扩展来引用字典中的项目。 该类定义了一个名为Key的属性,您将其设置为字典键。 您可以将StaticResourceExtension用作property-element标记中的元素,也可以在花括号中使用StaticResourceExtension或StaticResource。 如果您使用的是大括号语法,则可以省略Key和等号,因为Key是StaticResourceExtension的content属性。
ResourceSharing项目中的以下完整XAML文件说明了以下三个选项:

点击(此处)折叠或打开

  1. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
  2.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
  3.              x:Class="ResourceSharing.ResourceSharingPage">
  4.     <ContentPage.Resources>
  5.         <ResourceDictionary>
  6.             <LayoutOptions x:Key="horzOptions">Center</LayoutOptions>
  7.  
  8.             <LayoutOptions x:Key="vertOptions"
  9.                            Alignment="Center"
  10.                            Expands="True" />
  11.             <x:Double x:Key="borderWidth">3</x:Double>
  12.             <Color x:Key="textColor">Red</Color>
  13.             <OnPlatform x:Key="backgroundColor"
  14.                         x:TypeArguments="Color"
  15.                         Android="#404040" />
  16.             <OnPlatform x:Key="borderColor"
  17.                         x:TypeArguments="Color"
  18.                         Android="White"
  19.                         WinPhone="Black" />
  20.             <x:String x:Key="fontSize">Large</x:String>
  21.         </ResourceDictionary>
  22.     </ContentPage.Resources>
  23.  
  24.     <StackLayout>
  25.         <Button Text=" Carpe diem ">
  26.             <Button.HorizontalOptions>
  27.                 <StaticResourceExtension Key="horzOptions" />
  28.             </Button.HorizontalOptions>
  29.             <Button.VerticalOptions>
  30.                 <StaticResourceExtension Key="vertOptions" />
  31.             </Button.VerticalOptions>
  32.             <Button.BorderWidth>
  33.                 <StaticResourceExtension Key="borderWidth" />
  34.             </Button.BorderWidth>
  35.             <Button.TextColor>
  36.                 <StaticResourceExtension Key="textColor" />
  37.             </Button.TextColor>
  38.             <Button.BackgroundColor>
  39.                 <StaticResourceExtension Key="backgroundColor" />
  40.             </Button.BackgroundColor>
  41.             <Button.BorderColor>
  42.                 <StaticResourceExtension Key="borderColor" />
  43.             </Button.BorderColor>
  44.             <Button.FontSize>
  45.                 <StaticResourceExtension Key="fontSize" />
  46.             </Button.FontSize>
  47.         </Button>
  48.         <Button Text=" Sapere aude "
  49.                 HorizontalOptions="{StaticResource Key=horzOptions}"
  50.                 VerticalOptions="{StaticResource Key=vertOptions}"
  51.                 BorderWidth="{StaticResource Key=borderWidth}"
  52.                 TextColor="{StaticResource Key=textColor}"
  53.                 BackgroundColor="{StaticResource Key=backgroundColor}"
  54.                 BorderColor="{StaticResource Key=borderColor}"
  55.                 FontSize="{StaticResource Key=fontSize}" />
  56.         <Button Text=" Discere faciendo "
  57.                 HorizontalOptions="{StaticResource horzOptions}"
  58.                 VerticalOptions="{StaticResource vertOptions}"
  59.                 BorderWidth="{StaticResource borderWidth}"
  60.                 TextColor="{StaticResource textColor}"
  61.                 BackgroundColor="{StaticResource backgroundColor}"
  62.                 BorderColor="{StaticResource borderColor}"
  63.                 FontSize="{StaticResource fontSize}" />
  64.     </StackLayout>
  65. </ContentPage>
第三个按钮中最简单的语法是最常见的,实际上,语法是如此普遍,许多长期XAML开发人员可能完全不熟悉其他变体。 但是,如果您使用具有Key属性的StaticResource版本,请不要在其上放置x前缀。 x:Key属性仅用于为ResourceDictionary中的项定义字典键。
字典中的对象和值在所有StaticResource引用之间共享。 在前面的例子中并不是那么清楚,但要记住这一点。 例如,假设您将Button对象存储在资源字典中:

点击(此处)折叠或打开

  1. <ContentPage.Resources>
  2.     <ResourceDictionary>
  3.         <Button x:Key="button"
  4.                 Text="Shared Button?"
  5.                 HorizontalOptions="Center"
  6.                 VerticalOptions="CenterAndExpand"
  7.                 FontSize="Large" />
  8.     </ResourceDictionary>
  9. </ContentPage.Resources>
您当然可以通过使用StaticResourceExtension元素语法将Stack对象添加到StackLayout的Children集合中来在页面上使用该Button对象:

点击(此处)折叠或打开

  1. <StackLayout>
  2.     <StaticResourceExtension Key="button" />
  3. </StackLayout>
但是,为了将另一个副本放入StackLayout,您不能使用相同的字典项吗?

点击(此处)折叠或打开

  1. <StackLayout>
  2.     <StaticResourceExtension Key="button" />
  3.     <StaticResourceExtension Key="button" />
  4. </StackLayout>
那不行。 这两个元素都引用相同的Button对象,并且特定的视觉元素只能位于屏幕上的一个特定位置。 它不能在多个位置。
因此,视觉元素通常不存储在资源字典中。 如果您需要在页面上具有大部分相同属性的多个元素,您将需要使用样式,这将在第12章中探讨。
阅读(2897) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册