How to localize WPF Application with RESX files in subdirectories - c#

My team has some WPF projects written using XAML. We recently added a large number of local specific RESX files to each project. In order to keep things tidy, I was asked to store these files in [Project]>Localization>[locale]
Now, when we run the application on a non en-US locale, strings are pulled from the appropriate RESX file. We've tried to update Namespaces in the properties of the RESX files, as well as setting them to Public so that a resulting Designer is created.
The only way that we can get things to work is by moving the locale RESX files directly into the Project's Properties directory.
Is there anyway to update the XAML to search for locale RESX files in a subdirectory?
EDIT
XAML Codebase and Solution Explorer
I've attached an image of the problem for clarification.
Some code changes that we've tried:
1) We attempted to set the Namespace for xmlns:res="clr-namespace:[PROJECT].CoreUI.Localization"
2) Attempted to set the Namespace to xmlns:res="clr-namespace:[PROJECT].CoreUI"
3) We've also attempted to change the Custom Tool Namespace of the RESX file to match the current namespace My.Properties as well as CoreUI.Properties
We've also confirmed that the Access Modifiers for both Resources.resx and Resources.ru.resx (for example) are set to Public and that both Build Actions show "Embedded Resource"

Thanks for the help!
My colleague actually stumbled upon another post in here that we somehow missed during out countless searching:
Put translated resx files in a different folder in Visual Studio?
In short, we were thinking about making the project search down into subdirectories for the RESX files. In actuality, we need the RESX file to search for the already created designer further up in the chain.
<ItemGroup>
<EmbeddedResource Include="Localization\ar\Resources.ar.resx" >
<ManifestResourceName>$(TargetName).Properties.%(Filename)</ManifestResourceName>
</EmbeddedResource>
Entering the ManifestResourceName appears to tell the RESX file that we already have a Designer created and not to make a new one.
Thanks again for everyone's help!

You've to first include your folder in the namespace and mention project name like:
xmlns:resx="clr-namespace:Prism_Modules.MyResources;assembly=Prism_Modules"
Also you must include:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Finally, you should call values in resources as:
<dxb:BarButtonItem x:Name="menuFile" Content="{x:Static resx:Resources.mnuFile}" }" />

When moving .resx file to another folder/project, the .Designer.cs file that exposes resource members will still point to the old namespace and also Visual Studio will place it outside the .resx file.
To fix this, I simply deleted the generated .Designer.cs file and then after opening and saving .resx file, the Designer.cs file got generated with proper namespace and I could normally refer to it even from other projects. To generate .Designer.cs file for resource languages/files that have none just open .resx file and use the Access Modifier combobox and VS will create it for you.
I hope I was of any help.

Related

resx file access

When you create a new C# Windows Forms Application in Visual Studio 2012, It has a Properties folder containing a Resources.resx file.
How do I access this file?
I have tried:
ResourceManager rm=new ResourceManager("Resources.resx",typeof(MyClass).Assembly);
string s=rm.GetString("MyString");
But I get System.Resources.MissingManifestResourceException because for some reason it appends .resources to the filename so it's looking for Resources.resx.resources.
I then appended .resources to the filename to see if it might actually work. It didn't, same exception, why?
I also tried using the ResxResourceReader class but it looks for a resx file in a directory, and this specific resx file I'm trying to access is not stored in a directory, it's compiled in to my assemblies so that doesn't seem to be helping either.
I thought it'd be really simple, maybe it is and I'm just overlooking something?
If it's not simple, I might as well create a C# class and hard-code my strings (only type of resource I need right now).
And another question: If the resx file is compiled in to your exe, does that mean you can't change it's values during runtime?
It is plain simple (usually).
Use the Properties class!
Properties.Resources.MyString
The Properties folder you see in your Solution Explorer is not just a fancy folder ;p Visual Studio generates a class to access all your resources with ease.

Adding new strings to resource.resx not reflecting into Designer.cs

