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"));
Related
I am trying to make my project multilingual. To do this, I created resource files for English and for other languages, for example:
langu.resx
langu.uk-UA.resx
In some of my projects, everything works fine. But some projects don't want to change the language.
With this System.Threading.Thread.CurrentThread.CurrentUICulture returns the correct culture
I tried changing the language in the program with the following code:
ResourceManager RM = new ResourceManager("PasteCurb.Properties.Lang.langu", Assembly.GetExecutingAssembly());
string day = RM.GetString("btnApplyText");
CultureInfo ci = new CultureInfo("uk-UA");
string dayrr = RM.GetString("btnApplyText",ci);
But in the variable dayrr, I get the value in English, instead of Ukrainian.
Anyone have any ideas?
Set the culture info like below and than you can access a text string by the name:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("uk-UA");
var text = Properties.Resources.btnApplyText;
When you access resources directly by using the ResourceManager be sure that the root name of the resource file is defined correctly. By default the root name doesn't include the language identifier.
It should look like below:
var rm = new ResourceManager("PasteCurb.Properties.Resources", Assembly.GetExecutingAssembly());
string dayrr = rm.GetString("btnApplyText", new CultureInfo("uk-UA"));
For more information see CultureInfo.CurrentCulture Property
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.
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");
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);
}
c# windows forms: How do you create new settings at run time so that they are permanently saved as Settings.Default.-- values?
Just in case that still matters to anyone:
You can dynamically add settings through Settings.Default.Properties.Add(...) and have these also persisted in the local storage after saving (I had those entries reflected in the roaming file).
Nevertheless it seems that the dynamically added settings keep missing in the Settings.Default.Properties collecion after loading again.
I could work around this problem by adding the dynamic property before first accessing it.
Example (notice that I "create" my dynamic setting from a base setting):
// create new setting from a base setting:
var property = new SettingsProperty(Settings.Default.Properties["<baseSetting>"]);
property.Name = "<dynamicSettingName>";
Settings.Default.Properties.Add(property);
// will have the stored value:
var dynamicSetting = Settings.Default["<dynamicSettingName>"];
I don't know if this is supported by Microsoft as the documentation is very rare on this topic.
Problem is also described here http://www.vbdotnetforums.com/vb-net-general-discussion/29805-my-settings-run-time-added-properties-dont-save.html#post88152 with some solution offered here http://msdn.microsoft.com/en-us/library/saa62613(v=VS.100).aspx (see Community Content - headline "How to Create / Save / Load Dynamic (at Runtime) Settings"). But this is VB.NET.
In addition to John's solution for saving, the proper method for loading is add the property, and then do a Reload() on your settings.
Your dynamic setting will be there!
For a full example, valid for using in library code, as you can pass the settings in ..
ApplicationSettingsBase settings = passed_in;
SettingsProvider sp = settings.Providers["LocalFileSettingsProvider"];
SettingsProperty p = new SettingsProperty("your_prop_name");
your_class conf = null;
p.PropertyType = typeof( your_class );
p.Attributes.Add(typeof(UserScopedSettingAttribute),new UserScopedSettingAttribute());
p.Provider = sp;
p.SerializeAs = SettingsSerializeAs.Xml;
SettingsPropertyValue v = new SettingsPropertyValue( p );
settings.Properties.Add( p );
settings.Reload();
conf = (your_class)settings["your_prop_name"];
if( conf == null )
{
settings["your_prop_name"] = conf = new your_class();
settings.Save();
}
Since the Settings class is generated at build time (or, actually, whenever you update the settings file from within the designer), you can't use this mechanism for dynamic scenarios. You can, however, add some collection or dictionary to the application settings and modify that dynamically.
You can't add settings directly (at least not without editing the config XML at runtime), but you can fake it.
In my case, I had a group of identical custom controls on the form, and I wanted to store the runtime state of each control. I needed to store the state of each control, since each one had different data it.
I created a new StringCollection setting named ControlData and placed my own data in there. I then load the data from that list and use it to initialize my controls.
The list looks like this:
Box1Text=A
Box1List=abc;def;foo;bar;
Box2Text=hello
Box2List=server1;server2;
In my startup code, I read through the key/value pairs like this:
foreach (string item in Properties.Settings.Default.ControlData) {
string[] parts=item.split('=');
parts[0] will have the key and parts[1] will have the value. You can now do stuff based on this data.
During the shutdown phase, I do the inverse to write the data back to the list. (Iterate through all the controls in the form and add their settings to ControlData.
How would you access the new settings that you have created? The point of the Visual Studio settings designer is that you can write code that uses these settings with compile-time checking of your code. If you want to dynamically create new settings for your app to use, you will also need to dynamically load them. For dynamic settings, you may want to look at the System.Configuration assembly, notably ConfigurationSection. You can create a custom configuration section with that, which you could use for dynamic setting addition/removal. You might use a ConfigurationCollection for that dynamic addition/removal.
INI files eh? Google turned up this INI library for .NET.
What you could do is create a new registry key.
Name the new key "Your program settings".
RegistryKey ProgSettings = Registry.CurrentUser.OpenSubKey("Software", true);
ProgSettings.CreateSubKey("Your Program settings");
ProgSettings.Close();
Now you can add String Identifiers and values.
RegistryKey ProgSettings = Registry.CurrentUser.OpenSubKey("Software\\Your Program settings", true);
ProgSettings.SetValue("Setting Name", value); // store settings
string settings = ProgSettings.GetValue("Setting Name", false); // retreave settings
ProgSettings.DeleteValue("Setting Name", false);
Besure to close the registry key when you are done to avoid conflicts with other parts of your program that may write to the registry.
Many comercial software applications use these methods.
stackoverflow has many examples about writing and reading to the registry.
This is much easyer then modifying the appconfig.xml file that is used when you create settings.
It took me a long time using the top two answers here plus this link (Create new settings on runtime and read after restart) to get it to finally work.
First of all, set your expectations. The answer here will create a new user setting and you can get its value the next time you launch your app. However, the setting you created this way will not appear in the Settings designer. In fact, when you relaunch the app and try to access the setting in your code, it will not find it. However, the setting you have created through code is saved in the user.config file (say jDoe.config) somewhere in your file system. For you to access this value, you have to add the setting again.
Here is a working example I have:
private void FormPersistence_Load(object sender, EventArgs e)
{
StartPosition = FormStartPosition.Manual;
// Set window location
var exists = Settings.Default.Properties.OfType<SettingsProperty>().Any(p => p.Name == Name + "Location");
if (exists)
{
this.Location = (Point)Settings.Default[Name + "Location"];
}
else
{
var property = new SettingsProperty(Settings.Default.Properties["baseLocation"]);
property.Name = Name + "Location";
Settings.Default.Properties.Add(property);
Settings.Default.Reload();
this.Location = (Point)Settings.Default[Name + "Location"];
}
}
Note:
My new setting's name will be resolved at run time. Name is really this.Name, which is the form's name. This is a base form that other forms can inherit from, so all the child forms will be able to remember their locations.
baseLocation is a setting I have manually created in Settings designer. The new setting I have is the same type. This way I don't have to worry about things like provider, type, etc. in code.
I see how what I wanted was the wrong idea. I'm porting a c++ app over to c# and it has a lot of ini file settings and I was looking for a shortcut to add them in. I'm lazy.