I wrote a small application that shall automatically start in either English or German. English is default and German would be used on a German Windows.
The problem:
The German strings aren't loaded on a German Windows, although the program recognizes the client as German.
Explicitly setting the current culture (in code) to German however will result in a German UI.
What I did:
I followed this guide: http://www.codeproject.com/Articles/299436/WPF-Localization-for-Dummies
I created copies of the Resources.resx in the Properties section
Now there are: Resources.resx, Resources.en-US.resx, Resources.de-DE.resx
I put all Strings in the three Resources files. Resources.resx and *.en-US.resx contain the exact same strings
The name of the strings are consistent, Access Modifier on all files set to Public
File Properties of the Resources: Build Action: Embedded Resource; Do not copy; Custom Tool: PublicResXFileCodeGenerator
Code:
private void InitLocalization() // Executed on startup
{
if (CultureInfo.CurrentCulture.Name != "de-DE") // only use german on german systems. Otherwise use english
{
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture("en-US");
}
else
{
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture("de-DE");
}
rm = new ResourceManager("SaveEye.Properties.Resources", Assembly.GetExecutingAssembly());
// Manually assign the correct text to XAML-elements
_SettingsTextBlock.Text = rm.GetString("Settings");
_StartWithWindowsCheckBox.Content = rm.GetString("Startup");
_SaveButton.Content = rm.GetString("SaveAndClose");
}
Basically, I just want to make sure that either the Resources.en-US.resx or Resources.de-DE.resx is loaded from the ResourceManager.
In the rest of the code I grab the Strings I need with rm.GetString("").
This works just fine with English. I can even manually set the CurrentCulture to de-DE at the beginning of the InitLocalization-Method and then all German strings are loaded. But as I said, on other systems that are de-DE by default, the German strings are not loaded.
What am I doing wrong?
Regards
It is the CurrentUICulture that will affect which resources are loaded, and the CurrentCulture that will affect date and number formatting. A lot of people get these two confused.
You should probably be testing CurrentUICulture if you're trying to either set, or determine what string resources to retrieve. There is a big difference between a machine running with German date and number formats (CurrentCulture) and a machine running with a full German Language Pack installed and activated (CurrentUICulture).
Your sample code is using CultureInfo.DefaultThread(UI)CurrentCulture which will control the behaviour of all new threads created but this will default to whatever the main thread is using anyway so if it was already in German, you shouldn't need to explictly set it as such.
You can test the resource loading behaviour by updating your InitLocalization() method and setting Thread.CurrentThread.CurrentUICulture explicitly to "de-DE" to see if the German resources start loading. Then verify that the CurrentUICulture is really set to "de-DE" and not just the CurrentCulture. It's possible the German machine has German date/number formatting (CurrentCulture) but isn't using a German language pack (CurrentUICulture).
EDIT: In response to your comment, if you're already using CurrentUICulture correctly and the machine really has a full German UI but the German resources still aren't appearing, you should check that the German satellite resource file is actually being deployed.
The German resources are contained within a separate assembly named de-DE\MyApp.resources.dll and must reside in the same folder as the executable and stay within the de-DE folder (so you have \Folder\MyApp.exe and \Folder\de-DE\MyApp.resources.dll). The default resources (the ones in Resources.resx stay in the main executable and are the ones the ResourceManager falls back to if no more appropriate resource is found).
You didn't specify how you were deploying the application, but if you run you can use the 'Open in Explorer' (or Dateipfad Öffnen on the German machine) feature of Task Manager to take you to deployed folder of the running application so you can check that the de-DE folder is there (I only mention doing it this way because if you ClickOnce deploy the application it can be hard to find the installation folder).
If you are using ClickOnce and you publish with Visual Studio, you can control the files included during publishing by right-clicking the project and selecting properties then navigating to the 'Publishing' tab. The 'Application Files' button will show you a list of all the files included when publishing. Your de-DE satellite resource file should be set to 'Include'.
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 my loacalized *.resx files in another project to which I set a reference (it's a solution with mulltiple projects, so we have a *.Common project where we have styles, localization...). by now I have two *resx:
TextObjects.resx ------> english/invariant
TextObjects.de.resx --> german
How can i get these Files (the cultures of it)? Because I use WPFLocalizeExtension the *.resx-files need to be embedded resources.
I found only a way to watch inside the Resourcefile and get it's Keys, but not how many and which files i have.
Also I face two other problems:
The default invariant Language ist shown as this. Is there a way, without an Converter, to show it as english?
I like do set the systems CurrentCulture as first culture. If there is no localization for that the Extension correctly uses the Invariant Localization. BUT if the language doesn't exist it still get added to the MergedAvailableCultures and is as a result also shown in the ComboBox to which i bound this list. How can I avoid this?
I'm making an app in C#, with a lot of forms and other stuff.
I wanted to localize it, so I used the integrated localization functions in VS.
The app was originally in French (cause I am) with English translation RESXes, but now that it is on Codeplex with some other developers who doesn't speak french, I want to change the "default" language in the app and the RESX files so they can translate to other languages without reading French.
Cause when you choose another language in VS Form Designer, it shows the default language (here, French). I tried to rename all the files, but the problem is all the form properties are stored in the default RESX, the French one, so if I rename, it will break all the stuff. Is it possible to change the default language to English?
EDIT: I think I need to be more precise.
The app is originally in French. Then I localized it in English. There is now a MainWindow.resx that contains form properties + original french localization and a MainWindow.en-US.resx that contains ONLY english localization. So if in the Designer, in "Language" I choose "(default)" it shows me the MainWindow.resx FRENCH, and if I want to translate, It shows me the French texts. To make the translation more easy for the other developers, I want to make the MainWindow.resx ENGLISH localization and create a seperate MainWindow.fr-FR.resx. I also tried to change "Neutral Language" in AssemblyInfo.cs, no effect.
While you could do renames in file system to achieve neutral culture/resource change, you need to update project file as well, which is cumbersome. I found the simplest way was to do this via Visual studio extension named ResXManager.
Steps in detail:
1. Run & configure ResXManager
In VS: Tools -> ResXManager.
Choose configuration tab (below)
Disable option "Confirm adding new resource files". Otherwise you would have to click later per each file to accept its creation.
Set Neutral Resource language so it would show up with a correct flag for your viewing pleasure.
Switch back to main tab where you see all solution resources with translations side-by-side.
2. Extract neutral culture resources as explicitly French
Adda a new column for French using the "Add new language" button in the toolbar.
Copy all French resources from existing neutral language column (CTRL-SHIFT-DOWN helps top select full column)
Paste all resources to new French column.
Note that ResXManager will create new resx files for you and add them to project file.
3. Set neutral culture reousrces to English ones
Copy all English resources from specific culture column
Paste all resources to Neutral culture column
4. Inform .Net that neutral culture is now english
[assembly: NeutralResourcesLanguage("en-GB", UltimateResourceFallbackLocation.MainAssembly)]
5. Remove explicit English resx files.
Since the neutral resx files now already contain english resources then you don't need to keep them the culture-specific ones. Unfortunately ResXManager didn't seem to have a button for this but you can I chose to use VS solution manager filter "en-GB.resx" and deleted all files it found. Again, doing it within VS automatically updates your project file.
All done.
You can change the CurrentCulture and CurrentUICulture in your application through code.
It's the same approach that is used to change the apps language at runtime.
Have a look at this code:
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
Hope it helps.
I've got a WPF application that I'm modifying to support localization. My program is part of a suite of products that my company offers. We have created a resource DLL that contains all of the strings that need to be translated for all of our products. I've added a reference to this DLL to my program, added string resources to it, and modified my code to use the string resources instead of hard-coded strings. Everything works fine when I run my program in English.
We have had the string resources translated into Spanish. I've created a resx file with the Spanish translations in it. I've rebuilt my application. Now I want to see the Spanish text appear in my program without having to change my computer's culture settings.
It's not necessary for the program to change culture settings on the fly. The program will run in one language only for a particular installation.
The program has an App.config file. Short of adding a custom setting with the culture information in it, how do I tell my program to run in Spanish?
You could just define a key in your App.config like this
<configuration>
<appSettings>
<add key="DefaultCulture" value="es-CO" />
</appSettings>
</configuration>
and in your application read that value and set the culture
CultureInfo culture = new CultureInfo(ConfigurationManager.AppSettings["DefaultCulture"]);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
In the example of the config I set it to Spanish-Colombia
This is a list of culture codes
I decided to add this answer because while #MauricioGarcia's answer works if you want to always display a particular language on a machine with multiple language packs installed on it, no matter what the current region settings on the machine are, we didn't implement it that way.
Instead, we just use whatever CultureInfo objects are set in the current Thread.CurrentThread.CurrentCulture and Thread.CurrentThread.CurrentUICulture properties. When you set the region settings on your computer to a particular location and language, these properties are automatically changed. So they're always right & we don't have to add any code to change anything.
Interestingly, the object in the CurrentUICulture property is used to determine which language strings to display and the object in the CurrentCulture property is used to format numbers & DateTime.
We would like to employ satellite assemblies to contain various locale dependent resource files.
Question is ... do we need to link the default culture?
We have a separate project which will contain all of our different culture resource files. As is shown below, we have the project with two resource files inside of it.
ProjRES
Resource.resx
Resource.it-IT.resx
I am assuming that the "Resource.resx" will act as the default culture and if the Italian culture is selected, the application will adopt the it-IT resource file.
What do we need to do in order to get the rest of the application and projects to access the resource files. How do we set the namespaces for the resource files in order to be able to reference them.
Any help is greatly appreciated.
Basically,
if the current culture that the OS is using matches a certain culture that you've shipped, it will be used, if the current culture matches none of the cultures you've shipped, it will use the neutral culture.
In the most simplistic cases, you'll just need to include any of the localized dlls with the deployment and all will be fine..
When you're using resource managers, I think you can also pass in which culture you want to use explicitly, and the runtime will search for resources that match - this is better when a user of an ASP.Net site might have a certain culture preference that is different from that of the machine that the site is running on.
http://msdn.microsoft.com/en-us/magazine/cc163609.aspx seems to be a good starting point.