|Important||This document may not represent best practices for current development, links to downloads and other resources may no longer be valid. Current recommended version can be found here.|
Walkthrough: Localizing Windows Forms
The Visual Studio project system provides considerable support for localizing Windows Forms applications. There are two ways to generate resource files using the Visual Studio development environment:
Have the project system generate the resource files for localizable UI elements such as text and images on the form. The resource files are then built into satellite assemblies. These are known as forms-based resources.
Add a resource file template and then edit the template with the XML Designer. A reason for doing the latter is to make localizable strings that appear in dialog boxes and error messages. You must then write code to access these resources. These are known as project resources.
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.
It is important to be consistent, and use either form-based resources or project resources for the same property. Many images properties, such as the Image property on PictureBox, allow you either to select an image from project resources, or import a new image as a forms-based resource. If you attempt to set the default image using a project resource, and language-specific versions of the image using formed-based resources, the default image will never be displayed.
This walkthrough topic demonstrates both processes in a single Windows Application project.
To have Visual Studio generate resource files for you
Create a new Windows Application named "WindowsApplication1". For details, see How to: Create a Windows Application Project.
In the Properties window, set the form's Localizable property to true.
The Language property is already set to (Default).
Drag a Button control from the Windows Forms tab of the Toolbox to the form, and set its Text property to Hello World.
Set the form's Language property to German (Germany).
Set the button's Text property to Hallo Welt.
Set the form's Language property to French (France).
Set the button's Text property to Bonjour le Monde. You can resize the button to accommodate the longer string, if necessary.
Save and build the solution.
Click the Show All Files button in Solution Explorer.
The resource files appear underneath Form1.vb, Form1.cs, or Form1.jsl. Form1.resx is the resource file for the default culture, which will be built into the main assembly. Form1.de-DE.resx is the resource file for German as spoken in Germany. Form1.fr-FR.resx is the resource file for French as spoken in France.
In addition, you will see files appear named Form1.de.resx and Form1.fr.resx. Visual Studio automatically creates these files in order to work around a limitation in Visual SourceSafe having to do with adding new files to a project during a save operation. The .resx files are empty and contain no resources.
Press the F5 key or choose Start from the Debug menu.
You will now see a dialog box with an English, French, or German greeting depending on the UI language of your operating system.
The UI language used in Windows is a function of the CurrentUICulture setting. If your copy of Windows has a Multilingual User Interface Pack (MUI) installed, you can change UI language in Control Panel. For more information, see the Windows Server 2003, Windows XP & Windows 2000 MUI site. If you have no MUI installed, you can change the current UI culture programmatically, as explained next.
The following procedure shows you how to set the UI culture so the application displays your French resources. In real-world applications, you would not hard-code the UI culture in this way. The setting for the UI culture would depend instead on a user setting or an application setting.
To set the UI Culture to view specific resources
In the Code Editor, add the following code at the beginning of the module, before the Form1 declaration:
' Visual Basic Imports System.Globalization Imports System.Threading // C# using System.Globalization; using System.Threading;
Add the following code. In Visual Basic, it should go in the New function, before calling the InitializeComponent function. In Visual C#, it should go in Form1 and also before calling the InitializeComponent function.
' Visual Basic ' Sets the UI culture to French (France). Thread.CurrentThread.CurrentUICulture = New CultureInfo("fr-FR") // C# // Sets the UI culture to French (France). Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR");
Save and build the solution.
Press the F5 key or choose Start from the Debug menu.
Now the form will be always displayed in French. If you changed the size of the button earlier to accommodate the longer French string, notice that the button size has also been persisted in the French resource file.
To manually add resource files to the project and edit them
On the Project menu, click Add New Item.
In the Templates box, select the Resources File template. Type the file name "WinFormStrings.resx" in the Name box. The file WinFormStrings.resx will contain fallback resources in English. These resources will be accessed whenever the application cannot find resources more appropriate to the UI culture.
The file is added to your project in Solution Explorer and automatically opens in the XML Designer in Data view.
In the Data Tables pane, select data.
In the Data pane, click an empty row and enter strMessage in the name column and Hello World in the value column.
You do not need to specify the type or mimetype for a string; they are used for objects. The type specifier holds the data type of the object being saved. The MIME type specifier holds the base type (base64) of the binary information stored, if the object consists of binary data.
On the File menu, click Save WinFormStrings.resx.
Do steps 1-5 twice more to create two more resource files named WinFormStrings.de-DE.resx and WinFormStrings.fr-FR.resx, with the string resources specified in the following table. The file WinFormStrings.de-DE.resx will contain resources that are specific to German as spoken in Germany. The file WinFormStrings.fr-FR.resx will contain resources that are specific to French as spoken in France.
Resource file name
Bonjour le Monde
To access the manually added resources
In the Code Editor, import the System.Resources namespace at the beginning of the code module.
' Visual Basic Imports System.Resources // C# using System.Resources;
In Design view, double-click the button to display the code for its Click event handler and add the following code. The ResourceManager constructor takes two arguments. The first is the root name of the resources — that is, the name of the resource file without the culture and .resx suffixes. The second argument is the main assembly.
In this walkthrough, no namespaces are declared, so the first argument of the ResourceManager constructor can take the form of ProjectName.ResourceFileRootName. However, in a real-world application, you would set the DefaultNamespace property. In that case, you would need to declare the resource manager with the fully qualified root name of the resource file, including its namespace. For example, if the default namespace is MyCompany.MyApplication.MyComponent, the first argument of the ResourceManager constructor might be MyCompany.MyApplication.MyComponent.WinFormStrings.
' Visual Basic ' Declare a Resource Manager instance. Dim LocRM As New ResourceManager("WindowsApplication1.WinFormStrings", GetType(Form1).Assembly) ' Assign the string for the "strMessage" key to a message box. MessageBox.Show(LocRM.GetString("strMessage")) // C# // Declare a Resource Manager instance. ResourceManager LocRM = new ResourceManager("WindowsApplication1.WinFormStrings",typeof(Form1).Assembly); // Assign the string for the "strMessage" key to a message box. MessageBox.Show(LocRM.GetString("strMessage"));
By default, the ResourceManager object is case-sensitive. If you want to do case-insensitive lookups so that "TXTWELCOME" retrieves the same resource as "txtWelcome", you can set the resource manager's IgnoreCase property to true. However, for performance reasons, it is best to always specify the correct case for your resource names. Doing case-insensitive resource lookups can cause performance problems.
Build and run the form. Click the button.
The message box will display a string appropriate for the UI culture setting; or if it cannot find a resource for the UI culture, it will display a string from the fallback resources.