How to make multi-language app in Winforms? - c#

I have an application and I need to use two languages in that application.
For example :
English
Arabic
But I don't know how could I do that. Anybody can help me for this?
I need some examples in C# Windows Forms.

Using Localizable and Language Property of Form
Form class have Localizable and Language Property. If you set Localizable property to true, you can add controls to form for default language and set properties for default language. Then you can select another languages and change properties for those languages. This way, value or localizable properties will store in separate resource files for different cultures.
Note: A property is considered as localizable if it's decorated with [Localizable(true)] attribute. For example BackColor property is not localizable, but Text property is localizable.
Localizing Messages and Images using Resx Resource Files
The project has a Rseources.Resx file under Properties folder which you can use for localizing images and messages. Also you can add .resx Resource files to project. For example you can create a Strings.resx file and add some string key and values to it, then copy it as strings.en.resx and strings.fa.resx and edit values for those languages. Then you can use those resource values, For example:
MessageBox.Show(Properties.Resources.AreYouSure);
Will show the value of AreYouSure from Resources.Resx file with the current UI culture language.
If a resource key not found for a culture or the specified culture not found for the resource file, value of the key in neutral culture of the Resx file will be used.
Change the language at Run-time
You can set the culture of a application to Persian using:
System.Threading.Thread.CurrentThread.CurrentCulture =
System.Globalization.CultureInfo.GetCultureInfo("fa");
System.Threading.Thread.CurrentThread.CurrentUICulture =
System.Globalization.CultureInfo.GetCultureInfo("fa");
You should put the above code at start of your application or before showing a form.
More information
For more information and Example:
Globalizing Windows Forms
Walkthrough: Localizing Windows Forms
How to: Set the Culture and UI Culture for Windows Forms Globalization

Using a resource file might be easier in some cases.
Add a new resource file to the project in Visual Studio.
eg. en_local.resxfor english fr_local.resx for french.
Open the resource file, in the strings, name your string and put different translation in the value cell. For example: next station's value inen_local.resx is next station but in fr_local.resx can be Prochaine station.
example as below:
In the code, use public static ResourceManager rm = new ResourceManager("WindowsFormsApp1.en_local", Assembly.GetExecutingAssembly());
to select the language resource.
When you need to output any string to the application, use function GetString(), for example label1.Text = rm.GetString("welcome");

There are some missing parts in wwjih123's answer.
In VS2017
1-First of all create resource in projects root folder (Not in Resources folder). Name it like lang_en, lang_tr, lang_fr etc...
2-then object properties window leave Build action as Embedded Resource
3-inside the lang_tr.resx file add new string lbl_error and value "Hata" in turkish (whatever you like)
4- inside the class define variables as:
ResourceManager res_man; // declare Resource manager to access to specific cultureinfo
5-in class initialization after InitializeComponent();
Console.WriteLine("You are speaking {0}",
System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName);
res_man = new ResourceManager("MyApp.lang_"+ System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName, Assembly.GetExecutingAssembly());
lblError.Text = res_man.GetString("lbl_error");
if your ui language is Turkish it will automatically load the lang_tr.resx,
if english the lang_en.resx file will be loaded
etc...
good luck

Create an extension class and do as the following:
public static class TranslateToKurdish
{
public static void ToKurdish(this Control control,string kurdishText,float fontSize=10)
{
switch (control)
{
case TextBox textBox:
textBox.PlaceholderText = kurdishText;
textBox.RightToLeft = RightToLeft.Yes;
textBox.PlaceholderText = kurdishText;
textBox.Font = new Font("Calibri", fontSize, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)));
break;
case Label label:
label.Text = kurdishText;
label.RightToLeft = RightToLeft.Yes;
label.Font = new Font("Calibri", fontSize, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)));
break;
case Button button:
button.Text = kurdishText;
button.RightToLeft = RightToLeft.Yes;
button.Font = new Font("Calibri", fontSize, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)));
break;
}
}
}
then you can use in Form
if (userLanguage == stringLanguage)
{
isKurdishLanguage = true;
RightToLeft = RightToLeft.Yes;
RightToLeftLayout = true;
btnTruckTracking.Font = new Font("Calibri", 13.5F, FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
btnTruckTracking.ToKurdish(#"بارهه‌ڵگره‌كان",12);
btnSearch.ToKurdish(#"گـــه‌ڕان",12);
BtnProduct.ToKurdish(#"بـــه‌رهــه‌م",12);
btnCompany.ToKurdish(#"كــۆمپـانیـایه‌كـان",12);
btnUsers.ToKurdish(#"به‌كارهێنه‌ران",12);
btnClose.ToKurdish(#"داخســـتن",12);
}

Related

Set CurrentUICulture so it uses Resources.resx

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.

Get localized string resources before run (C# Winforms)

I need to get localized string resources before run (C# Winforms). I have custom control of button with printing text on event OnPaint. I can set culture for set location before running in the constractor of custom control and see erea for text in designer:
var culture = new CultureInfo("de-DE");
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
But when I try to get string resource before running I get neutral string resource instead of the German:
ResourceManager p = new ResourceManager("myProject.Properties.Resources",
Assembly.GetExecutingAssembly());
Text = p.GetString(ResourceNameForText, new CultureInfo("de-DE"));
How can I get the German string resurce in designer before running?
We have found a solution. We have created an open property in custom control, which calls stream reading and parsing method from Resources.de-DE.resx during design-time mode only.

managing MultiLanguage resources

I have created two resource files in my project GlobalRes.ge.resx and GlobalResources.en.resx
I receive language as an input parameters . I want to know how can I read my values based on language. for example if string lang = "en" then by globalres.welcome I should see WOLCOME but if I choose lang = "ge" then globalres.welcome should be willkommen
(I have already created the welcome line in both files)
The Resource Designer will load the appropriate text based on the CurrentUICulture
System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo("en-US");
bCancel.Text = Resource.Cancel;
In .NET 4.5 and later you can use the following properties to set the DefaultThreadCurrentCulture & DefaultThreadCurrentUICulture culture.
CultureInfo.DefaultThreadCurrentCulture = System.Globalization.CultureInfo.GetCultureInfo("en-US");
CultureInfo.DefaultThreadCurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo("en-US");

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

How to read global resource file

I have a window based application in c#. Where i am displaying some message box based on language selected.Its working fine with Form level resources but what if i want to access global resource file(project level).
ResourceManager res_man = new ResourceManager("Resources",typeof(Form2).Assembly);
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("ar-SA");
string s = res_man.GetString("String1");
MessageBox.Show("Arabic-" + s);
I tried this but any how not working
For updated ans
Access Modifier is by default internal. Did you use the PublicResXFileCodeGenerator ?
You can set the Access Modifier to public when you open the RESX file in Visual Studio. There is a dropdown box that can be found at the top of the form which changes the Access Modifier.
And after that you will be able to access :
var resxManager = new ResourceManager(typeof(Resource));
var currentString = resxManager.GetString("Practitioner", CultureInfo.GetCultureInfo("en-US"));
Here can be a related issue : Visual Studio - Resx File default 'internal' to 'public'
try to change Current Culture in place of UI culture -
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("ar-SA");
I am using following code for fetching specific value from Global Resource for specific culture -
ResourceManager myManager = new ResourceManager(typeof(Resources.Strings));
String currencySymbol = myManager.GetString("Currency", CultureInfo.GetCultureInfo("en-GB"));

Categories