资源字典——重复使用XAML资源

简介: XAML资源是可以多次使用的对象的定义。 ResourceDictionary允许在单个位置定义资源,并在整个Xamarin.Forms应用程序中重新使用。 本文介绍了如何创建和使用ResourceDictionary,以及如何合并资源字典。

XAML资源是可以多次使用的对象的定义。 ResourceDictionary允许在单个位置定义资源,并在整个Xamarin.Forms应用程序中重新使用。 本文介绍了如何创建和使用ResourceDictionary,以及如何合并资源字典。

概观

ResourceDictionary是由Xamarin.Forms应用程序使用的资源的存储库。 存储在ResourceDictionary中的典型资源包括样式,控件模板,数据模板,颜色和转换器。
在XAML中,资源在ResourceDictionary中定义,然后通过使用StaticResource标记扩展检索并应用于元素。 在C#中,资源在ResourceDictionary中定义,然后通过使用基于字符串的索引器检索并应用到元素。 但是,在C#中使用ResourceDictionary几乎没有什么优势,因为资源可以直接分配给可视元素的属性,而无需先从ResourceDictionary中检索它们。

创建和使用ResourceDictionary

可以在连接到页面或控件的资源集合或应用程序的资源集合的ResourceDictionary中定义资源。 选择在哪里定义ResourceDictionary会影响可以使用的地方:

  • 在控制级定义的ResourceDictionary中的资源只能应用于控件及其子级。
  • 在页面级定义的ResourceDictionary中的资源只能应用于页面及其子级。
  • 在应用程序级定义的ResourceDictionary中的资源可以应用于整个应用程序。

以下XAML代码示例显示了在应用程序级别ResourceDictionary中定义的资源:

点击(此处)折叠或打开

  1. Application ...>
  2.     Application.Resources>
  3.         ResourceDictionary>
  4.             Color x:Key="PageBackgroundColor">Yellow/Color>
  5.             Color x:Key="HeadingTextColor">Black/Color>
  6.             Color x:Key="NormalTextColor">Blue/Color>
  7.             Style x:Key="LabelPageHeadingStyle" TargetType="Label">
  8.                 Setter Property="FontAttributes" Value="Bold" />
  9.                 Setter Property="HorizontalOptions" Value="Center" />
  10.                 Setter Property="TextColor" Value="{StaticResource HeadingTextColor}" />
  11.             /Style>
  12.         /ResourceDictionary>
  13.     /Application.Resources>
  14. /Application>


这个ResourceDictionary定义了三个Color资源和一个Style资源。 有关创建XAML App类的更多信息,请参阅App类。
每个资源都有一个使用x:Key属性指定的键,在ResourceDictionary中给它一个描述性键。 密钥用于通过StaticResource标记扩展从ResourceDictionary中检索资源,如以下XAML代码示例所示,该示例显示了在控制级别ResourceDictionary中定义的其他资源:

点击(此处)折叠或打开

  1. StackLayout Margin="0,20,0,0">
  2.   StackLayout.Resources>
  3.     ResourceDictionary>
  4.       Style x:Key="LabelNormalStyle" TargetType="Label">
  5.         Setter Property="TextColor" Value="{StaticResource NormalTextColor}" />
  6.       /Style>
  7.       Style x:Key="MediumBoldText" TargetType="Button">
  8.         Setter Property="FontSize" Value="Medium" />
  9.         Setter Property="FontAttributes" Value="Bold" />
  10.       /Style>
  11.     /ResourceDictionary>
  12.   /StackLayout.Resources>
  13.   Label Text="ResourceDictionary Demo" Style="{StaticResource LabelPageHeadingStyle}" />
  14.     Label Text="This app demonstrates consuming resources that have been defined in resource dictionaries."
  15.            Margin="10,20,10,0"
  16.            Style="{StaticResource LabelNormalStyle}" />
  17.     Button Text="Navigate"
  18.             Clicked="OnNavigateButtonClicked"
  19.             TextColor="{StaticResource NormalTextColor}"
  20.             Margin="0,20,0,0"
  21.             HorizontalOptions="Center"
  22.             Style="{StaticResource MediumBoldText}" />
  23. /StackLayout>


第一个Label实例检索并使用应用程序级ResourceDictionary中定义的LabelPageHeadingStyle资源,第二个Label实例检索并使用控件级ResourceDictionary中定义的LabelNormalStyle资源。 同样,Button实例检索并使用应用程序级ResourceDictionary中定义的NormalTextColor资源和控制级ResourceDictionary中定义的MediumBoldText资源。 这将导致以下屏幕截图中显示的外观:

