Fichiers de ressources, de contenu et de données d'une application WPF
Les applications Microsoft Windows dépendent souvent de fichiers qui contiennent des données non exécutables, notamment de fichiers Extensible Application Markup Language (XAML), d'images, vidéo et audio. Windows Presentation Foundation (WPF) assure une prise en charge spéciale pour la configuration, l'identification, et l'utilisation de ces types de fichiers de données, appelés fichiers de données d'application. Cette prise en charge repose sur un jeu spécifique de types de fichiers de données d'application, y compris :
Fichiers de ressources : fichiers de données compilés en un fichier exécutable ou un assembly WPF de bibliothèque.
Fichiers de contenu : fichiers de données autonomes possédant une association explicite avec un assembly WPF exécutable.
Fichiers du site d'origine : fichiers de données autonomes ne possédant aucune association avec un assembly WPF exécutable.
Une distinction importante à faire entre ces trois types de fichiers est que les fichiers de ressources et les fichiers de contenu sont connus au moment de la génération ; un assembly les connaît explicitement. Pour des fichiers du site d'origine, en revanche, un assembly peut n'avoir aucune connaissance d'eux, ou une connaissance implicite par le biais d'un uniform resource identifier (URI) à en-tête pack de référence ; dans ce dernier cas, il n'y a aucune garantie que le fichier du site d'origine référencé existe réellement.
Pour référencer des fichiers de données d'application, Windows Presentation Foundation (WPF) utilise le modèle uniform resource identifier (URI) à en-tête pack qui est décrit en détail dans URI à en-tête pack dans WPF).
Cette rubrique décrit comment configurer et utiliser des fichiers de données d'application.
Cette rubrique comprend les sections suivantes.
- Fichiers de ressources
- Fichiers de contenu
- Fichiers du site d'origine
- Régénération après modification du type de build
- Rubriques connexes
Fichiers de ressources
Si un fichier de données d'application doit toujours être disponible pour une application, la seule méthode pour garantir cette disponibilité est de le compiler en un assembly exécutable principal d'application ou l'un de ses assemblys référencés. Ce type de fichier de données d'application est connu sous le nom de fichier de ressources.
Vous devez utiliser des fichiers de ressources lorsque :
Vous n'avez pas besoin de mettre à jour le contenu du fichier de ressources après qu'il a été compilé en un assembly.
Vous souhaitez simplifier la complexité de distribution d'application en réduisant le nombre de dépendances de fichier.
Votre fichier de données d'application doit être localisable (consultez Vue d'ensemble de la globalisation et de la localisation WPF).
Remarque |
---|
Les dictionnaires de ressources (fichiers XAML avec ResourceDictionary comme élément de niveau supérieur) ne sont pas des fichiers de ressources WPF ; bien que les fichiers de ressources WPF puissent être des dictionnaires de ressources, un dictionnaire de ressources n'est pas tenu d'être un fichier de ressources (consultez ResourceDictionary). En outre, les fichiers de ressources WPF sont différents du type de ressources incorporé ou lié qui peut être configuré à l'aide du support principal .NET Framework pour les ressources d'assembly (consultez Gestion des ressources de l'application).Bien que les fichiers de ressources WPF tirent parti du support de ressource incorporée .NET Framework principal, l'accès aux fichiers de ressources WPF est plus facile à l'aide des URIs à en-tête pack qu'à l'aide des espaces de noms. |
Configuration de fichiers de ressources
Dans WPF, un fichier de ressources est un fichier inclus dans un projet Microsoft build engine (MSBuild) sous la forme d'un élément Resource.
<Project "xmlns=https://schemas.microsoft.com/developer/msbuild/2003" ... >
...
<ItemGroup>
<Resource Include="ResourceFile.xaml" />
</ItemGroup>
...
</Project>
Remarque |
---|
Dans Microsoft Visual Studio, vous créez un fichier de ressources en ajoutant un fichier à un projet et en définissant son Build Action sur Resource. |
Lorsque le projet est généré, MSBuild compile la ressource en l'assembly.
Utilisation de fichiers de ressources
Pour charger un fichier de ressources, vous pouvez appeler la méthode GetResourceStream de la classe Application, en passant URI à en-tête pack qui identifie le fichier de ressources souhaité. GetResourceStream retourne un objet StreamResourceInfo, qui expose le fichier de ressources en tant que Stream et décrit son type de contenu.
À titre d'exemple, le code suivant montre comment utiliser GetResourceStream pour charger un fichier de ressources Page et le définir comme contenu d'un Frame (pageFrame) :
' Navigate to xaml page
Dim uri As New Uri("/PageResourceFile.xaml", UriKind.Relative)
Dim info As StreamResourceInfo = Application.GetResourceStream(uri)
Dim reader As New System.Windows.Markup.XamlReader()
Dim page As Page = CType(reader.LoadAsync(info.Stream), Page)
Me.pageFrame.Content = page
// Navigate to xaml page
Uri uri = new Uri("/PageResourceFile.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetResourceStream(uri);
System.Windows.Markup.XamlReader reader = new System.Windows.Markup.XamlReader();
Page page = (Page)reader.LoadAsync(info.Stream);
this.pageFrame.Content = page;
Bien que l'appel de GetResourceStream vous donne accès à Stream, vous devez exécuter le travail supplémentaire de conversion vers le type de la propriété avec lequel vous le définirez. À la place, vous pouvez laisser à WPF le soin d'ouvrir et de convertir Stream en chargeant directement un fichier de ressources dans la propriété d'un type à l'aide du code.
L'exemple suivant montre comment charger directement un Page dans un Frame (pageFrame) à l'aide du code.
Dim pageUri As New Uri("/PageResourceFile.xaml", UriKind.Relative)
Me.pageFrame.Source = pageUri
Uri pageUri = new Uri("/PageResourceFile.xaml", UriKind.Relative);
this.pageFrame.Source = pageUri;
L'exemple suivant est l'équivalent sous forme de balise de l'exemple précédent.
<Frame Name="pageFrame" Source="PageResourceFile.xaml" />
Fichiers de code d'application comme fichiers de ressources
Un jeu spécial de fichiers de code d'application WPF peut être référencé à l'aide des URIs à en-tête pack, lesquels comprennent des fenêtres, des pages, des documents dynamiques et des dictionnaires de ressources. Par exemple, vous pouvez définir la propriété Application.StartupUri avec un URI à en-tête pack qui référence la fenêtre ou la page que vous aimeriez charger lorsqu'une application démarre.
<Application
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
StartupUri="SOOPage.xaml" />
Vous pouvez le faire lorsqu'un fichier XAML est inclus dans un projet Microsoft build engine (MSBuild) sous la forme d'un élément Page.
<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" ... >
...
<ItemGroup>
<Page Include="MainWindow.xaml" />
</ItemGroup>
...
</Project>
Remarque |
---|
Dans Visual Studio, vous ajoutez un nouveau Window, NavigationWindow, Page, FlowDocument ou ResourceDictionary à un projet, Build Action pour le fichier de balisage aura comme valeur par défaut Page. |
Lorsqu'un projet avec des éléments Page est compilé, les éléments XAML sont convertis en format binaire et compilés dans l'assembly associé. Par conséquent, ces fichiers peuvent être utilisés de la même façon que des fichiers de ressources typiques.
Remarque |
---|
Si un fichier XAML est configuré comme un élément Resource, et qu'il n'a pas de fichier code-behind, le XAML brut est compilé en un assembly plutôt qu'en une version binaire du XAML brut. |
Fichiers de contenu
Un fichier de contenu est distribué comme un fichier libre en même temps qu'un assembly exécutable. Bien qu'ils ne soient pas compilés en un assembly, ceux-ci sont compilés avec les métadonnées qui établissent une association avec chaque fichier de contenu.
Vous devez utiliser des fichiers de contenu lorsque votre application requiert un jeu spécifique de fichiers de données d'application que vous souhaitez pouvoir mettre à jour sans recompiler l'assembly qui les consomme.
Configuration de fichiers de contenu
Pour ajouter un fichier de contenu à un projet, un fichier de données d'application doit être inclus en tant qu'élément Content. En outre, comme un fichier de contenu n'est pas compilé directement dans l'assembly, vous devez définir l'élément de métadonnées MSBuild CopyToOutputDirectory pour spécifier que le fichier de contenu est copié vers un emplacement qui est relatif à l'assembly créé. Si vous souhaitez que la ressource soit copiée vers le dossier de sortie de génération chaque fois qu'un projet est généré, vous définissez l'élément de métadonnées CopyToOutputDirectory avec la valeur Always. Sinon, vous pouvez vous assurer que seule la version la plus récente de la ressource est copiée vers le dossier de sortie de génération en utilisant la valeur PreserveNewest.
Ce qui suit montre un fichier configuré comme un fichier de contenu qui est copié dans le dossier de sortie de génération uniquement lorsqu'une nouvelle version de la ressource est ajoutée au projet.
<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" ... >
...
<ItemGroup>
<Content Include="ContentFile.xaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
...
</Project>
Remarque |
---|
Dans Visual Studio, vous créez un fichier de contenu en ajoutant un fichier à un projet et en définissant son Build Action à Content et vous affecter à son Copy to Output Directory la valeur Copy always (identique à Always) et Copy if newer (identique à PreserveNewest). |
Lorsque le projet est généré, un attribut AssemblyAssociatedContentFileAttribute est compilé dans les métadonnées de l'assembly pour chaque fichier de contenu.
[assembly: AssemblyAssociatedContentFile("ContentFile.xaml")]
La valeur du AssemblyAssociatedContentFileAttribute implique le chemin d'accès au fichier contenu par rapport à sa position dans le projet. Par exemple, si un fichier de contenu était situé dans un sous-dossier de projet, les informations supplémentaires du chemin d'accès seraient incorporées dans la valeur AssemblyAssociatedContentFileAttribute.
[assembly: AssemblyAssociatedContentFile("Resources/ContentFile.xaml")]
La valeur AssemblyAssociatedContentFileAttribute est également celle du chemin d'accès au fichier de contenu dans le dossier de sortie de génération.
Utilisation de fichiers de contenu
Pour charger un fichier de contenu, vous pouvez appeler la méthode GetContentStream de la classe Application, en passant une URI de pack qui identifie le fichier de contenu souhaité. GetContentStream retourne un objet StreamResourceInfo, qui expose le fichier de contenu en tant que Stream et décrit son type de contenu.
À titre d'exemple, le code suivant montre comment utiliser GetContentStream pour charger un fichier de contenu Page et le définir comme contenu d'un Frame (pageFrame).
' Navigate to xaml page
Dim uri As New Uri("/PageContentFile.xaml", UriKind.Relative)
Dim info As StreamResourceInfo = Application.GetContentStream(uri)
Dim reader As New System.Windows.Markup.XamlReader()
Dim page As Page = CType(reader.LoadAsync(info.Stream), Page)
Me.pageFrame.Content = page
// Navigate to xaml page
Uri uri = new Uri("/PageContentFile.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetContentStream(uri);
System.Windows.Markup.XamlReader reader = new System.Windows.Markup.XamlReader();
Page page = (Page)reader.LoadAsync(info.Stream);
this.pageFrame.Content = page;
Bien que l'appel de GetContentStream vous donne accès à Stream, vous devez exécuter le travail supplémentaire de conversion vers le type de la propriété avec lequel vous le définirez. À la place, vous pouvez laisser à WPF le soin d'ouvrir et de convertir Stream en chargeant directement un fichier de ressources dans la propriété d'un type à l'aide du code.
L'exemple suivant montre comment charger directement un Page dans un Frame (pageFrame) à l'aide du code.
Dim pageUri As New Uri("/PageContentFile.xaml", UriKind.Relative)
Me.pageFrame.Source = pageUri
Uri pageUri = new Uri("/PageContentFile.xaml", UriKind.Relative);
this.pageFrame.Source = pageUri;
L'exemple suivant est l'équivalent sous forme de balise de l'exemple précédent.
<Frame Name="pageFrame" Source="PageContentFile.xaml" />
Fichiers du site d'origine
Les fichiers de ressources ont une relation explicite avec les assemblys avec lesquels ils sont distribués, comme défini par AssemblyAssociatedContentFileAttribute. Toutefois, il peut arriver que vous souhaitiez établir une relation implicite ou inexistante entre un assembly et un fichier de données d'application, y compris lorsque :
Un fichier n'existe pas lors de la compilation.
Vous ignorez de quels fichiers votre assembly aura besoin jusqu'au moment de l'exécution.
Vous souhaitez pouvoir mettre des fichiers à jour sans recompiler l'assembly auquel ils sont associés.
Votre application utilise des fichiers de données volumineux, tels que des fichiers audio et vidéo, et vous souhaitez que les utilisateurs ne les téléchargent que s'ils choisissent de le faire.
Il est possible de charger ces types de fichiers en utilisant des modèles URI traditionnels, tels que les modèles file:/// et http://.
<Image Source="file:///C:/DataFile.bmp" />
<Image Source="http://www.datafilewebsite.com/DataFile.bmp" />
Toutefois, les modèles file:/// et http:// requièrent que votre application bénéficient de la confiance totale. S'il s'agit d'une XAML browser application (XBAP) lancée à partir d'Internet ou d'un intranet, et qu'elle n'a besoin que du jeu des autorisations prévues pour des applications lancées à partir de ces emplacements, des fichiers libres ne peuvent être chargés qu'à partir du site d'origine de l'application (emplacement de lancement). De tels fichiers sont dénommés fichiers du site d'origine.
Les fichiers du site d'origine sont la seule option pour les applications bénéficiant d'une confiance partielle, bien qu'ils ne se limitent aux applications bénéficiant d'une confiance partielle. Les applications bénéficiant d'une confiance totale peuvent quand même devoir charger des fichiers de données d'application dont ils n'ont pas connaissance lors de la génération ; bien que des applications bénéficiant d'une confiance totale puissent utiliser file:///, il est probable que les fichiers de données d'application seront installés dans le même dossier ou sous-dossier que l'assembly d'application. Dans ce cas, l'utilisation du référencement du site d'origine est plus facile que l'utilisation de file:///, parce que l'utilisation de ce dernier requiert que vous résolviez le chemin d'accès complet du fichier.
Remarque |
---|
Les fichiers du site d'origine ne sont pas mis en mémoire cache avec une XAML browser application (XBAP) sur un ordinateur client, alors que les fichiers de contenu le sont.Par conséquent, ils sont téléchargés uniquement lorsqu'on le demande spécifiquement.Si une XAML browser application (XBAP) contient des fichiers multimédia volumineux, configurer ceux-ci comme fichiers du site d'origine signifie que le lancement de l'application initiale est beaucoup plus rapide, et que les fichiers sont téléchargés uniquement à la demande. |
Configuration des fichiers du site d'origine
Si vos fichiers du site d'origine sont inexistants ou inconnus lors de la compilation, vous devez utiliser des mécanismes de déploiement traditionnels pour garantir que les fichiers requis seront disponibles lors de l'exécution, y compris à l'aide du programme de ligne de commande XCopy ou de Microsoft Windows Installer.
Si vous savez lors de la compilation quels fichiers vous aimeriez voir situés sur le site d'origine, mais que vous souhaitez toutefois éviter une dépendance explicite, vous pouvez ajouter ces fichiers à un projet Microsoft build engine (MSBuild) comme élément None. Comme avec les fichiers de contenu, vous devez définir l'attribut MSBuildCopyToOutputDirectory pour spécifier que le fichier du site d'origine est copié vers un emplacement qui est relatif à l'assembly généré, en spécifiant la valeur Always ou la valeur PreserveNewest.
<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" ... >
...
<None Include="PageSiteOfOriginFile.xaml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
...
</Project>
Remarque |
---|
Dans Visual Studio, vous créez un fichier du site d'origine en ajoutant un fichier à un projet et en définissant son Build Action à None. |
Lorsque le projet est généré, MSBuild copie les fichiers spécifiés dans le dossier de sortie de génération.
Utilisation de fichiers du site d'origine
Pour charger un fichier du site d'origine, vous pouvez appeler la méthode GetRemoteStream de la classe Application, en passant URI qui identifie le fichier du site d'origine souhaité. GetRemoteStream retourne un objet StreamResourceInfo, qui expose le fichier du site d'origine en tant que Stream et décrit son type de contenu.
À titre d'exemple, le code suivant montre comment utiliser GetRemoteStream pour charger un fichier du site d'origine Page et le définir comme contenu d'un Frame (pageFrame).
' Navigate to xaml page
Dim uri As New Uri("/SiteOfOriginFile.xaml", UriKind.Relative)
Dim info As StreamResourceInfo = Application.GetRemoteStream(uri)
Dim reader As New System.Windows.Markup.XamlReader()
Dim page As Page = CType(reader.LoadAsync(info.Stream), Page)
Me.pageFrame.Content = page
// Navigate to xaml page
Uri uri = new Uri("/SiteOfOriginFile.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetRemoteStream(uri);
System.Windows.Markup.XamlReader reader = new System.Windows.Markup.XamlReader();
Page page = (Page)reader.LoadAsync(info.Stream);
this.pageFrame.Content = page;
Bien que l'appel de GetRemoteStream vous donne accès à Stream, vous devez exécuter le travail supplémentaire de conversion vers le type de la propriété avec lequel vous le définirez. À la place, vous pouvez laisser à WPF le soin d'ouvrir et de convertir Stream en chargeant directement un fichier de ressources dans la propriété d'un type à l'aide du code.
L'exemple suivant montre comment charger directement un Page dans un Frame (pageFrame) à l'aide du code.
Dim pageUri As New Uri("pack://siteoforigin:,,,/Subfolder/SiteOfOriginFile.xaml", UriKind.Absolute)
Me.pageFrame.Source = pageUri
Uri pageUri = new Uri("pack://siteoforigin:,,,/SiteOfOriginFile.xaml", UriKind.Absolute);
this.pageFrame.Source = pageUri;
L'exemple suivant est l'équivalent sous forme de balise de l'exemple précédent.
<Frame Name="pageFrame" Source="pack://siteoforigin:,,,/SiteOfOriginFile.xaml" />
Régénération après modification du type de build
Après avoir modifié le type de build d'un fichier de données d'application, vous devez régénérer l'application entière pour vous assurer que ces modifications sont appliquées. Si vous générez seulement l'application, les modifications ne sont pas appliquées.