Question Problème avec les ressources WinForms partagées entre les projets dans Visual Studio


J'ai déplacé toutes les ressources d'image dans une grande solution multi-projets vers un nouveau projet spécifiquement créé pour les ressources partagées.

L'ajout d'une nouvelle référence à d'autres projets où les images partagées sont utilisées fonctionne comme prévu. L'image dans le bouton sélectionné ci-dessous continue à apparaître dans le concepteur mais avec des problèmes.

Dans VS Designer, je ne parviens pas à sélectionner des ressources partagées dans l'éditeur d'images, mais à modifier manuellement le code du concepteur.

Plus précisément, dans la boîte de dialogue Editeur d'images (accessible à partir de la propriété "Image" d'un contrôle existant), sélectionnez "Sélectionner dans un fichier / une ressource ..." pour ouvrir la boîte de dialogue Sélectionner une ressource (illustrée). accéder à toutes les ressources du projet local (Resources.resx), je voudrais maintenant ajouter l’accès au nouveau projet de ressources partagées.

Comment cela peut-il être fait? Y a-t-il une meilleure façon?

alt text http://permalink.gennetten.com/SharedResourcesIssue.png


11
2017-07-08 20:43


origine


Réponses:


J'ai pu partager un fichier resx entre le projet et l'utiliser dans le concepteur dans VS 2008 SP1 (ne sais pas d'autres versions). Différemment pour les autres approches, les ressources sont partagées statiquement et dinamicalement, donc à l'exécution, il y a vraiment une copie des ressources partagées. Aucun gaspillage de mémoire ou de stockage, facilité de maintenance avec des tonnes de projets.

Suivez le guide et dites-moi si cela fonctionne pour vous:

  • Créer un projet de classe Ressources;
  • Créez un fichier de ressources (allez dans Propriétés -> Ressources du projet);
  • Déplacer le fichier de ressources (par défaut Resources.resx) vers le racine du projet;
  • Renommez le fichier de ressources Resources.resx -> GlobalResources.resx;
  • Modifiez le modificateur de fichier de ressources en Public (double-cliquez sur le fichier de ressources, "Modificateur d’accès" -> "Public");
  • Copier tout fichier de ressources sur le répertoire racine du projet;
  • Ajoutez n'importe quelle ressource au fichier de ressources en utilisant "Ajouter un fichier existant" et sélection des ressources sur le racine répertoire du projet.

Le projet dans l'Explorateur de solutions doit ressembler à ceci:

enter image description here

Maintenant, dans tout projet, vous avez besoin du fichier resx à partager, procédez comme suit:

  • Ajoutez le projet "Ressource" comme dipendance;
  • Modifiez manuellement le fichier de projet (* .csproj) et ajoutez les lignes suivantes dans le fichier de ressources ItemGroup (créez un fichier de ressources local si vous voulez le voir):

    <ItemGroup>
      ...
      <EmbeddedResource Include="..\Resources\GlobalResources.resx">
        <Link>GlobalResources.resx</Link>
        <Generator>ResXFileCodeGenerator</Generator>
        <LastGenOutput>GlobalResources.Designer.cs</LastGenOutput>
        <CustomToolNamespace>Resources</CustomToolNamespace>
      </EmbeddedResource>
      ...
    </ItemGroup>
    

De toute évidence, l'attribut "Include" doit être le chemin relatif correct vers GlobalResources.resx.

  • Utilisez les ressources du concepteur comme vous le demandiez.

Dans mon projet, les lignes suivantes sont générées et ajoutées automatiquement au projet lorsque je fais ceci:

<Compile Include="..\Resources\GlobalResources.Designer.cs">
  <Link>GlobalResources.Designer.cs</Link>
  <AutoGen>True</AutoGen>
  <DesignTime>True</DesignTime>
  <DependentUpon>GlobalResources.resx</DependentUpon>
</Compile>

S'ils ne sont pas ajoutés, ajoutez-les manuellement.

Maintenant, le projet devrait ressembler à ceci dans l'Explorateur de solutions (les fichiers similaires doivent être marqués différemment):

enter image description here

Deux dernières étapes:

  • Cliquez sur le lien "GlobalResources.resx" et sur le jeu de propriétés "Aucun" comme "BuildAction". "Espace de noms de l'outil personnalisé" doit déjà être défini sur "Ressources";

enter image description here

  • Cliquez sur le lien "GlobalResources.Designer.resx" lié et sur le jeu de propriétés "Aucun" comme "BuildAction".

enter image description here

Et vous avez terminé: à ce stade, vous devriez vraiment être en mesure d'utiliser les ressources que vous avez ajoutées dans la resx partagée dans le concepteur en sélectionnant "GlobalResources.resx" dans la boîte de dialogue "Fichier de ressources du projet" de votre question. Et comme dit, il est vraiment partagé, même à l'exécution! Dans le panneau Propriétés, vous devez voir l'espace de noms complet et la classe du projet externe. Si vous supprimez la dépendance sur le projet "Resource", il ne compile même pas. Si cela ne fonctionne pas pour vous, insistez jusqu'à ce que cela fonctionne et, au cas où, dites-moi où le guide est faux. Ça doit marcher! Faites le moi savoir.


20
2018-06-07 19:24



Je suis tombé sur le même problème récemment. Regardé autour de la documentation de MS mais n’a pu trouver aucune bonne solution. J'ai finalement réussi à faire en sorte que l'éditeur d'images du concepteur de WinForms reconnaisse les fichiers de ressources d'autres projets en utilisant la méthode décrite ci-dessous. C'est pirate - si quelqu'un a une solution de nettoyage à partager, postez-la. Je l'ai testé sur VS 2008 uniquement.

Avant de commencer, je dois dire que si vous souhaitez simplement rendre les éléments d'un fichier Resources.resx accessibles aux autres projets, vous pouvez simplement modifier ses propriétés et définir le modificateur d'accès de la classe générée sur public afin d'utiliser PublicResXFileCodeGenerator. La gymnastique ci-dessous n'est nécessaire que si vous voulez que les concepteurs de WinForms récupèrent les images dans ce fichier de ressources, comme décrit dans le post ci-dessus de Douglas.

Dites que votre solution a la disposition suivante. L'espace de nommage par défaut pour les différents projets (clic droit sur un nœud de projet dans l'explorateur de solutions -> Propriétés -> onglet Application) est important ici, j'ai donc mis ceci entre parenthèses après les noms des projets.

  • MySolution
    • SharedProject (espace de nommage par défaut = SharedProject)
      • SharedProject.csproj
    • WinFormsProject1 (espace de noms par défaut = WinFormsProject1)
      • WinFormsProject1.csproj
    • WinFormsProject2 (espace de noms par défaut = WinFormsProject2)
      • WinFormsProject2.csproj

