Set CurrentUICulture so it uses Resources.resx - c#

I'm working on localization in a small test WPF app and want to have English and French. I created Resources.en-CA.resx and Resources.fr-CA.resx.
When my test app starts, I have a startup window with a dropdown to select English or French. When the user clicks OK, a method is called to switch the culture based on the selected language, and then it loads another window which will show some resource strings in the selected language.
switch (selectedLanguage)
{
case "English":
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-CA");
break;
case "French":
Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-CA");
break;
}
The user can close then close this window and select a different language from the startup window and click OK to show the window again but with the new language they selected.
This is working but I also have a Resources.resx which is basically just a duplicate of Resources.en-CA.resx. I want to know if I can get rid of Resources.en-CA.resx, and if so, what do I set CurrentUICulture to so that it will use the values from Resources.resx when English is selected.
switch (selectedLanguage)
{
case "English":
//What would I do here?
break;
case "French":
Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-CA");
break;
}
I'm accessing the resources strings in code using
Properties.Resources.SomeLocalizedString

Yes, you can get rid of the Resources.en-CA.resx file if you like. You don't need to change anything as your current code will continue to work in the same way.
The localization in .Net is implemented with a fallback feature from the more specific to the more generic. If It cannot find the resource file for the specified language and local (e.g. Resources.fr-CA.resx ), it looks for the resource file of the language alone (e.g. Resources.fr.resx) and if it cannot find it, it uses the default resource file (e.g. Resources.resx).
For more details, see Hierarchical Organization of Resources for Localization.

Related

Windows Phone 8.1 app Multi language

I am creating windows phone app 8.1 in SilverLight with Visual Studio 2015. I am creating multi language app in English and Arabic. For that I have created Strings folder in the project with two folder of en-US and ar-KW with Resources.resw file in each folder.
I am x:Uid setting properties. For example Key:- Actual.Text Value:- Actual
<TextBlock x:Uid="Actual" TextWrapping="Wrap" MaxWidth="65" HorizontalAlignment="Center" />
Above is working very good. I have combobox with Item EN and AR. I am triggering SelectionChanged event to change the Language But the issue is when I stop the app and run it again than only it change the text and layout.
How can I do it at runtime without restart.
private void LanguageComboBoxName_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string selectedItem = (e.AddedItems[0] as ComboBoxItem).Content as string;
var RootFrame = Window.Current.Content as SlideApplicationFrame;
if (selectedItem == "EN")
ApplicationLanguages.PrimaryLanguageOverride = "en-US";
else if (selectedItem == "AR")
ApplicationLanguages.PrimaryLanguageOverride = "ar-KW";
RootFrame.Navigate(this.GetType());
}
As far as i remember it is not recommended by Microsoft to change language in a runtime (by overriding it) but you can do it by reloading the page. The easiest way is to put your combobox with the code on another page and there you will override language, so when you navigate back (and page will be reloaded) you will have what you want. Keep in mind that overriding language will not localize controls in the runtime (but it shouldn't be a great issue for you). You must restart the app to localize controls.
When you override language with this code:
ApplicationLanguages.PrimaryLanguageOverride = "xx-XX";
then it is saved and you don't have to override it again on the start. App will load with the overrided language.
Additionally when you localize the app it is good to override culture info because if you have some dates - they are shown properly for the culture (e.g. 12/01/2015 or 01-12-2015)
string lang = "en-US"; //default
var culture = new CultureInfo(lang);
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = lang;
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
There's one more important thing.
In your app manifest or what you have there, you need to set Generate app bundle to "Never". The reason is that when you uploaded packaged version to the store then your runtime localization won't work. You may be able to localize your app in the runtime with emulator or debug versions or even sometimes with deployed release versions. But you need to do that so when your app is in the store then there is no problem with localization and all of the string for languages can be accessed (because for packaged version some of them might not be if you haven't installed the language on your phone).
If you want the app to depend on a language through user selection, you'll need to store that selection and read it out on app start.
That way you can change the ApplicationLanguage when the app starts.
So in App.Xaml.cs look for the method InitializePhoneApplication() and add following lines ( or you could also try your approach here with ApplicationLanguages.PrimaryLanguageOverride )
string savedLanguage = string.Empty;
var hasSavedLanguage = AppSettings.TryGetSetting(Constants.LanguageSettingKey, out savedLanguage);
if (hasSavedLanguage)
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(savedLanguage);
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture;
}
Of course you'll also need to save the language when the user selected one from the combobox