注意:特定于单个页面的资源不应包含在应用程序级资源字典中,因为这些资源将在应用程序启动时被解析,而不是在页面需要时解析。 有关更多信息,请参阅减少应用程序资源字典大小。

重写资源

当ResourceDictionary资源共享x:Key属性值时,在视图层次结构中定义较低的资源将优先于定义较高的资源。 例如,在应用程序级别将PageBackgroundColor资源设置为蓝色将被设置为黄色的页面级PageBackgroundColor资源覆盖。 同样,页面级PageBackgroundColor资源将被控件级PageBackgroundColor资源覆盖。 以下XAML代码示例演示了这种优先级:

点击(此处)折叠或打开

  1. ContentPage ... BackgroundColor="{StaticResource PageBackgroundColor}">
  2.     ContentPage.Resources>
  3.         ResourceDictionary>
  4.             Color x:Key="PageBackgroundColor">Blue/Color>
  5.             Color x:Key="NormalTextColor">Yellow/Color>
  6.         /ResourceDictionary>
  7.     /ContentPage.Resources>
  8.     StackLayout Margin="0,20,0,0">
  9.         ...
  10.         Label Text="ResourceDictionary Demo" Style="{StaticResource LabelPageHeadingStyle}" />
  11.         Label Text="This app demonstrates consuming resources that have been defined in resource dictionaries."
  12.                Margin="10,20,10,0"
  13.                Style="{StaticResource LabelNormalStyle}" />
  14.         Button Text="Navigate"
  15.                 Clicked="OnNavigateButtonClicked"
  16.                 TextColor="{StaticResource NormalTextColor}"
  17.                 Margin="0,20,0,0"
  18.                 HorizontalOptions="Center"
  19.                 Style="{StaticResource MediumBoldText}" />
  20.     /StackLayout>
  21. /ContentPage>
在应用程序级别定义的原始PageBackgroundColor和NormalTextColor实例将被在页面级定义的PageBackgroundColor和NormalTextColor实例覆盖。 因此,页面背景颜色变为蓝色,页面上的文本变为黄色,如以下屏幕截图所示:


但是请注意,NavigationPage的背景栏仍为黄色,因为BarBackgroundColor属性设置为应用程序级ResourceDictionary中定义的PageBackgroundColor资源的值。

合并资源字典

合并资源字典将一个或多个ResourceDictionary实例组合到另一个中。 这可以通过将ResourceDictionary.MergedDictionaries属性设置为将被合并到应用程序,页面或控件级别ResourceDictionary中的一个或多个资源字典来实现。

ResourceDictionary类型还具有MergedWith属性,可用于将单个ResourceDictionary合并到另一个中,将ResourceDictionary指定为将MergedWith属性的值合并到当前ResourceDictionary实例中。 当通过MergedWith属性进行合并时,当前ResourceDictionary中将共享x:Key属性值与ResourceDictionary中要合并资源的任何资源将被替换。 但是,MergedWith属性将在Xamarin.Forms的未来版本中被弃用。 因此,建议使用MergedDictionaries属性来合并ResourceDictionary实例。

以下XAML代码示例显示了一个名为MyResourceDictionary的ResourceDictionary,其中包含一个资源:

点击(此处)折叠或打开

  1. ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
  2.                     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
  3.                     x:Class="ResourceDictionaryDemo.MyResourceDictionary">
  4.     DataTemplate x:Key="PersonDataTemplate">
  5.         ViewCell>
  6.             Grid>
  7.                 Grid.ColumnDefinitions>
  8.                     ColumnDefinition Width="0.5*" />
  9.                     ColumnDefinition Width="0.2*" />
  10.                     ColumnDefinition Width="0.3*" />
  11.                 /Grid.ColumnDefinitions>
  12.                 Label Text="{Binding Name}" TextColor="{StaticResource NormalTextColor}" FontAttributes="Bold" />
  13.                 Label Grid.Column="1" Text="{Binding Age}" TextColor="{StaticResource NormalTextColor}" />
  14.                 Label Grid.Column="2" Text="{Binding Location}" TextColor="{StaticResource NormalTextColor}" HorizontalTextAlignment="End" />
  15.             /Grid>
  16.         /ViewCell>
  17.     /DataTemplate>
  18. /ResourceDictionary>