Vous voulez créer un fichier de ressources dans SharedProject contenant des images pouvant être utilisées par WinFormsProject1 et WinFormsProject2.

Commencez par créer un nouveau fichier de ressources à la racine de SharedProject, appelons ça SharedResources.resx. Il est important que ce fichier utilise ResXFileCodeGenerator plutôt que PublicResXFileCodeGenerator pour des raisons qui apparaîtront plus tard.

modifier SharedResources.resx dans Visual Studio et ajoutez les ressources d'image que vous souhaitez partager. Visual Studio devrait également générer un fichier de classe pour vous à l'intérieur SharedProject appelé SharedResources.designer.cs.

Votre solution devrait maintenant ressembler à ceci:

  • MySolution
    • SharedProject (espace de nommage par défaut = SharedProject)
      • SharedProject.csproj
      • SharedResources.resx
      • SharedResources.Designer.cs
    • WinFormsProject1 (espace de noms par défaut = WinFormsProject1)
      • WinFormsProject1.csproj
    • WinFormsProject2 (espace de noms par défaut = WinFormsProject2)
      • WinFormsProject2.csproj

Si vous ouvrez SharedProject.csproj avec un éditeur de texte, vous devriez voir les entrées suivantes:

<EmbeddedResource Include="SharedResources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>SharedResources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<Compile Include="SharedResources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>SharedResources.resx</DependentUpon>
</Compile>

Vous devez maintenant rendre les ressources accessibles dans WinFormsProject1. Pour ce faire, vous devez modifier WinFormsProject1.csprojdans un éditeur de texte car certaines des propriétés à définir ne sont pas exposées dans Visual Studio.

Ouvrez le WinFormsProject1.csproj fichier et ajouter les éléments suivants dans un ItemGroup:

<Compile Include="..\SharedProject\SharedResources.Designer.cs">
    <Link>SharedResources.Designer.cs</Link>
    <AutoGen>True</AutoGen>
    <DesignTime>True</DesignTime>
    <DependentUpon>SharedResources.resx</DependentUpon>
</Compile>
<EmbeddedResource Include="..\SharedProject\SharedResources.resx">
    <Link>SharedResources.resx</Link>
    <Generator>ResXFileCodeGenerator</Generator>
    <LastGenOutput>SharedResources.Designer.cs</LastGenOutput>
    <CustomToolNamespace>SharedProject</CustomToolNamespace>
    <LogicalName>SharedProject.SharedResources.resources</LogicalName>
</EmbeddedResource>

Les choses clés ici sont CustomToolNamespace et Nom logique. Par défaut, Visual Studio utilise l'espace de noms par défaut du projet pour nommer les ressources et générer le fichier * .Designer.cs. Depuis SharedProject et WinFormsProject1 avoir différents espaces de noms par défaut le comportement par défaut provoque la ressource qui est incorporée dans WinFormsProject1 être incompatible avec le fichier * .Designer.cs qui se trouve à l'intérieur SharedProject. Cela peut être évité en substituant CustomToolNamespace et LogicalName.