Add / switch between embedded / linked resources at running time

I have the resources.resx in my c# code with some strings filled:
Text1,"Some Text"
and i can call it during running time by
Properties.Resources.Text1
which results in
"Some Text"
Now i want to have Text1 a different output (another language for example or something)
so that Properties.Resources.Text1 results in "Different Text".
How can i achieve this?
EDIT1: i discovered this but i was looking for a different approach with the resource files.
If you want to use different Resource Files, you can use the ResourceManager:
ResourceManager rm;
if (Configuration.Default.Culture == "en-US")
rm = new ResourceManager(typeof(Resource1));
else
// ...
String label = rm.GetString("Text1");
Save the the Culture in the User Settings, add a configuration file and define a user variable.
Configuration.Default.Culture= "en-US";
Configuration.Default.Save();
Updated question according to information
I am afraid you have to add another resource file for other culture. just look into this thread
How to use localization in C#
In reference to a comment:
get the current cultureinfo and load resources like this:
Thread.CurrentThread.CurrentCulture.ClearCachedData();
CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
if(currentCulture.Name == "en-US")
Console.WriteLine(resources.Text1);
else if if(currentCulture.Name == "ja-JP")
Console.WriteLine(resourcesJapan.Text1);

Problem with changing language using CultureInfo

Language is not getting changed when we are giving specific culture like "fr-FR" through Resource File.please help me out of it if any one knows ,Thanks in advance.
CultureInfo cinfo = new CultureInfo("fr-FR");
Thread.CurrentThread.CurrentCulture = cinfo;
Thread.CurrentThread.CurrentUICulture = cinfo;
The below code indicate that accessing the value through resource1 file according to the culture .
_inboxpage.Text = Resource1.Ready;
The resource files need to have a special naming convention to work transparently with different culture information.
You create a separate resource file for each language that you want to support or for a language and culture. Have one separate neutral resource file for the application to fall back upon in case the required key/value pair is not found.
ex:
Resources.resx //neutral resource file
Resources.fr.resx //french specific file
Resources.fr-FR.resx //French language for France
and so on.
You can get more details here:http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.aspx
Finally i got a solution that while doing Localization in Plugin Application we need to copy that culture folders like "fr-FR" to corresponding Main Application then it will works fine.

C# Windows Forms Localization Testing

I have setup a windows forms project to use localization so that it will support Chinese and English languages. I have built in a way of forcing the language to one or the other when the form loads. Before InitializeComponent() is called I have a bit of code that does this...
switch (Properties.Settings.Default.SelectedLanguage)
{
case "":
break;
case "English":
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
break;
case "Chinese":
try
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo("zh-CHT");
Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-CHT");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
break;
}
So when the SelectedLanguage property is set to "Chinese" the program should use the Chinese localization right? I tested this while debugging and it worked exactly as expected. That is, when SelectedLanguage == "Chinese" at the program start all the buttons and labels display in the Chinese text that I entered. When the SelectedLangugage == "English" everything is displayed in the English Text that I have entered.
The problem is that when I install this program and run it (not debugging) it doesn't work. Even on my development machine. No matter what SelectedLanguage is set to the program always displays the English Localization. I even put in a message box to pop up at the beginning of the program which displays `Application.CurrentCulture.Name' and it shows the Chinese culture name (zh-CHT) but it still displays everything in English. So what is the difference between what happens during debugging and during actual run time? And how can i fix it?!?
Make sure that your localized resources Dll are correctly installed.
Your installer should put resources files into sub-folders such as
zh-CHT\AssemblyName.resources.dll
It sounds like the english default is being used at all times, which would suggest that the resources you have set up for Chinese are not being included in the build. Double check your resources and make sure it is included in your deployment.

