http://www.developer.com/net/net/article.php/3384221/Build-a-Localized-Form-that-Speaks-the-Users-Language.htm
Welcome to the next installment of the .NET Nuts & Bolts column. This article covers the basics of how to build a multilingual application using Microsoft .NET. It outlines the construction and then demonstrates it with examples. Large organizations with locations across the globe have long needed to make the same application available in multiple languages. However, this problem is not unique to large organizations. In this age of outsourcing, where operations span multiple cultures, almost any organization can face the demand for a multilingual application. The process for enabling applications to be deployed in more than one language is often referred to as localization. It refers to the application's ability to adapt to the user's locale-specific settings, such as language, date, and currency styles. I struggle enough with the English language, let alone attempting to master another language. I've often wondered why I can pick up obscure programming languages with ease and yet struggle to learn another language, but I digress. Over the years, a number of localization approaches have emerged. This column focuses on the Microsoft .NET Framework's solution. The .NET Framework provides support for localization (a.k.a. multilingual deployments) through resource files. Microsoft designed the resource file to store locale-specific information. You create a resource file for each locale you wish to support in your application. The resource files are then compiled into satellite assemblies, which are automatically loaded based on the locale settings of the computer. For the sake of this article, I'll pretend that I know German better than I really do and use it as my example. For those readers who are fluent in German, please don't be offended by my bad usage. The following sample code contains a basic application form that you soon will learn to configure into a localized form: Figure 1 shows the output of the sample form. When you press either of the buttons, it displays some simple message boxes. Figure 1: Default Locale (English) Resource files are simple text-based files that you can edit with a simple editor like "Visual Notepad" (as I often affectionately refer to good old Notepad). However, Visual Studio .NET makes creating resource files through the IDE easy. It also has a utility called winres.exe that allows resources to be edited in a lightweight editor that cannot change code. Because I'm all about taking the path of least resistance, I'll create the resource files through the Visual Studio .NET IDE. Here is the basic recipe for creating a localized form using the form from above: The following is the resulting form once I went through the sample code from the Localization by Resource File section and made all of my localized configurations: Figure 2 shows the application form that displays when you run the above sample with the CurrentUICulture explicitly set to de-GR. Simply commenting out the line of code that sets the CurrentUICulture will cause the application to display the English-based form again the next time it runs. Figure 2: de-GR Locale (German) This column demonstrated on some of the basics of creating a multilingual, or localized, application. It only touched upon setting the display value for labels and buttons. Here are a couple of additional items to ponder: The topic of the next column is yet to be determined. If you have something in particular that you would like to see explained here, you can reach me at mstrawmyer@crowechizek.com. Mark Strawmyer, MCSD, MCSE, MCDBA is a Senior Architect of .NET applications for large and mid-size organizations. Mark is a technology leader with Crowe Chizek in Indianapolis, Indiana. He specializes in architecture, design, and development of Microsoft-based solutions. Mark was honored to be named a Microsoft MVP for application development with C#. You can reach Mark at mstrawmyer@crowechizek.com.
Build a Localized Form that Speaks the User's Language
July 22, 2004
Localization by Resource File
Form Sample Code
using System;using System.Drawing;using System.Collections;using System.ComponentModel;using System.Windows.Forms;using System.Data;namespace CodeGuru.Globalization{ /// <summary> /// Sample application form. /// </summary> public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.Label NameLabel; private System.Windows.Forms.TextBox NameTextBox; private System.Windows.Forms.Label LangQuesLabel; private System.Windows.Forms.Button GoBtn; private System.Windows.Forms.Button HelpBtn; /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; public Form1() { // // Required for Windows Form Designer support // InitializeComponent(); } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.GoBtn = new System.Windows.Forms.Button(); thisthis.HelpBtn = new System.Windows.Forms.Button(); this.NameLabel = new System.Windows.Forms.Label(); this.NameTextBox = new System.Windows.Forms.TextBox(); this.LangQuesLabel = new System.Windows.Forms.Label(); this.SuspendLayout(); // // GoBtn // this.GoBtn.Location = new System.Drawing.Point(72, 112); this.GoBtn.Name = "GoBtn"; this.GoBtn.TabIndex = 0; this.GoBtn.Text = "Go"; this.GoBtn.Click += new System.EventHandler(this.GoBtn_Click); // // HelpBtn // this.HelpBtn.Location = new System.Drawing.Point(288, 112); this.HelpBtn.Name = "HelpBtn"; this.HelpBtn.TabIndex = 1; this.HelpBtn.Text = "Help"; this.HelpBtn.Click += new System.EventHandler(this.HelpBtn_Click); // // NameLabel // this.NameLabel.Location = new System.Drawing.Point(16, 24); this.NameLabel.Name = "NameLabel";- this.NameLabel.Size = new System.Drawing.Size(72, 23); this.NameLabel.TabIndex = 2; this.NameLabel.Text = "My Name is:"; // // NameTextBox // this.NameTextBox.Location = new System.Drawing.Point(96, 24); this.NameTextBox.Name = "NameTextBox"; this.NameTextBox.Size = new System.Drawing.Size(256, 20); this.NameTextBox.TabIndex = 3; this.NameTextBox.Text = ""; // // LangQuesLabel // this.LangQuesLabel.Location = new System.Drawing.Point(16, 64); this.LangQuesLabel.Name = "LangQuesLabel"; this.LangQuesLabel.Size = new System.Drawing.Size(336, 23); this.LangQuesLabel.TabIndex = 4; this.LangQuesLabel.Text = "Do you speak English?"; // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(440, 286); this.Controls.Add(this.LangQuesLabel); this.Controls.Add(this.NameTextBox); this.Controls.Add(this.NameLabel); this.Controls.Add(this.HelpBtn); this.Controls.Add(this.GoBtn); this.Name = "Form1"; this.Text = "English Application"; this.ResumeLayout(false); } #endregion /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.Run(new Form1()); } private void HelpBtn_Click(object sender, System.EventArgs e) { MessageBox.Show("How are you?"); } private void GoBtn_Click(object sender, System.EventArgs e) { MessageBox.Show("Where do you want to go today?"); } }}Form Sample Output

Editing Resource Files
Localized Form Sample Code
using System;using System.Drawing;using System.Collections;using System.ComponentModel;using System.Windows.Forms;using System.Data;namespace CodeGuru.Globalization{ /// <summary> /// Sample application form. /// </summary> public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.Label NameLabel; private System.Windows.Forms.TextBox NameTextBox; private System.Windows.Forms.Label LangQuesLabel; private System.Windows.Forms.Button GoBtn; private System.Windows.Forms.Button HelpBtn; /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; public Form1() { // // Required for Windows Form Designer support // InitializeComponent(); } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1)); this.GoBtn = new System.Windows.Forms.Button(); this.HelpBtn = new System.Windows.Forms.Button(); this.NameLabel = new System.Windows.Forms.Label(); this.NameTextBox = new System.Windows.Forms.TextBox(); this.LangQuesLabel = new System.Windows.Forms.Label(); this.SuspendLayout(); // // GoBtn // this.GoBtn.AccessibleDescription = resources.GetString("GoBtn.AccessibleDescription"); this.GoBtn.AccessibleName = resources.GetString("GoBtn.AccessibleName"); this.GoBtn.Anchor = ((System.Windows.Forms.AnchorStyles) (resources.GetObject("GoBtn.Anchor"))); this.GoBtn.BackgroundImage = ((System.Drawing.Image) (resources.GetObject("GoBtn.BackgroundImage"))); this.GoBtn.Dock = ((System.Windows.Forms.DockStyle) (resources.GetObject("GoBtn.Dock"))); this.GoBtn.Enabled = ((bool)(resources.GetObject("GoBtn.Enabled"))); this.GoBtn.FlatStyle = ((System.Windows.Forms.FlatStyle) (resources.GetObject("GoBtn.FlatStyle"))); this.GoBtn.Font = ((System.Drawing.Font) (resources.GetObject("GoBtn.Font"))); this.GoBtn.Image = ((System.Drawing.Image) (resources.GetObject("GoBtn.Image"))); this.GoBtn.ImageAlign = ((System.Drawing.ContentAlignment) (resources.GetObject("GoBtn.ImageAlign"))); this.GoBtn.ImageIndex = ((int)(resources.GetObject ("GoBtn.ImageIndex"))); this.GoBtn.ImeMode = ((System.Windows.Forms.ImeMode) (resources.GetObject("GoBtn.ImeMode"))); this.GoBtn.Location = ((System.Drawing.Point) (resources.GetObject("GoBtn.Location"))); this.GoBtn.Name = "GoBtn"; this.GoBtn.RightToLeft = ((System.Windows.Forms.RightToLeft) (resources.GetObject("GoBtn.RightToLeft"))); this.GoBtn.Size = ((System.Drawing.Size) (resources.GetObject("GoBtn.Size"))); this.GoBtn.TabIndex = ((int)(resources.GetObject ("GoBtn.TabIndex"))); this.GoBtn.Text = resources.GetString("GoBtn.Text"); this.GoBtn.TextAlign = ((System.Drawing.ContentAlignment) (resources.GetObject("GoBtn.TextAlign"))); this.GoBtn.Visible = ((bool) (resources.GetObject("GoBtn.Visible"))); this.GoBtn.Click += new System.EventHandler(this.GoBtn_Click); // // HelpBtn // this.HelpBtn.AccessibleDescription = resources.GetString("HelpBtn.AccessibleDescription"); this.HelpBtn.AccessibleName = resources.GetString("HelpBtn.AccessibleName"); this.HelpBtn.Anchor = ((System.Windows.Forms.AnchorStyles) (resources.GetObject("HelpBtn.Anchor"))); this.HelpBtn.BackgroundImage = ((System.Drawing.Image) (resources.GetObject("HelpBtn.BackgroundImage"))); this.HelpBtn.Dock = ((System.Windows.Forms.DockStyle) (resources.GetObject("HelpBtn.Dock"))); this.HelpBtn.Enabled = ((bool)(resources.GetObject("HelpBtn.Enabled"))); this.HelpBtn.FlatStyle = ((System.Windows.Forms.FlatStyle) (resources.GetObject("HelpBtn.FlatStyle"))); this.HelpBtn.Font = ((System.Drawing.Font) (resources.GetObject("HelpBtn.Font"))); this.HelpBtn.Image = ((System.Drawing.Image) (resources.GetObject("HelpBtn.Image"))); this.HelpBtn.ImageAlign = ((System.Drawing.ContentAlignment) (resources.GetObject("HelpBtn.ImageAlign"))); this.HelpBtn.ImageIndex = ((int)(resources.GetObject ("HelpBtn.ImageIndex"))); this.HelpBtn.ImeMode = ((System.Windows.Forms.ImeMode) (resources.GetObject("HelpBtn.ImeMode"))); this.HelpBtn.Location = ((System.Drawing.Point) (resources.GetObject("HelpBtn.Location"))); this.HelpBtn.Name = "HelpBtn"; this.HelpBtn.RightToLeft = ((System.Windows.Forms.RightToLeft) (resources.GetObject("HelpBtn.RightToLeft"))); this.HelpBtn.Size = ((System.Drawing.Size) (resources.GetObject("HelpBtn.Size"))); this.HelpBtn.TabIndex = ((int)(resources.GetObject("HelpBtn.TabIndex"))); this.HelpBtn.Text = resources.GetString("HelpBtn.Text"); this.HelpBtn.TextAlign = ((System.Drawing.ContentAlignment) (resources.GetObject("HelpBtn.TextAlign"))); this.HelpBtn.Visible = ((bool)(resources.GetObject("HelpBtn.Visible"))); this.HelpBtn.Click += new System.EventHandler (this.HelpBtn_Click); // // NameLabel // this.NameLabel.AccessibleDescription = resources.GetString("NameLabel.AccessibleDescription"); this.NameLabel.AccessibleName = resources.GetString("NameLabel.AccessibleName"); this.NameLabel.Anchor = ((System.Windows.Forms.AnchorStyles) (resources.GetObject("NameLabel.Anchor"))); this.NameLabel.AutoSize = ((bool)(resources.GetObject ("NameLabel.AutoSize"))); this.NameLabel.Dock = ((System.Windows.Forms.DockStyle) (resources.GetObject("NameLabel.Dock"))); this.NameLabel.Enabled = ((bool)(resources.GetObject("NameLabel.Enabled"))); this.NameLabel.Font = ((System.Drawing.Font) (resources.GetObject("NameLabel.Font"))); this.NameLabel.Image = ((System.Drawing.Image) (resources.GetObject("NameLabel.Image"))); this.NameLabel.ImageAlign = ((System.Drawing.ContentAlignment) (resources.GetObject("NameLabel.ImageAlign"))); this.NameLabel.ImageIndex = ((int)(resources.GetObject("NameLabel.ImageIndex"))); this.NameLabel.ImeMode = ((System.Windows.Forms.ImeMode) (resources.GetObject("NameLabel.ImeMode"))); this.NameLabel.Location = ((System.Drawing.Point) (resources.GetObject("NameLabel.Location"))); this.NameLabel.Name = "NameLabel"; this.NameLabel.RightToLeft = ((System.Windows.Forms.RightToLeft) (resources.GetObject("NameLabel.RightToLeft"))); this.NameLabel.Size = ((System.Drawing.Size) (resources.GetObject("NameLabel.Size"))); this.NameLabel.TabIndex = ((int)(resources.GetObject("NameLabel.TabIndex"))); this.NameLabel.Text = resources.GetString("NameLabel.Text"); this.NameLabel.TextAlign = ((System.Drawing.ContentAlignment) (resources.GetObject("NameLabel.TextAlign"))); this.NameLabel.Visible = ((bool)(resources.GetObject("NameLabel.Visible"))); // // NameTextBox // this.NameTextBox.AccessibleDescription = resources.GetString("NameTextBox.AccessibleDescription"); this.NameTextBox.AccessibleName = resources.GetString("NameTextBox.AccessibleName"); this.NameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles) (resources.GetObject("NameTextBox.Anchor"))); this.NameTextBox.AutoSize = ((bool)(resources.GetObject("NameTextBox.AutoSize"))); this.NameTextBox.BackgroundImage = ((System.Drawing.Image) (resources.GetObject("NameTextBox.BackgroundImage"))); this.NameTextBox.Dock = ((System.Windows.Forms.DockStyle) (resources.GetObject("NameTextBox.Dock"))); this.NameTextBox.Enabled = ((bool)(resources.GetObject("NameTextBox.Enabled"))); this.NameTextBox.Font = ((System.Drawing.Font) (resources.GetObject("NameTextBox.Font"))); this.NameTextBox.ImeMode = ((System.Windows.Forms.ImeMode) (resources.GetObject("NameTextBox.ImeMode"))); this.NameTextBox.Location = ((System.Drawing.Point) (resources.GetObject("NameTextBox.Location"))); this.NameTextBox.MaxLength = ((int)(resources.GetObject("NameTextBox.MaxLength"))); this.NameTextBox.Multiline = ((bool)(resources.GetObject("NameTextBox.Multiline"))); this.NameTextBox.Name = "NameTextBox"; this.NameTextBox.PasswordChar = ((char)(resources.GetObject("NameTextBox.PasswordChar"))); this.NameTextBox.RightToLeft = ((System.Windows.Forms.RightToLeft) (resources.GetObject("NameTextBox.RightToLeft"))); this.NameTextBox.ScrollBars = ((System.Windows.Forms.ScrollBars) (resources.GetObject("NameTextBox.ScrollBars"))); this.NameTextBox.Size = ((System.Drawing.Size) (resources.GetObject("NameTextBox.Size"))); this.NameTextBox.TabIndex = ((int)(resources.GetObject("NameTextBox.TabIndex"))); this.NameTextBox.Text = resources.GetString("NameTextBox.Text"); this.NameTextBox.TextAlign = ((System.Windows.Forms.HorizontalAlignment) (resources.GetObject("NameTextBox.TextAlign"))); this.NameTextBox.Visible = ((bool)(resources.GetObject("NameTextBox.Visible"))); this.NameTextBox.WordWrap = ((bool)(resources.GetObject("NameTextBox.WordWrap"))); // // LangQuesLabel // this.LangQuesLabel.AccessibleDescription = resources.GetString("LangQuesLabel.AccessibleDescription"); this.LangQuesLabel.AccessibleName = resources.GetString("LangQuesLabel.AccessibleName"); this.LangQuesLabel.Anchor = ((System.Windows.Forms.AnchorStyles) (resources.GetObject("LangQuesLabel.Anchor"))); this.LangQuesLabel.AutoSize = ((bool)(resources.GetObject("LangQuesLabel.AutoSize"))); this.LangQuesLabel.Dock = ((System.Windows.Forms.DockStyle) (resources.GetObject("LangQuesLabel.Dock"))); this.LangQuesLabel.Enabled = ((bool)(resources.GetObject("LangQuesLabel.Enabled"))); this.LangQuesLabel.Font = ((System.Drawing.Font) (resources.GetObject("LangQuesLabel.Font"))); this.LangQuesLabel.Image = ((System.Drawing.Image) (resources.GetObject("LangQuesLabel.Image"))); this.LangQuesLabel.ImageAlign = ((System.Drawing.ContentAlignment) (resources.GetObject("LangQuesLabel.ImageAlign"))); this.LangQuesLabel.ImageIndex = ((int)(resources.GetObject("LangQuesLabel.ImageIndex"))); this.LangQuesLabel.ImeMode = ((System.Windows.Forms.ImeMode) (resources.GetObject("LangQuesLabel.ImeMode"))); this.LangQuesLabel.Location = ((System.Drawing.Point) (resources.GetObject("LangQuesLabel.Location"))); this.LangQuesLabel.Name = "LangQuesLabel"; this.LangQuesLabel.RightToLeft = ((System.Windows.Forms.RightToLeft) (resources.GetObject("LangQuesLabel.RightToLeft"))); this.LangQuesLabel.Size = ((System.Drawing.Size) (resources.GetObject("LangQuesLabel.Size"))); this.LangQuesLabel.TabIndex = ((int)(resources.GetObject("LangQuesLabel.TabIndex"))); this.LangQuesLabel.Text = resources.GetString("LangQuesLabel.Text"); this.LangQuesLabel.TextAlign = ((System.Drawing.ContentAlignment) (resources.GetObject("LangQuesLabel.TextAlign"))); this.LangQuesLabel.Visible = ((bool)(resources.GetObject("LangQuesLabel.Visible"))); // // Form1 // this.AccessibleDescription = resources.GetString("$this.AccessibleDescription"); this.AccessibleName = resources.GetString("$this.AccessibleName"); this.AutoScaleBaseSize = ((System.Drawing.Size) (resources.GetObject("$this.AutoScaleBaseSize"))); this.AutoScroll = ((bool)(resources.GetObject("$this.AutoScroll"))); this.AutoScrollMargin = ((System.Drawing.Size) (resources.GetObject("$this.AutoScrollMargin"))); this.AutoScrollMinSize = ((System.Drawing.Size) (resources.GetObject("$this.AutoScrollMinSize"))); this.BackgroundImage = ((System.Drawing.Image) (resources.GetObject("$this.BackgroundImage"))); this.ClientSize = ((System.Drawing.Size) (resources.GetObject("$this.ClientSize"))); this.Controls.Add(this.LangQuesLabel); this.Controls.Add(this.NameTextBox); this.Controls.Add(this.NameLabel); this.Controls.Add(this.HelpBtn); this.Controls.Add(this.GoBtn); this.Enabled = ((bool)(resources.GetObject("$this.Enabled"))); this.Font = ((System.Drawing.Font)(resources.GetObject("$this.Font"))); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.ImeMode = ((System.Windows.Forms.ImeMode) (resources.GetObject("$this.ImeMode"))); this.Location = ((System.Drawing.Point) (resources.GetObject("$this.Location"))); this.MaximumSize = ((System.Drawing.Size) (resources.GetObject("$this.MaximumSize"))); this.MinimumSize = ((System.Drawing.Size) (resources.GetObject("$this.MinimumSize"))); this.Name = "Form1"; this.RightToLeft = ((System.Windows.Forms.RightToLeft) (resources.GetObject("$this.RightToLeft"))); this.StartPosition = ((System.Windows.Forms.FormStartPosition) (resources.GetObject("$this.StartPosition"))); this.Text = resources.GetString("$this.Text"); this.ResumeLayout(false); } #endregion /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("de-DE"); Application.Run(new Form1()); } private void HelpBtn_Click(object sender, System.EventArgs e) { MessageBox.Show("How are you?"); } private void GoBtn_Click(object sender, System.EventArgs e) { MessageBox.Show("Where do you want to go today?"); } }}Localized Form Screen Output

Possible Enhancements
Future Columns
About the Author