RandomEngy
RandomEngy

Reputation: 15413

Put translated resx files in a different folder in Visual Studio?

I've got a solution with 14 translations and 12 files and the "Resources" folder is getting a bit out of hand. Is there a way to put the translated files into a different folder so I can access the master English ones more easily?

I've noticed that you can change the namespace the designer file is generated in by setting the Custom Tool Namespace, but I haven't figured out how to pick up translations from a different folder. I toyed with the idea of using links to make a "shortcuts" folder and a "real" folder but you can't link to a file within the project structure and you can't link to the same file twice outside of the project structure. I thought about changing the namespace that the ResourceManager used based on the language but that would break the fallback behavior.

Is there any way to manage this so it isn't a giant list of files in Solution Explorer?

Upvotes: 3

Views: 3844

Answers (3)

David Maisonave
David Maisonave

Reputation: 188

The combination of Simon Mourier and RandomEngy answers help me get it working with Visual Studio 2022. I inserted the following text right before the first EmbeddedResource tag in the *.csproj file.

<EmbeddedResource Update="Translations\*.resx">
    <ManifestResourceName>$(TargetName).%(Filename)</ManifestResourceName>
    <!-- add this for all .resx files in a custom folder -->
</EmbeddedResource>

That will pull in all the resx files in the Translations folder. I had to use "Update" instead of using "Include". Every time I used include, I got a build error.

Upvotes: 1

Simon Mourier
Simon Mourier

Reputation: 139095

Let's say you want to place all the translated .resx files in a Translations folder, like this (note I have left the default and en versions in the root folder):

enter image description here

Then all you need to do is edit the MSBuild project file (from Visual Studio, right-click on the project node, 'Unload project', then 'Edit xxx.csproj'), and reconfigure each Resx file in this folder like this:

before:

  <ItemGroup>
    ...
    <EmbeddedResource Include="Resource1.en.resx" />
    <EmbeddedResource Include="Translations\Resource1.fr.resx" />
    <EmbeddedResource Include="Resource1.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resource1.Designer.cs</LastGenOutput>
    </EmbeddedResource>
    ...
  </ItemGroup>

after:

  <ItemGroup>
    ...
    <EmbeddedResource Include="Resource1.en.resx" />
    <EmbeddedResource Include="Translations\Resource1.fr.resx">
      <ManifestResourceName>$(TargetName).%(Filename)</ManifestResourceName> <!-- add this for all .resx files in a custom folder -->
    </EmbeddedResource>
    <EmbeddedResource Include="Resource1.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resource1.Designer.cs</LastGenOutput>
    </EmbeddedResource>
    ...
  </ItemGroup>

What it does is instruct underlying MSBuild tasks to use the manifest name you specificy instead of generating one automatically. The automatically generated one always uses the folder layout where the RESX resides in which is not what we want.

After compilation, the final satellite ConsoleApplication1.resources.dll file will be placed in the fr folder as usual, but its content will be the same as if the resx file was placed in the root folder.

Upvotes: 7

user844705
user844705

Reputation:

One way to achieve this could be to write a custom resource provider. Rick Strahl wrote one to serve resources from a database rather than RESX files. The class he inherits from is System.Resources.ResourceManager in mscorlib. Here is his implementation.

https://github.com/RickStrahl/Westwind.Globalization/blob/master/Westwind.Globalization/DbResourceManager/DbResourceManager.cs

Here is a link to the article, and he provides the code.

http://weblog.west-wind.com/posts/2014/Mar/31/Updated-ASPNET-Database-Resource-Provider

I realise you dont want to store the resources from a DB, but the principle should apply

Upvotes: 1

Related Questions