Thread.CurrentThread.CurrentUICulture not working consistently

I've been working on a pet project on the weekends to learn more about C# and have encountered an odd problem when working with localization. To be more specific, the problem I have is with System.Threading.Thread.CurrentThread.CurrentUICulture.
I've set up my app so that the user can quickly change the language of the app by clicking a menu item. The menu item in turn, saves the two-letter code for the language (e.g. "en", "fr", etc.) in a user setting called 'Language' and then restarts the application.
Properties.Settings.Default.Language = "en";
Properties.Settings.Default.Save();
Application.Restart();
When the application is started up, the first line of code in the Form's constructor (even before InitializeComponent()) fetches the Language string from the settings and sets the CurrentUICulture like so:
public Form1()
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(Properties.Settings.Default.Language);
InitializeComponent();
}
The thing is, this doesn't work consistently. Sometimes, all works well and the application loads the correct language based on the string saved in the settings file. Other times, it doesn't, and the language remains the same after the application is restarted.
At first I thought that I didn't save the language before restarting the application but that is definitely not the case. When the correct language fails to load, if I were to close the application and run it again, the correct language would come up correctly. So this implies that the Language string has been saved but the CurrentUICulture assignment in my form constructor is having no effect sometimes.
Any help? Is there something I'm missing of how threading works in C#? This could be machine-specific, so if it makes any difference I'm using Pentium Dual-Core CPU.
UPDATE
Vlad asked me to check what the CurrentThread's CurrentUICulture is. So I added a MessageBox on my constructor to tell me what the CurrentUICulture two-letter code is as well as the value of my Language user string.
MessageBox.Show(string.Format("Current Language: {0}\nCurrent UI Culture: {1}", Properties.Settings.Default.Language, Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName));
When the wrong language is loaded, both the Language string and CurrentUICulture have the wrong language. So I guess the CurrentUICulture has been cleared and my problem is actually with the Language Setting.
So I guess the problem is that my application sometimes loads the previously saved language string rather than the last saved language string. If the app is restarted, it will then load the actual saved language string.
I got the same problem. I figured out that Application.Restart() do not really make an absolutely restart, see MSDN.
So Application.Restart() do not call the initializing things within the forms constructor
like InitializeComponent(), more the "Applications are restarted in the context in which they were initially run."
So your code is correct
Properties.Settings.Default.Language = "en";
Properties.Settings.Default.Save();
public Form1()
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(Properties.Settings.Default.Language);
//...
InitializeComponent();
}
but it doesn't work this way with Application.Restart(). If You close the app and open it again your (new) settings are taken.
So we have to find a way to initialize the form again to make the new language settings happen.
Could you check what is your thread's CurrentUICulture?
I remember having a problem like yours; it was solved by reloading the resource dictionary containing the strings to be localized:
Thread.CurrentThread.CurrentUICulture = <new culture>;
ResourceDictionary newDict = new ResourceDictionary();
newDict.Source = localizedStrings.Source;
localizedStrings = newDict;
(and this approach worked dynamically as well; here is some more information).
You could manually change the language of the current form similar to this:
CultureInfo cInfo = new CultureInfo("en-US");
ResourceManager rm = new ResourceManager(GetType());
// For each control on the form, perform the translation manually (probably better in a loop)
control1.Text = rm.GetString(control1.Name + ".Text", cInfo);
// Now set the culture for all other dialogs
Thread.CurrentThread.CurrentUICulture = cInfo;
Hope that helps!
You could simply "reset" your application by closing the open forms and re-creating them. Then you could directly set the culture when the user changes the setting.
Also, try giving some debug output so you see what values are being set and if the culture is actually what you expect.
EDIT: My guess: Since the data has to be written to a file, and then loaded from that file, you may be restarting too quickly for the write to have been completed.
By using CurrentThread.CurrentUICulture, and then changing the form, you don't need to restart the application. Ref my old post here

Categories