MyResourceDictionary可以合并到任何应用程序,页面或控件级别的ResourceDictionary中。 以下XAML代码示例显示使用MergedDictionaries属性将其合并到页面级ResourceDictionary中:

点击(此处)折叠或打开

  1. ContentPage ...>
  2.     ContentPage.Resources>
  3.         ResourceDictionary>
  4.             ResourceDictionary.MergedDictionaries>
  5.                 local:MyResourceDictionary />
  6.                 !-- Add more resource dictionaries here -->
  7.             /ResourceDictionary.MergedDictionaries>
  8.         /ResourceDictionary>
  9.     /ContentPage.Resources>
  10.     ...
  11. /ContentPage>
当合并的ResourceDictionary资源共享相同的x:Key属性值时,Xamarin.Forms使用以下资源优先级:


  1. 资源字典的本地资源。
  2. 包含在通过MergedWith属性合并的资源字典中的资源。
  3. 通过MergedDictionaries集合合并的资源字典中包含的资源,按MergedDictionaries属性中列出的顺序排列。

注意:如果应用程序包含多个大型资源字典,则搜索资源字典可能是一个计算密集型任务。 因此,请确保应用程序中的每个页面仅使用适合页面的资源字典,以避免不必要的搜索。

概述

本文介绍了如何创建和使用ResourceDictionary,以及如何合并资源字典。 ResourceDictionary允许在单个位置定义资源,并在整个Xamarin.Forms应用程序中重新使用。

目录
相关文章
|
C# 数据格式 XML
WPF 资源(StaticResource 静态资源、DynamicResource 动态资源、添加二进制资源、绑定资源树)
原文:WPF 资源(StaticResource 静态资源、DynamicResource 动态资源、添加二进制资源、绑定资源树) 一、WPF对象级(Window对象)资源的定义与查找 实例一: StaticR...
8068 0
|
C++
新建项无资源字典类型
新建项无资源字典类型
96 0
新建项无资源字典类型
|
弹性计算 JSON 运维
使用模板创建资源|学习笔记
快速学习使用模板创建资源
64 0
使用模板创建资源|学习笔记
|
Java Spring 容器
开发20年,你可知道SpringWeb接口资源是如何保存起来的?
我们在浏览器上只输入了一个URL地址,怎么就能访问到这个接口的呢?于是乎就引出了 今天我们要讨论的话题。Spring中的Web接口资源是如何保存起来的?
191 0
|
安全 编译器 API
C++在资源管理类中提供对原始资源的访问
C++在资源管理类中提供对原始资源的访问
128 0
|
C#
WPF BitmapImage 占用资源无法释放、无法删除问题
原文:WPF BitmapImage 占用资源无法释放、无法删除问题 使用Image控件显示图片后,虽然自己释放了图片资源,Image.Source =null 了一下,但是图片实际没有释放。解决方案:修改加载方式~        public static BitmapImage GetImage...
2027 1
|
Android开发
【Android 安装包优化】移除无用资源 ( 自动移除无用资源 | 直接引用资源 | 动态获取资源 id | Lint 检查资源 )(一)
【Android 安装包优化】移除无用资源 ( 自动移除无用资源 | 直接引用资源 | 动态获取资源 id | Lint 检查资源 )(一)
413 0
【Android 安装包优化】移除无用资源 ( 自动移除无用资源 | 直接引用资源 | 动态获取资源 id | Lint 检查资源 )(一)
|
Android开发
【Android 安装包优化】移除无用资源 ( 自动移除无用资源 | 直接引用资源 | 动态获取资源 id | Lint 检查资源 )(二)
【Android 安装包优化】移除无用资源 ( 自动移除无用资源 | 直接引用资源 | 动态获取资源 id | Lint 检查资源 )(二)
326 0
【Android 安装包优化】移除无用资源 ( 自动移除无用资源 | 直接引用资源 | 动态获取资源 id | Lint 检查资源 )(二)
|
安全 Java 程序员
避免创建不必要的对象
在Java开发中,程序员要尽可能的避免创建相同的功能的对象,因为这样既消耗内存,又影响程序运行速度。在这种情况下可以考虑重复利用对象。
334 0
避免创建不必要的对象
|
C#
WPF资源字典怎么用
资源字典的使用方法
188 0
WPF资源字典怎么用