Proper Localization of a Winforms Application

How to make multi-language app in Winforms?

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

Windows forms application localization problem?

Resx files are in XML to begin with. You don't need to "add more resx" when you add language, at least you do not have to add them to your solution/project. What you need is to apply proper build process (I suspect that you build your application directly from Visual Studio, which is not very good idea) - you could use MSBuild to do that. In that case, all you need to do is to place translated files in their right paths and start building.

There are also other localization methods for Winforms applications - for example you might want to try WinRes.

How do I change the culture of a WinForms application at runtime

This worked:

private void button1_Click(object sender, EventArgs e)
{
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("fr-BE");
ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1));
resources.ApplyResources(this, "$this");
applyResources(resources, this.Controls);
}

private void applyResources(ComponentResourceManager resources, Control.ControlCollection ctls)
{
foreach (Control ctl in ctls)
{
resources.ApplyResources(ctl, ctl.Name);
applyResources(resources, ctl.Controls);
}
}

Be careful to avoid adding whistles like this that nobody will ever use. It at best is a demo feature, in practice users don't change their native language on-the-fly.

Proper way to change language at runtime

I believe the solution shown in Hans Passant's comment might be the only (general) solution.

Personally, I use this base class for all forms that need to be localized:

public class LocalizedForm : Form
{
/// <summary>
/// Occurs when current UI culture is changed
/// </summary>
[Browsable(true)]
[Description("Occurs when current UI culture is changed")]
[EditorBrowsable(EditorBrowsableState.Advanced)]
[Category("Property Changed")]
public event EventHandler CultureChanged;

protected CultureInfo culture;
protected ComponentResourceManager resManager;

/// <summary>
/// Current culture of this form
/// </summary>
[Browsable(false)]
[Description("Current culture of this form")]
[EditorBrowsable(EditorBrowsableState.Never)]
public CultureInfo Culture
{
get { return this.culture; }
set
{
if (this.culture != value)
{
this.ApplyResources(this, value);

this.culture = value;
this.OnCultureChanged();
}
}
}

public LocalizedForm()
{
this.resManager = new ComponentResourceManager(this.GetType());
this.culture = CultureInfo.CurrentUICulture;
}

private void ApplyResources(Control parent, CultureInfo culture)
{
this.resManager.ApplyResources(parent, parent.Name, culture);

foreach (Control ctl in parent.Controls)
{
this.ApplyResources(ctl, culture);
}
}

protected void OnCultureChanged()
{
var temp = this.CultureChanged;
if (temp != null)
temp(this, EventArgs.Empty);
}
}

Then instead of directly changing Thread.CurrentThread.CurrentUICulture, I use this property in static manager class to change UI culture:

public static CultureInfo GlobalUICulture
{
get { return Thread.CurrentThread.CurrentUICulture; }
set
{
if (GlobalUICulture.Equals(value) == false)
{
foreach (var form in Application.OpenForms.OfType<LocalizedForm>())
{
form.Culture = value;
}

Thread.CurrentThread.CurrentUICulture = value;
}
}
}

Regarding windows form localization C#

It's pretty simple.

CurrentCulture is the culture assigned for thread to be used in various culture-specific methods. To example, ToString() one.

CurrentUICulture is

used by the Resource Manager to look up culture-specific resources at run time.

By setting both you ensure what all ToString() works correctly and your form resources are loaded from appropriate satellite.

Regarding usage, you may think to provide user with option to change language. To example, I have native German windows, but I set English culture in it (date format and default culture for console applications), while I speak Russian. Which language do you think I will chose when using your software? =P

By default, either take language chosen in installer (if you have installer in multiple languages and options to change it there) or current Windows user language preferences.


One possible scenario:

Preconditions: application is already localized, satellites are there (if not, read this). I don't like satellites myself, but they are easy to start with.

When application starts, you create a list of available languages (either statically or by enumerating satellites).

string[] Languages = new[] {"en", "fr", "de", "ru"};

Then, if application start for the first time (to example, you have string language setting and it's by default null or "", this would be a flag what no language is selected yet), you detect default os language

var language = CultureInfo.InstalledUICulture.TwoLetterISOLanguageName; // to ex, "fr"

and if it's in your list, then you set

Thread.CurrentThread.CurrentUICulture =
Thread.CurrentThread.CurrentCulture = new new CultureInfo(language);

Otherwise, if you don't have this language, then use "default" language (to example, "en"). If its done at at the start of your application, then any further constructed and used window will use proper resources.

User should be able to change language. Give him possibility to chose one of available Languages. In winforms you will have to reload forms after change culture. Easiest solution would be to simply tell user what "software restart is required".

localize a picturebox image from a resource from a satellite library

  1. Please check this page:
    http://msdn.microsoft.com/en-us/library/y99d1cd3(v=vs.80).aspx
    It is about how to localize a string and from which you will know we use different resource file for different language version.
    Here is the description of it from that page:
    "In general, you should use forms-based resources for all resources specific to a form in your Windows Forms application. You should use project resources for all non-forms-based user interface strings and images, such as error messages."
  2. Here is way and code about image:
    Localization of image resources in Windows Forms
    and a step by step solution here:
    Proper localization of a WinForms application

I've just completed a C# .Net 3.5 project with a similar problem. We were writing WinForms plugin for an existing multi-lingual application with 8 languages (including English).
This is how we did it:
Create all our forms and UI in the default language, English.
Put all our internal strings in a resource file (stuff not tied directly to a form like custom error messages and dialog box titles etc)
Once we had completed most of the work and testing we localised it.
Each form already had a .resx file but this was empty. We set the property 'Localizable' to true, the .resx file was filled with things like button sizes & strings.
For each of the other languages, we changed the 'Language' property on the form. We chose the basic version of each language eg: 'Spanish' instead of 'Spanish (Chile)' etc. so that it would work for every 'Spanish' dialect, I think.
Then we went through each control, translated its text and resized, if needed. This created a .resx per language and form combination.
We were then left with, for 8 languages, 8 .resx for each form and 8 .resx for the general strings. When compiled the output folder had the .dll we were creating and then a sub folder for each language with a .resources.dll in it.



Related Topics



Leave a reply



Submit