Localizing Windows Forms Application

by Sajad Deyargaroo

To make software available for international users, it must accommodate the changes in different languages and cultures. Many times, the first version of the software is developed in English and changes are made to the existing software to accommodate the new language. Learn to avoid this bad practice.

Localizing Windows Forms Application

To make software available for international users, it must accommodate the changes in different languages and cultures. Many times, the first version of the software is developed in English and, when business moves from a single country to international market, changes are made to the existing software; this results in bad design and a lot of maintenance costs. So, the needs of world-ready software must be considered at the beginning of the project.

In the early days, you wrote a lot of code for mundane tasks of localization. Now, with the .NET Framework and Visual Studio IDE, these tasks have become very easy. Now you can add localization features to your applications without putting in much effort. There are many differences in how you localize the ASP.NET and Windows Forms application. In this article, I will walk through the localization of the Windows Forms application.

Step 1

Open Visual Studio 2008 and create a new project. Choose the Windows Forms Application template and name the application WinTest.

Step 2

Rename the default Form1 to LocalizedForm and add following controls to it:

Control Name Text
Label AmountLabel Amount
TextBox AmountTextBox  
GroupBox TypeGroupBox Type of Payment
RadioButton PaymentRadioButton Payment
RadioButton ExpenseRadioButton Expense
Button OKButton OK
Button CancelButton Cancel

Step 3

Change the following properties of the LocalizedForm.

Property Value
Text Localized Form
AcceptButton OKButton
CancelButton CancelButton

The LocalizedForm should look like the following figure.

Step 4

Open the properties window of the LocalizedFrom and change the value of Localizable property to True. Once the Localizable property is changed to True, Visual Studio automatically adds a resource file, LocalizedForm.resx, to the project.

Step 5

Now, go the language property and choose French (France) from the drop-down list against it. Change the Text properties of the controls as shown below.

Control Name Text
LocalizedForm Forme localisée
AmountLabel Montant
TypeGroupBox Type de paiement
PaymentRadioButton Paiement
ExpenseRadioButton Dépense
OKButton OK
CancelButton Annuler

As you change the properties of the controls, one more resource file, LocalizedForm.fr-FR.resx, is added to the project. LocalizedForm.resx stores the settings for English language whereas LocalizedForm.fr-FR.resx stores settings for the French language. If you open these two files in the IDE and look for the Text properties that you just changed, you will see the following values.


Name Value
$this.Text Localized Form
AmountLabel.Text Amount
CancelButton.Text Cancel
ExpenseRadioButton.Text Expense
OKButton.Text OK
PaymentRadioButton.Text Payment
TypeGroupBox.Text Type of Payment


Name Value
$this.Text Forme localisée
AmountLabel.Text Montant
CancelButton.Text Annuler
ExpenseRadioButton.Text Dépense
PaymentRadioButton.Text Paiement
TypeGroupBox.Text Type de paiement

As you saw above, resource files save the values corresponding to different languages, but if you have noticed above in the LocalizedForm.fr-FR.resx file, the Text of the OKButton is not saved. This is because the text of the OKButton in the French is the same as in the default culture, in the LocalizedForm.resx file. This is true with all the resource files; the resource files other than the default one only saves those values that are different from the default ones. All other values are taken from the default resource file.

Step 6

Now press F5 to run the application. You will see the LocalizedForm with all the captions in English. The application automatically picks up the current culture information from the windows. Because your default culture is not French, all the captions are displayed in English.

An application can take the current culture settings from Windows, but many times you also may need to have the settings configurable in the application itself. For example, a user knows more than one language; the language of Windows is set as English, but the application should run in French because the application is used by another user who knows only French. For this test application, you will change the current culture in the code so that we can see the settings of the French culture.

Step 7

Open the Program.cs file and change the current culture to fr-FR. Your code should look like what's shown below.

static void Main()
   //localization code
   Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR");
   Thread.CurrentThread.CurrentCulture   = new CultureInfo("fr-FR");

   Application.Run(new LocalizedForm());

As seen in the preceding code, in .NET you have two classes, CurrentUICulture and CurrentCulture, for culture settings. CurrentCulture provides the culture-specific information, such as language and formats of numbers, date, casing conventions, and so forth, whereas CurrentUICulture maps to the Language settings in Windows. They are usually the same, but they can be set to different values.

You chose the fr-FR culture here because you already have created resources files for this culture. In fr-FR, fr represents the neutral culture of French whereas FR represents the specific culture of France. For one neutral culture, there can be many specific cultures; for example, in fr-CA, CA represents the specific culture of Canada.

Step 8

Now, press F5 again to run the application. You will see the LocalizedForm with the French captions as shown below.


Look under the hood now and see how it works.

Open the LocalizedForm.Designer.cs file and you will see in the InitializeComponent method, the IDE has created an instance of the ComponentResourceManager class; this takes the type of the form as the argument for the constructor. Then, the ApplyResources method of the ComponentResourceManager object is called for each control. The code looks like what you see below.

System.ComponentModel.ComponentResourceManager resources =
   new System.ComponentModel.ComponentResourceManager

