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中定义的资源:
点击(此处)折叠或打开
- Application ...>
- Application.Resources>
- ResourceDictionary>
- Color x:Key="PageBackgroundColor">Yellow/Color>
- Color x:Key="HeadingTextColor">Black/Color>
- Color x:Key="NormalTextColor">Blue/Color>
- Style x:Key="LabelPageHeadingStyle" TargetType="Label">
- Setter Property="FontAttributes" Value="Bold" />
- Setter Property="HorizontalOptions" Value="Center" />
- Setter Property="TextColor" Value="{StaticResource HeadingTextColor}" />
- /Style>
- /ResourceDictionary>
- /Application.Resources>
- /Application>
这个ResourceDictionary定义了三个Color资源和一个Style资源。 有关创建XAML App类的更多信息,请参阅App类。
每个资源都有一个使用x:Key属性指定的键,在ResourceDictionary中给它一个描述性键。 密钥用于通过StaticResource标记扩展从ResourceDictionary中检索资源,如以下XAML代码示例所示,该示例显示了在控制级别ResourceDictionary中定义的其他资源:
点击(此处)折叠或打开
- StackLayout Margin="0,20,0,0">
- StackLayout.Resources>
- ResourceDictionary>
- Style x:Key="LabelNormalStyle" TargetType="Label">
- Setter Property="TextColor" Value="{StaticResource NormalTextColor}" />
- /Style>
- Style x:Key="MediumBoldText" TargetType="Button">
- Setter Property="FontSize" Value="Medium" />
- Setter Property="FontAttributes" Value="Bold" />
- /Style>
- /ResourceDictionary>
- /StackLayout.Resources>
- Label Text="ResourceDictionary Demo" Style="{StaticResource LabelPageHeadingStyle}" />
- Label Text="This app demonstrates consuming resources that have been defined in resource dictionaries."
- Margin="10,20,10,0"
- Style="{StaticResource LabelNormalStyle}" />
- Button Text="Navigate"
- Clicked="OnNavigateButtonClicked"
- TextColor="{StaticResource NormalTextColor}"
- Margin="0,20,0,0"
- HorizontalOptions="Center"
- Style="{StaticResource MediumBoldText}" />
- /StackLayout>
第一个Label实例检索并使用应用程序级ResourceDictionary中定义的LabelPageHeadingStyle资源,第二个Label实例检索并使用控件级ResourceDictionary中定义的LabelNormalStyle资源。 同样,Button实例检索并使用应用程序级ResourceDictionary中定义的NormalTextColor资源和控制级ResourceDictionary中定义的MediumBoldText资源。 这将导致以下屏幕截图中显示的外观:
注意:特定于单个页面的资源不应包含在应用程序级资源字典中,因为这些资源将在应用程序启动时被解析,而不是在页面需要时解析。 有关更多信息,请参阅减少应用程序资源字典大小。
重写资源
当ResourceDictionary资源共享x:Key属性值时,在视图层次结构中定义较低的资源将优先于定义较高的资源。 例如,在应用程序级别将PageBackgroundColor资源设置为蓝色将被设置为黄色的页面级PageBackgroundColor资源覆盖。 同样,页面级PageBackgroundColor资源将被控件级PageBackgroundColor资源覆盖。 以下XAML代码示例演示了这种优先级:
点击(此处)折叠或打开
- ContentPage ... BackgroundColor="{StaticResource PageBackgroundColor}">
- ContentPage.Resources>
- ResourceDictionary>
- Color x:Key="PageBackgroundColor">Blue/Color>
- Color x:Key="NormalTextColor">Yellow/Color>
- /ResourceDictionary>
- /ContentPage.Resources>
- StackLayout Margin="0,20,0,0">
- ...
- Label Text="ResourceDictionary Demo" Style="{StaticResource LabelPageHeadingStyle}" />
- Label Text="This app demonstrates consuming resources that have been defined in resource dictionaries."
- Margin="10,20,10,0"
- Style="{StaticResource LabelNormalStyle}" />
- Button Text="Navigate"
- Clicked="OnNavigateButtonClicked"
- TextColor="{StaticResource NormalTextColor}"
- Margin="0,20,0,0"
- HorizontalOptions="Center"
- Style="{StaticResource MediumBoldText}" />
- /StackLayout>
- /ContentPage>
但是请注意,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,其中包含一个资源:
点击(此处)折叠或打开
- ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
- xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
- x:Class="ResourceDictionaryDemo.MyResourceDictionary">
- DataTemplate x:Key="PersonDataTemplate">
- ViewCell>
- Grid>
- Grid.ColumnDefinitions>
- ColumnDefinition Width="0.5*" />
- ColumnDefinition Width="0.2*" />
- ColumnDefinition Width="0.3*" />
- /Grid.ColumnDefinitions>
- Label Text="{Binding Name}" TextColor="{StaticResource NormalTextColor}" FontAttributes="Bold" />
- Label Grid.Column="1" Text="{Binding Age}" TextColor="{StaticResource NormalTextColor}" />
- Label Grid.Column="2" Text="{Binding Location}" TextColor="{StaticResource NormalTextColor}" HorizontalTextAlignment="End" />
- /Grid>
- /ViewCell>
- /DataTemplate>
- /ResourceDictionary>
点击(此处)折叠或打开
- ContentPage ...>
- ContentPage.Resources>
- ResourceDictionary>
- ResourceDictionary.MergedDictionaries>
- local:MyResourceDictionary />
- !-- Add more resource dictionaries here -->
- /ResourceDictionary.MergedDictionaries>
- /ResourceDictionary>
- /ContentPage.Resources>
- ...
- /ContentPage>
- 资源字典的本地资源。
- 包含在通过MergedWith属性合并的资源字典中的资源。
- 通过MergedDictionaries集合合并的资源字典中包含的资源,按MergedDictionaries属性中列出的顺序排列。
注意:如果应用程序包含多个大型资源字典,则搜索资源字典可能是一个计算密集型任务。 因此,请确保应用程序中的每个页面仅使用适合页面的资源字典,以避免不必要的搜索。
概述
本文介绍了如何创建和使用ResourceDictionary,以及如何合并资源字典。 ResourceDictionary允许在单个位置定义资源,并在整个Xamarin.Forms应用程序中重新使用。