Maintenant, faites la même chose pour WinFormsProject2.csproj. Revenez à Visual Studio. Vous remarquerez que vous avez modifié les fichiers csproj et demandé de recharger les projets - choisissez "reload". Vous devriez trouver que vous pouvez maintenant choisir des images de SharedResources.resx lors de la conception des formulaires dans les deux WinFormsProject1 et WinFormsProject2.

Essentiellement, tout cela fait que VS inclut le SharedResources.resx fichier de SharedProject dans le WinFormsProject1 et WinFormsProject2 projets. Il n'y a qu'un seul fichier source .resx (dans SharedProject), mais lorsque vous compilerez la solution, trois classes identiques seront appelées SharedProject.SharedResources, un dans chacune des trois assemblées, mais comme tous ont une visibilité interne, ils n’interféreront pas entre eux même si vous ajoutez une référence entre les projets.


7
2018-01-30 22:29



PARTAGE DES RESSOURCES ENTRE LES PROJETS DE VS2012

en 3 étapes faciles en utilisant uniquement le concepteur!

  1. créer un projet et ajouter vos ressources à partager comme d'habitude
  2. créer un autre projet et "ajouter en tant que lien" au fichier resources.resx du premier projet dans le dialogue "Ajouter un élément existant", accessible depuis le menu contextuel
  3. sélectionnez les images du fichier de ressources lié comme vous le souhaitez; Vous pouvez sélectionner cette option dans le menu déroulant "Fichier de ressources du projet" dans la boîte de dialogue "Sélectionner une ressource", accessible depuis le volet des propriétés.

VOILA!


6
2018-05-06 06:19



Vous devez seulement ajouter un nouveau projet de classe avec un fichier RESX où vous incluez les ressources (images, textes, etc.). Après, dans les autres projets, ajoutez une référence à ceci et utilisez le nom de la classe Resource afin d'accéder à la ressource requise, par exemple: Project.SharedImages.Upload_64x64 (le résultat est un bitmap prêt à être utilisé dans ce cas)


1
2017-09-16 00:50



Pour Visual Studio 2015+

Il existe un moyen simple et direct qui n’est pas pris en charge dans l’interface utilisateur de VisualStudio. Donc, si vous n'avez pas peur de modifier les fichiers du projet, lisez la suite.

Si vous ne l'avez pas déjà fait, ajoutez un nouveau projet partagé dans la solution.Add a New Shared Projecct

Si vous ne l'avez pas déjà fait, incluez le nouveau projet partagé en tant que référence de projet partagé dans votre projet de périphérique.enter image description here

Notez comment ce projet partagé est inclus dans le projet périphérique (.csproj fichier) de manière simple:

<Import Project="..\Common\Common.projitems" Label="Shared" />

Ainsi, même si l'interface utilisateur VS ne l'expose pas, tout dans le projet partagé (.projitems fichier) est inclus directement dans le projet périphérique. Ajout des définitions de ressources suivantes au projet partagé (.projitemsfichier) les inclura directement dans votre projet périphérique. Mais parce que le Resource L'élément n'est pas pris en charge par l'interface utilisateur VS pour les projets partagés, ces fichiers seront masqués et ignorés dans l'EDI.

<ItemGroup>
  <Resource Include="$(MSBuildThisFileDirectory)Resources\one 16x16.png" />
  <Resource Include="$(MSBuildThisFileDirectory)Resources\one 64x64.png" />
  <Resource Include="$(MSBuildThisFileDirectory)Resources\one.ico" />
  <Resource Include="$(MSBuildThisFileDirectory)Resources\two 16x16.png" />
  <Resource Include="$(MSBuildThisFileDirectory)Resources\three 16x16.png" />
  <Resource Include="$(MSBuildThisFileDirectory)Resources\four 16x16.png" />
  <Resource Include="$(MSBuildThisFileDirectory)Resources\five 16x16.png" />
  <Resource Include="$(MSBuildThisFileDirectory)Resources\six 16x16.png" />
</ItemGroup>

Enfin, alors que vos ressources de projet périphériques peuvent avoir des chemins relatifs (par ex. ".\Resources\main.ico"), ces ressources sont compilées dans votre projet périphérique avec des identifiants de base, non absolus ou relatifs. par exemple.:

<Window x:Class="Common.Shared"
  ...
  Icon="one.ico">
  <Window.Resources>
    <ResourceDictionary>
      <BitmapImage x:Key="one64" UriSource="one 64x64.png"/>
    </ResourceDictionary>
  </Window.Resources>

0
2017-08-02 21:27