I am adding two new strings to our resource.resx but these newly added resources(strings) are not reflecting into the auto-generated Designer.cs file. I have rebuilt the project and also tried clean+build the project but no luck!
I have other resource files to support various international languages where also i need to these two new string resources
Please suggest.
Make sure the Custom tool property for your resx file is set to ResXFileCodeGenerator or PublicResXFileCodeGenerator. The .Designer.cs file should be regenerated every time you modify the resx file; if it's not, you can force it by selecting Run custom tool in the context menu for the resx file.
Right click the resx file in solution explorer, select "Run custom tool".
This generated/added the code in the .designer.cs file for the new strings in the resource file for me.
When editing the resource file in Visual Studio, check the Access Modifier drop down is not set to No code generation.
If it is then select the appropriate option from the drop down - Public or Internal.
You just need to :
& then do :
Tada! You got your new Designer.cs !
In JetBrains Rider, I had to right-click the resx file and select "Generate resources"
I had the same issue when I renamed my [YOUR_RESOURCE].resx file into [YOUR_RESOURCE].en-US.resx. It seems [YOUR_RESOURCE].Designer.cs no longer auto generates any code after you renamed the default [YOUR_RESOURCE].resx format to something like [YOUR_RESOURCE].en-US.resx
I came across this solution and it worked fine for me.
Close the solution
Edit the project file LastGenOutput tag for the resource file
Open the solution again and try
If you're looking to automate this process you can use resgen
resgen c:\development\test\properties\resources.resx /str:csharp

Invalid .resx file after renamed namespace

Consider the following situation:
In my Windows Forms appliation I have a form.
That form has a .resx file.
The form makes use of a class ("OtherClass") from another assembly ("Other.dll").
"Other.dll" is built in the same VisualStudio 2010 solution as the main application
(just a separate project in the same solution).
In the main project (the Windows Forms application) I have properly
added a reference to the "Other.dll" project.
Everything works well (as expected).
Now I need to change the namespace of the type contained in "Other.dll" from "Old.Namespace" to "New.Namespace":
In VS2010, I bring up the Properties window of the "Other.dll"
project
I change the namespace in the "Default namespace" text box from "Old.Namespace" to
"New.Namespace"
I change namespaces in related .cs files accordingly
I rebuild the modified "Other.dll" project. No errors. The modified "Other.dll" is produced OK.
Now comes the problem:
When I after this rebuild the whole solution, the compiler stops and reports that the .resx file of the form is invalid:
"Invalid Resx file. Could not load type Old.Namespace.OtherType, Other, Version 1.0.0.0, Culture=neutral, PublicKeyToken=null which is used in the .RESX file. Ensure that the necessary references have been added to your project. Line 1521, position 5"
Clearly, the .resx file still references the type with the old namespace from somewhere. That "somewhere" appers to be from inside the binary section of the .resx file!
Question:
How can I make the .resx understand that it must now reference the new type (with the changed namespace)?
Please help, I really don't know how to proceed here...
I've had the same problem and the solution was to remove the data sections from the resx file
I too had the same problem, and after trying several other options I followed Stefania Mereut's advice and deleted the data sections from the resx file. When I re-added the resources, it apparently rewrote the data sections correctly.
I had this problem when I was updating a reference to a new version of a dll. In my case, the references had the option "specific version" = true. In that case, it is not possible to deserialize an old version of a class inside the res file because it contains the version of the old class on it.
I changed the option on my refereces "specific version" from "true" to "false" and everything worked again.
You need to open the resx file manually and change the type name of this binary resource to the new correct type name. I'm guessing this is a non-standard (i.e. not a string or image) resource that's been added manually to the resx file directly.
I believe these can only be viewed in the 'Other' section of the ResX editor - they can't be added through it.

Changing Resource files (resx) namespace and access modifier

