I am developing a WinForm application which require localization.
If I try to set the Localizable property of the form to True and set the text for all the languages then every thing works fine.
What I want is to maintain all languages resource files in a separate folder (one file for each form).
-Project
-Resources
-Language
frmFirstForm.en-US.resx
frmFirstForm.en-GB.resx
frmSecondForm.en-US.resx
frmSecondForm.en-GB.resx
frmFirst.cs
frmSecond.cs
In my resource file I have defined all strings as follows:
**Key Value**
lblName Name
lblAddress Address
.....
The key is my control names, I will also keep form specific strings in the resource files. Now the issue is when I compile the solution, it do generate the language files but while running the application it just displays the default values. I don't even know whether the localized resource file is loaded or not. Also, though I have specified two separate form files but while compiling the system is generating only one single resource file per language for a project (means no separate resource file for FirstForm and SecondForm).
Is there any way where the form controls are changed as per the specified localized thread?
I have already added the following line in my main application Program.cs file:
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-GB");
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
Please suggest me how to proceed with this..
#Ashish : this is what you want exactly!!!!
Related
Good evening,
I happen to have an issue with Winforms and Resources.resx.
The app I'm working on is built via 'Winforms App' template selectable via Visual Studio.
The issue I'm having is kind of outside of winforms localization - which I think is important to mention.
Here's my issue:
- I've created a 'HistoryManager' class, which has only one method and one action to perform - add a history to the SQL database.
- I've created Resource.resx file, entered a format string into it under "MsgTaskAdded" which is equal to "Task {0} has been added to {1}".
- The said string adds to the database flawlessly.
Resources.resx works well - if I change MsgTaskAdded resource string, it changes what will be added to database .
Now, the issue I'm having is.
- I've created a Resources.de-DE.resx file, copied strings from Resources.resx and translated to german.
- Changed CurrentThread.CurrentCulture and CurrentThread.CurrentUICulture to 'de-DE'.
As a result, the text added to database is STILL in english, as if the file wasn't found and it fell back into using the default Resources.resx.
Make certain that your Resources.de-DE.resx file is contained within the Properties folder of your project, and that it has a Build Action of Embedded Resource, so that it gets properly associated to your default Resources.resx during compile. The culture settings on CurrentThread also need to happen before the call to the database, ideally somewhere in your static void Main() function before the Application.Run(…) call.
This should produce a culture-specific folder in your bin\<build_configuration> folder that contains a file named <your_app>.resources.dll. If needed, you can crack this open with a tool like ILSpy or Reflector to verify that the translated resources exist in the expected place within the assembly.
Maybe the reason in that how you're changing the thread culture. I did exectly what you did and its worked. That is how I've changed the culture
static void Main(string[] args)
{
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("de-DE");
Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("de-DE");
Console.WriteLine(Resources.Hello);
}
it prints "Hallo"
I found a solution.
If you guys ever have issue with the Resources.resx, make sure the localized file isn't: Resources.de-DE.resx or Resources.pl-PL.resx, instead - use only the first bit (Resources.de.resx) and make sure to open the file and set accessors to 'Internal' so it generates you a Designer file with proper code.
I have an application that I am developing that is made with Window Forms. For localizing all my Labels, ToolStripMenuItems, Buttons, etc I use resx resource files. Specifically to localize my application for German, I open my Main.en-CA.resx file in winres. I then go through all the terms found in the form and change them to their German translation. I then save the file to Main.de-DE.resx. I now have a Main.en-CA.resx file and a Main.de-DE.resx file. In my code I then only have to change the current culture to whatever language I want and apply the change to all my Labels, Controls, Buttons, etc. For example something like this:
System.Threading.Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(language);
// Must re-apply resources after changing the culture
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main));
resources.ApplyResources(this, "$this");
foreach (Control c in this.Controls)
{
resources.ApplyResources(c, c.Name);
}
This seems to work great for all Labels etc that do not change. I do however have entries that are changed. For example I might have a dropdown ComboBox that is filled with the entries: "Apple", "Banana", "Orange". Or I might have some error messages: "Missing Input", "Cannot find xml file" that are only sometimes displayed. Now I suppose maybe for the error messages I could just have Labels and selectively change their visibility depending on whether they need to be shown, however for the dropdown ComboBox these entries might change depending on say which file the user loads.
I am wondering then, is there a way to store these entries in the resx files and then access them from my code. I tried opening the resx files and adding them manually (i.e. without using winres) but attempting to do this resulted in the warning:
You are trying to edit a resource file that is a part of another project item (such as a form or control). Editing this item could corrupt the project item, and you will have to recover it by hand. In addition, changes made to this resource file may be lost if further changes are made to the project item.
Do you really want to edit this file?
This sounded like a bad idea so I didn't try that any further. Additionally I am not sure on how I would access the terms in the file manually. I am very new to windows forms and resource files (this is my first time using them) so I realize this might be a simple question but I have had trouble finding information on how exactly to do this.
Ok as it turns out I have uncovered how I can achieve what I am looking for. Ok from the SO post I can access any strings stored in the files Resource.resx by the code:
myLabel.Text = Properties.Resources.MissingController;
where MissingController is a key (i.e. Name) in the file Resources.resx.
Therefore all I need to do is add additional resource files such as Resource.de-DE.resx in the case of German and fill in the translations (i.e. the values in the resource file) corresponding to the same keys (i.e. the names in the resource file).
The Resources.resx file looks like:
and the Resources.de-DE.resx looks like:
As mentioned in the question I had already created some resource files for translating my forms but I had used winres. Whereas they had been located under my Main.cs [Design] file, the Resources.resx and Resources.de-de.resx are located under Properties. Because I had used winres to make my resx files I think that meant I was not supposed to manually edit them hence the warning it gave?? I'm still not 100% sure about this.
Regardless I can now just manually add terms to my Resource.resx file as well as create different versions of this file for different languages and the localization will work. When right clicking on Properties and going Add->New Item and then selecting Resource, if you do not see the Resource file type as an option (as happened to me) then that might mean you need to add the development tools that did not get installed with your version of visual studio. You can achieve this by just running the visual studio installer again and clicking modify and adding the .NET development tools.
I am having an issue where when using the localizable property in the windows forms designer. I have a label that has its Text property set by a resource file, and I want that text to change to another string in the resource file when a button is clicked. There is no issue adding the new string to the resource files or getting the strings with a resource manager. The problem is that every time I open the form designer, the resource generator wipes out that new string that was manually added.
Q: Is there a way,using best practices, to have generated localization resources from the designer and manually created ones live happily together?
I was under the impression that the Microsoft documentation states not to mix project and form resource files for localization, which is why I'm not taking that approach. Though I may have misunderstood the rational as indicated in this document.
EDIT: Reproducible steps
1. Create a windows form (Form1) with a button (button1) and a label (label1)
2. set label1.Text = "Hello";
3. set the localizable property of Form1 in the designer to true
4. In the Form1.resx file that is generated, add a string resource named "strWorld" with a value of "world". When you start typing, click okay on the message box that appears; agreeing that you are foolish enough to modify the resource file that is part of the form.
Steps 5 and 6 optional
5. Add the following eventHandler
private void button1_Click(object sender, EventArgs e)
{
ResourceManager resources = new ComponentResourceManager(typeof(Form1));
label1.Text = resources.GetString("strWorld");
}
6. Build and start the application to verify that the button functions
7. return to the designer and nudge the button by a pixel or two (or change anything else)
8. return to Form1.resx to find strWorld gone.
I am trying to figure out how one can visually align elements in different languages, taking advantage of the form designer, have controls that change properties of elements from said resource files and stay within recommended practices. Does one have to roll their own code around this or use a 3rd party solution or is there just something that I'm missing? Surely this is a common enough issue.
I think Microsoft expect you to do define texts
in the designer or
in the source code
If you enable localization, texts you specify in the designer will be stored in the local resx files associated with the form or the user control.
For each property in the designer, you can specify one text only.
If you want to change the text at runtime, you should define the text in the source code, and update it from your code.
Microsoft would expect you localize this text using named resources, which would be defined in the Resources.resx file at project level. The localized versions would be in localized versions of Resources.resx.
(If you define additional resources of your own in the "local" resource file associated with a form, the designer will probably discard them.)
I don't know if that is "best practice", but I think that is how Microsoft expect you to work.
In the Shared project of my universal app I have two folders inside of the Strings folder, en-US and sv-SE. Inside of both folders I have Resources.resw files. These contain the strings for my app.
When I run the app I'm able to see the strings, mapped using x:Uid, but I'm not able to see the string when using the designer designer.
Moving the English Resources.resw file to the root of Strings generates an error, telling me there is no Resources.resw file for the default language (en-US). Also, it does not make the strings appear in the editor.
Is it possible to make the resources from a *.resw appear in the designer?
I'd be surprised if your other project actually works as you think. Strings in *.resw files are not automatically understood for the designer. Given this:
<TextBlock x:Uid="MyWelcomeMessage" />
In the designer would show an empty TextBlock because the designer doesn't get the localized resource at design-time. The recommendation is to use some placeholder values for those items you are localizing with resources.
We have a winform app that has been in development for some time. It has several images and control colours that create a branded experience. We have a second customer who would like the same product, but with different branding.
So we have lines of code in the control designer.cs files like:
this.BackgroundImage = global::MyNameSpace.Properties.Resources.background;
It seems like resource files are the way to go, as I could simply change the culture and have a separate resource file with different images.
But I don't want to change the culture (I don't want the display of dates, currency, etc.) to be altered and it just smells.
Can I change the resource file manually at runtime or compile time without having to change the culture?
Is there a better way to achieve this outcome?
Also, how do you / can you use resource files to set controls colours (e.g. change all backgrounds from black to red)?
You can read in the resources from a separate file that just had the resources (but doesn't depend on the globalized satellite assembly mechanism). You could also compile default resources with your main assembly as a fall-back.
You can use Resgen.exe to create a .resources file from, e.g., a .resx file and then use ResourceManager to read it:
//note that resourceFilename does NOT include the ".resources" extension
var rm = ResourceManager.CreateFileBasedResourceManager( resourceFilename
,resourceDir
,null);
this.BackgroundImage = (Image) rm.GetObject("background");
One option you could consider is to create a custom culture, so for example you could create a culture called
ClientA-fr-FR
ClientB-fr-FR
The you create resources for each and you should be able to set the Thread Culture approriately.
Here is a link "How to: Create Custom Cultures"