resources.ApplyResources(this.CancelButton,  "CancelButton");
resources.ApplyResources(this.AmountLabel,   "AmountLabel");
resources.ApplyResources(this.AmountTextBox, "AmountTextBox");
resources.ApplyResources(this.TypeGroupBox,  "TypeGroupBox");
resources.ApplyResources(this.OKButton, "OKButton");
resources.ApplyResources(this, "$this");

It is the ComponentResourceManager that checks the current culture that application is running in and loads the corresponding resources for the controls. All this works fine for the UI controls but what about the data, error messages, and so on that are displayed to the users? How do we translate them to different languages and cultures so that they match the user's locale?

The resources that were automatically created by the IDE are the form-level resources. For the other text, like error messages, that you want to display to the users, you have to create project-level resources.

Step 9

Click on the Project > Add New Item and choose the Resource File from the templates; name it as ProjectResource.resx. Open the file in the designer and add the following values:

Name Value
AddedAmountSuccessMessage Amount updated successfully.
InvalidAmountErrorMessage Invalid amount, please check the amount and try again.
InvalidTypeErrorMessage Invalid data, please enter valid data.

Step 10

Add another resource file to the project and name it ProjectResource.fr-FR.resx. Add the same items in this file also, but with French values. The file should look like the following table in the designer.

Name Value
AddedAmountSuccessMessage Montant mis à jour avec succès.
InvalidAmountErrorMessage Montant incorrect, s'il vous plaît vC)rifier le montant et essayez à nouveau.
InvalidTypeErrorMessage Des données incorrectes, s'il vous plaît entrer des données.

Step 11

Open the LocalizedFrom.cs file and add the following code to it.

int amt;
ResourceManager objRM =
   new ResourceManager("WinTest.ProjectResource",

You have created an instance of the ResourceManager class that you will use to retrieve the culture-specific values from the ProjectResource. If the application is run in the default culture, ResourceManager will retrieve the values from the ProjectResource.resx file and, if the culture is set to fr-FR, the values will be retrieved automatically from the ProjectResource.fr-FR.resx file.

Step 12

In the Validating event of the AmountTextBox, add the following code.

private void AmountTextBox_Validating(object sender,
   CancelEventArgs e)
      amt = Convert.ToInt32(AmountTextBox.Text);
      AmountTextBox.Text = string.Format("{0:c}", amt);
   catch (FormatException ex)
         ("InvalidTypeErrorMessage"), "WinTest",
          MessageBoxButtons.OK, MessageBoxIcon.Error);
      e.Cancel = true;

What you are doing here is formatting the value to currency format and, if the user has keyed in the wrong type of data, you display an error message. You are retrieving the error message from ProjectResource using the ResourceManager object.

Step 13

Add the following code in the Click event of the OKButton.

private void OKButton_Click(object sender, EventArgs e)
   if (amt > 0 && amt <= 10000)
      //add to total
         ("AddedAmountSuccessMessage"), "WinTest",
          MessageBoxButtons.OK, MessageBoxIcon.Information);
         ("InvalidAmountErrorMessage"), "WinTest",
          MessageBoxButtons.OK, MessageBoxIcon.Error);

You are putting a rule here that says the amount should be greater than 0 and less than 10,000. If the amount is in that range, you run some logic and display the success message. If the amount is not in range, you display the error message. Both the success and error messages are retrieved from the ProjectResource using the instance of ResourceManager.

Step 14

Close the form in the Click event of the CancelButton.

private void CancelButton_Click(object sender, EventArgs e)

Step 15

Finally, in the FormClosing event, write the following code that tells ResourceManager object to release all the resources.

private voidLocalisedForm_FormClosing(object sender,
   FormClosingEventArgs e)

Step 16

With this, you are done with the changes. Now, press F5 again to run the application. The LocalizedForm is displayed with French captions. Remember that you have set the current culture to fr-FR in the Main() function.

Type abc in the Amount text box and press the TAB key. The following error message is displayed.


Type -100 as the amount and click on the OK button. The following error message is displayed because the rule that you wrote earlier has failed.


Now, type 500, which is the valid amount and press the TAB key again. See how the amount has been formatted according to the fr-FR culture.


Click on the OK button and you will get the success message as shown below.


Step 17

Now, comment out the two lines of code that you wrote in the Main() function to change the culture back to the default one. Run the application again and repeat the previous steps.

Enter abc as the amount and the following error message is displayed.


Enter an amount outside the range and click on OK button. The following error message will be displayed.


Type 500 as the amount and it is formatted according to the default culture.


Finally, click OK and it displays the success message in English.


With this, you are done with the walkthrough of localization in the Windows Forms application.

Sajad Deyargaroo

Sajad is a Kashmiri Software Engineer, MCTS, MCP with 7 years of experience in software development using different technologies and programming languages, such as VB, C, C++, C#, VB.NET, ASP.NET, T-SQL, PL/SQL, and the like. Now, he is working at DELL Inc.; at this time, he is focused on .NET technology. You can send an email to sajad@programmer.net.

This article was originally published on Thursday Jul 24th 2008
Mobile Site | Full Site