In my webproject I'm using 4 resources files in my App_GlobalResources folder. One of them (lang.resx) has been created before my arrival on the project. It has the correct namespace (WebApplication.App_GlobalResources) and access modifier : public.
On the other hand, the three others Resource files that I just created have a different namespace (Resources) and internal access modifier, and I can't change it on the Resource File Form from Visual Studio because it's disabled. If I try to change it directly in the designer.cs file, the modifications are cancelled on the next save of the file.
It's not a critical bug but it can be misleading for the others developers on the project to find different namespaces and access modifiers for the resources files they will use.
The quick answer is: Just open the Properties of the resource file and change the Custom Tool Namespace to the namespace you need.
Simple as that.
I'm not entirely sure where the problem lies yet, but I can tell you that you can solve it by changing the tool used to generate the code.
When I tried to follow this article, I also stumbled onto this problem. After downloading the source files as the author suggested, I noticed that the resource file that were already present had the following class in the "Custom Tool" property: "PublicResXFileCodeGenerator". Also, the "Build Action" property was set to "Embedded Resource", but I'm not sure if that's part of the problem.
Any new resource file that I created used the custom tool "GlobalResourceProxyGenerator". After overwriting this with the aforementioned "PublicResXFileCodeGenerator" seemed to solve the problem, whatever the real problem may be.
I also noticed that the present resource file was in the "2.0" format, whereas new files were in the "1.3" format. You can see this when you open the resx file using an XML editor (or by using "open with" from visual studio itself).
I hope you can make it work like this, it's not ideal though. It's likely to be an installation issue with Visual Studio 2008 and SP1, or something like that.
Update:
This blog entry may also help.
Or you can change the CustomTool attribute (tested in VS2010).
You just have to open the file properties of the resource file and
change the “Custom Tool” from “GlobalResourceProxyGenerator” to
“PublicResXFileCodeGenerator”, which is the default Tool for local
resource files. Next you have to change the “Build Action” to
“Embedded Resource”. You may also want to assign a proper Custom Tool
Namespace like “Resources” in order to access the file properly, but
this isn’t necessary...
Source
The resx picks up the namespace depending on the namespace specified in your Visual Studio project configuration. Update your project to have the right namespace, and the resx should inherit it (new ones for sure, not sure if existing ones will be fixed - they should).
Resource Files access modifiers are in the .csproj;
Changing directly the .csproj file should workaround this problem.
Look for the <Generator> element and set its value in accordance to the examples below:
A resource file with internal modifier looks like this,
<ItemGroup>
<EmbeddedResource Update="resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
where a resource file with public modifier looks like this.
<ItemGroup>
<EmbeddedResource Update="resources.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>

Form resources usage for programmatic strings?

Had a basic WinForm question: By default a resx file is created for every form or user control (along with the designer.cs). This resx works fine for all the controls and the text added to the controls via the UI.
I was wondering if I could use the same resx to add strings which have to be used programmatically and based on conditions, attached to the controls? Will the resx get overridden in any case and this custom strings be removed?
What is the best practice to follow in this case?
There's a strange problem with the string resources in the Resources.resx file. There's no obvious way that I ever discovered how to create a new resource table for another language with the IDE. It can be done by hand though. Follow these steps:
Project + Properties, Resource tab,
add the strings you want to use in
your program
Start Windows Explorer and navigate
to your project's Properties folder
Copy and paste the Resources.resx
file
Rename it to the culture you want to
use. For example:
Resources.fr-FR.resx
Back to VS, click the Show All Files
icon in the Solution Explorer window
Expand the Properties node, the new
resource file should be visible
Right-click it and select "Include
in project"
Select it, in the Properties window
set Custom Tool =
"ResXFileCodeGenerator"
Verify that Build Action is set to
"Embedded Resource"
Build your program. You should get a new folder in your project's bin\Debug directory with the satellite assembly, named projectname.resources.dll. This satellite assembly contains both the localized strings and any localized resource from the forms. Test that it works with code like this:
public Form1() {
System.Threading.Thread.CurrentThread.CurrentUICulture =
System.Globalization.CultureInfo.GetCultureInfo("fr-FR");
InitializeComponent();
textBox1.Text = Properties.Resources.String1;
}
The auto-generated ones get overwritten (I'm using 2005), so no I would not use the same file. I would suggest creating a separate area in your project for .resx files like this. Usually I create one .resx per form, matching the name, of course.
Edit: Here is a more detailed answer I gave recently to organize the file/folder structure when localizing your app with .resx files.
Or you can try this:
Add this code in main();
using System.Resources;
ResXResourceWriter rw = new ResXResourceWriter("Resources.de-DE.resx");
rw.AddResource("String1", "de");
rw.Close();
...
repeat for more files
Go to the bin directory and move the XML (resx) file(s) to perhaps the property folder.
Go to Step 5-9 above in nobugz post.

Categories

Resources