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

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应用程序中重新使用。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值