Xamarin.Forms dictionnaires de ressources
Un ResourceDictionary
est un référentiel pour les ressources utilisées par une Xamarin.Forms application. Ressources classiques stockées dans un ResourceDictionary
include styles, modèles de contrôle, modèles de données, couleurs et convertisseurs.
En XAML, les ressources stockées dans un ResourceDictionary
peuvent être référencées et appliquées aux éléments à l’aide de l’extension StaticResource
de balisage ou DynamicResource
. En C#, les ressources peuvent également être définies dans un ResourceDictionary
, puis référencées et appliquées aux éléments à l’aide d’un indexeur basé sur des chaînes. Toutefois, l’utilisation d’un en C#présente peu d’avantages ResourceDictionary
, car les objets partagés peuvent être stockés en tant que champs ou propriétés et accessibles directement sans avoir à les récupérer d’abord à partir d’un dictionnaire.
Créer des ressources en XAML
Chaque VisualElement
objet dérivé a une Resources
propriété, qui peut ResourceDictionary
contenir des ressources. De même, un Application
objet dérivé a une Resources
propriété, qui est un ResourceDictionary
qui peut contenir des ressources.
Une Xamarin.Forms application contient uniquement une classe qui dérive de Application
, mais utilise souvent de nombreuses classes qui dérivent de VisualElement
, y compris les pages, les dispositions et les contrôles. La propriété de l’un de ces objets peut être Resources
définie sur une ResourceDictionary
ressource contenante. Choix de l’endroit où placer un impact particulier ResourceDictionary
où les ressources peuvent être utilisées :
- Les ressources d’un
ResourceDictionary
qui est attaché à une vue telle queButton
ou neLabel
peuvent être appliquées qu’à cet objet particulier. - Les ressources d’un
ResourceDictionary
joint à une disposition telle queStackLayout
ouGrid
peuvent être appliquées à la disposition et à tous les enfants de cette disposition. - Les ressources d’un
ResourceDictionary
défini au niveau de la page peuvent être appliquées à la page et à tous ses enfants. - Les ressources d’un
ResourceDictionary
défini au niveau de l’application peuvent être appliquées dans l’ensemble de l’application.
À l’exception des styles implicites, chaque ressource du dictionnaire de ressources doit avoir une clé de chaîne unique définie avec l’attribut x:Key
.
Le code XAML suivant montre les ressources définies au niveau ResourceDictionary
de l’application dans le fichier App.xaml :
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ResourceDictionaryDemo.App">
<Application.Resources>
<Thickness x:Key="PageMargin">20</Thickness>
<!-- Colors -->
<Color x:Key="AppBackgroundColor">AliceBlue</Color>
<Color x:Key="NavigationBarColor">#1976D2</Color>
<Color x:Key="NavigationBarTextColor">White</Color>
<Color x:Key="NormalTextColor">Black</Color>
<!-- Implicit styles -->
<Style TargetType="{x:Type NavigationPage}">
<Setter Property="BarBackgroundColor"
Value="{StaticResource NavigationBarColor}" />
<Setter Property="BarTextColor"
Value="{StaticResource NavigationBarTextColor}" />
</Style>
<Style TargetType="{x:Type ContentPage}"
ApplyToDerivedTypes="True">
<Setter Property="BackgroundColor"
Value="{StaticResource AppBackgroundColor}" />
</Style>
</Application.Resources>
</Application>
Dans cet exemple, le dictionnaire de ressources définit une Thickness
ressource, plusieurs Color
ressources et deux ressources implicites Style
. Pour plus d’informations sur la App
classe, consultez Xamarin.Forms Classe d’application.
Notes
Il est également valide de placer toutes les ressources entre des balises explicites ResourceDictionary
. Toutefois, depuis Xamarin.Forms la version 3.0, les ResourceDictionary
balises ne sont pas obligatoires. Au lieu de cela, l’objet ResourceDictionary
est créé automatiquement et vous pouvez insérer les ressources directement entre les balises d’élément Resources
property.
Utiliser des ressources dans XAML
Chaque ressource a une clé spécifiée à l’aide de l’attribut x:Key
, qui devient sa clé de dictionnaire dans le ResourceDictionary
. La clé est utilisée pour référencer une ressource à partir de avec l’extension ResourceDictionary
StaticResource
de balisage ou DynamicResource
.
L’extension StaticResource
de balisage est similaire à l’extension de DynamicResource
balisage en ce que les deux utilisent une clé de dictionnaire pour référencer une valeur d’un dictionnaire de ressources. Toutefois, tandis que l’extension de StaticResource
balisage effectue une recherche de dictionnaire unique, l’extension de DynamicResource
balisage conserve un lien vers la clé de dictionnaire. Par conséquent, si l’entrée de dictionnaire associée à la clé est remplacée, la modification est appliquée à l’élément visuel. Cela permet d’apporter des modifications aux ressources d’exécution dans une application. Pour plus d’informations sur les extensions de balisage, consultez Extensions de balisage XAML.
L’exemple XAML suivant montre comment consommer des ressources et définit également des ressources supplémentaires dans un StackLayout
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ResourceDictionaryDemo.HomePage"
Title="Home Page">
<StackLayout Margin="{StaticResource PageMargin}">
<StackLayout.Resources>
<!-- Implicit style -->
<Style TargetType="Button">
<Setter Property="FontSize" Value="Medium" />
<Setter Property="BackgroundColor" Value="#1976D2" />
<Setter Property="TextColor" Value="White" />
<Setter Property="CornerRadius" Value="5" />
</Style>
</StackLayout.Resources>
<Label Text="This app demonstrates consuming resources that have been defined in resource dictionaries." />
<Button Text="Navigate"
Clicked="OnNavigateButtonClicked" />
</StackLayout>
</ContentPage>
Dans cet exemple, l’objet ContentPage
utilise le style implicite défini dans le dictionnaire de ressources au niveau de l’application. L’objet StackLayout
consomme la PageMargin
ressource définie dans le dictionnaire de ressources au niveau de l’application, tandis que l’objet Button
consomme le style implicite défini dans le StackLayout
dictionnaire de ressources. Cela donne l’affichage illustré dans les captures d’écran suivantes :
Important
Les ressources spécifiques à une seule page ne doivent pas être incluses dans un dictionnaire de ressources au niveau de l’application, car ces ressources seront ensuite analysées au démarrage de l’application plutôt qu’au moment où une page l’exige. Pour plus d’informations, consultez Réduire la taille du dictionnaire de ressources d’application.
Comportement de recherche de ressources
Le processus de recherche suivant se produit lorsqu’une ressource est référencée avec l’extension de StaticResource
balisage ou DynamicResource
:
- La clé demandée est vérifiée dans le dictionnaire de ressources, le cas échéant, pour l’élément qui définit la propriété. Si la clé demandée est trouvée, sa valeur est retournée et le processus de recherche se termine.
- Si aucune correspondance n’est trouvée, le processus de recherche recherche l’arborescence visuelle vers le haut, en vérifiant le dictionnaire de ressources de chaque élément parent. Si la clé demandée est trouvée, sa valeur est retournée et le processus de recherche se termine. Sinon, le processus continue vers le haut jusqu’à ce que l’élément racine soit atteint.
- Si aucune correspondance n’est trouvée au niveau de l’élément racine, le dictionnaire de ressources au niveau de l’application est examiné.
- Si une correspondance n’est toujours pas trouvée, un
XamlParseException
est levée.
Par conséquent, lorsque l’analyseur XAML rencontre une StaticResource
extension de balisage ou DynamicResource
, il recherche une clé correspondante en parcourant l’arborescence visuelle, à l’aide de la première correspondance qu’il trouve. Si cette recherche se termine à la page et que la clé est toujours introuvable, l’analyseur XAML recherche le ResourceDictionary
joint à l’objet App
. Si la clé est toujours introuvable, une exception est levée.
Remplacer les ressources
Lorsque les ressources partagent des clés, les ressources définies plus bas dans l’arborescence visuelle sont prioritaires sur celles définies plus haut. Par exemple, la définition d’une AppBackgroundColor
ressource sur AliceBlue
au niveau de l’application est remplacée par une ressource au niveau AppBackgroundColor
de la page définie sur Teal
. De même, une ressource au niveau AppBackgroundColor
de la page est remplacée par une ressource de niveau AppBackgroundColor
contrôle.
Dictionnaires de ressources autonomes
Une classe dérivée de ResourceDictionary
peut également se trouver dans un fichier XAML autonome. Le fichier XAML peut ensuite être partagé entre les applications.
Pour créer un tel fichier, ajoutez un nouvel élément Affichage du contenu ou Page de contenu au projet (mais pas une vue de contenu ou une page de contenu avec uniquement un fichier C#). Supprimez le fichier code-behind et, dans le fichier XAML, remplacez le nom de la classe de base par ContentView
ou ContentPage
par ResourceDictionary
. En outre, supprimez l’attribut x:Class
de la balise racine du fichier.
L’exemple XAML suivant montre un ResourceDictionary
nom MyResourceDictionary.xaml :
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<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>
Dans cet exemple, le ResourceDictionary
contient une ressource unique, qui est un objet de type DataTemplate
. MyResourceDictionary.xaml peut être consommé en le fusionnant dans un autre dictionnaire de ressources.
Par défaut, l’éditeur de liens supprime les fichiers XAML autonomes des builds en version lorsque le comportement de l’éditeur de liens est défini pour lier tous les assemblys. Pour vous assurer que les fichiers XAML autonomes restent dans une version de version :
Ajoutez un attribut personnalisé
Preserve
à l’assembly contenant les fichiers XAML autonomes. Pour plus d’informations, consultez Conservation du code.Définissez l’attribut
Preserve
au niveau de l’assembly :[assembly:Preserve(AllMembers = true)]
Pour plus d’informations sur la liaison, consultez Liaison d’applications Xamarin.iOS et Liaison sur Android.
Dictionnaires de ressources fusionnés
Les dictionnaires de ressources fusionnés combinent un ou plusieurs ResourceDictionary
objets dans un autre ResourceDictionary
.
Fusionner des dictionnaires de ressources locales
Un fichier local ResourceDictionary
peut être fusionné dans un autre ResourceDictionary
en créant un ResourceDictionary
objet dont Source
la propriété est définie sur le nom du fichier XAML avec les ressources :
<ContentPage ...>
<ContentPage.Resources>
<!-- Add more resources here -->
<ResourceDictionary Source="MyResourceDictionary.xaml" />
<!-- Add more resources here -->
</ContentPage.Resources>
...
</ContentPage>
Cette syntaxe n’instancie pas la MyResourceDictionary
classe. Au lieu de cela, il fait référence au fichier XAML. Pour cette raison, lors de la définition de la Source
propriété, un fichier code-behind n’est pas requis et l’attribut x:Class
peut être supprimé de la balise racine du fichier MyResourceDictionary.xaml .
Important
La Source
propriété ne peut être définie qu’à partir de XAML.
Fusionner des dictionnaires de ressources à partir d’autres assemblys
Un ResourceDictionary
peut également être fusionné dans un autre en ResourceDictionary
l’ajoutant à la MergedDictionaries
propriété de .ResourceDictionary
Cette technique permet de fusionner des dictionnaires de ressources, quel que soit l’assembly dans lequel ils résident. La fusion de dictionnaires de ressources à partir d’assemblys externes nécessite ResourceDictionary
qu’une action de build soit définie sur EmbeddedResource, qu’elle ait un fichier code-behind et que l’attribut x:Class
soit défini dans la balise racine du fichier.
Avertissement
La classe ResourceDictionary
définit aussi une propriété MergedWith
. Toutefois, cette propriété a été dépréciée et ne doit plus être utilisée.
L’exemple de code suivant montre deux dictionnaires de ressources ajoutés à la MergedDictionaries
collection d’un niveau ResourceDictionary
de page :
<ContentPage ...
xmlns:local="clr-namespace:ResourceDictionaryDemo"
xmlns:theme="clr-namespace:MyThemes;assembly=MyThemes">
<ContentPage.Resources>
<ResourceDictionary>
<!-- Add more resources here -->
<ResourceDictionary.MergedDictionaries>
<!-- Add more resource dictionaries here -->
<local:MyResourceDictionary />
<theme:LightTheme />
<!-- Add more resource dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Add more resources here -->
</ResourceDictionary>
</ContentPage.Resources>
...
</ContentPage>
Dans cet exemple, un dictionnaire de ressources du même assembly et un dictionnaire de ressources d’un assembly externe sont fusionnés dans le dictionnaire de ressources au niveau de la page. En outre, vous pouvez également ajouter d’autres ResourceDictionary
objets dans les MergedDictionaries
balises property-element et d’autres ressources en dehors de ces balises.
Important
Il ne peut y avoir qu’une MergedDictionaries
seule balise d’élément de propriété dans un ResourceDictionary
, mais vous pouvez y placer autant d’objets ResourceDictionary
que nécessaire.
Lorsque des ressources fusionnées ResourceDictionary
partagent des valeurs d’attribut identiques x:Key
, Xamarin.Forms utilise la priorité de ressource suivante :
- Ressources locales du dictionnaire de ressources.
- Les ressources contenues dans les dictionnaires de ressources qui ont été fusionnés via la
MergedDictionaries
collection, dans l’ordre inverse, sont répertoriées dans laMergedDictionaries
propriété .
Notes
La recherche dans les dictionnaires de ressources peut être une tâche gourmande en ressources si une application contient plusieurs dictionnaires de ressources volumineux. Par conséquent, pour éviter toute recherche inutile, vous devez vous assurer que chaque page d’une application utilise uniquement les dictionnaires de ressources appropriés à la page.
Liens connexes
- Dictionnaires de ressources (exemple)
- Extensions de balisage XAML
- Xamarin.Forms Styles
- Liaison d’applications Xamarin.iOS
- Liaison sur Android
- ResourceDictionary API