Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

User-Defined Multi-Lingual Applications

0.00/5 (No votes)
25 Sep 2009 1  
Developing multilingual applications that allow users to create their own language files

Introduction

A recent application of mine required multi-lingual capabilities. The user of the software is happy to provide the language-specific strings for his language. I just need to give him the file. Multi-lingual applications and localization are discussed in lots of places, but I've not seen any easy approaches whereby the end user can create his own language by simply creating and editing a new “language file”. This skin-able approach to language provides a great deal of user customization, yet minimal expense in terms of hiring translators.

Background

This approach created an interesting programming challenge. What would this language file look like? How would the application load the language file and update the controls? What happens when I create new forms and controls in the future versions of the application (which have new text items) and the user is using an old language file? How do I access the “language library” from anywhere in my application without having to pass it from form to form?

These questions were basically answered by two words: Reflection and Singleton. OK, there are a lot more words that apply, but those were the two concepts that helped me finally get to a solution that I liked.
So without any further ado, here’s the approach.

  1. The LanguageLoader is a Singleton class that contains the applications strings and can read/write language files. This class can be accessed from anywhere in the project. If you update it from anywhere in the application, the updates are available elsewhere. This Singleton stuff is cool!
  2. You add strings to an “ApplicationStrings” class. This class is accessed by the LanguageLoader (for loading and saving) via reflection. This reflection stuff is pretty cool too!
  3. For easy updating of controls, it helps if each form has a method that updates all of the strings on the form. This method can be called in the form’s “Load” method and can also be called when the language is changed by the user.

Using the Code

So let’s do it:

  1. Create a Windows Forms Application.
    Let’s add a label. Visual Studio calls it “label1.”  I'm not feeling too creative, so let’s stay with that. We can also add a button and call it “button1”.

  2. Now for the fun part. Add LanguageLoader and IniAccess to the solution. In the LangaugeLoader file, fill in the default value for the strings. (Look for the ApplicationStrings class at the bottom of the file).

    The strings need to be of the format: ParentForm_StringName (more on this later):

    //
    // This is at the bottom of the LanguageLoader.cs file:
    //
    public class ApplicationStrings
    {
        public String MainForm_Button1Text = "Click me for a new dialog/form";
        public String MainForm_Label1Text = "Hello, I'm a text label on the main form";
    }
  3. To get these strings to show up on the main form, add this method.You can call it from the Form’s “Load” method or anytime you want to update the strings.
    //
    // These are in the application’s main form source file:
    //
    private void UpdateLanguageOnControls()
    {
        // this function places language specific text on all "skin-able" text items
        button1.Text = LanguageLoader.appStrings.MainForm_Button1Text;
        label1.Text = LanguageLoader.appStrings.MainForm_Label1Text;
    }
    
    private void Form1_Load(object sender, EventArgs e)
    {
        UpdateLanguageOnControls();
    }

That’s basically it.  Once the application runs, the file “EnglishUS.lng” will be created in the application folder.  (Note: Vista may not allow the file to be written in the “Program Files” folder).

Creating a New Language

If you edit the LNG file (using NotePad or something similar), the edited strings will show up in the application. The language file is of the traditional INI format where each “section” is the name of the form and the “key” is the string’s name.  The section and key are extracted from the string variable’s name. Do you remember the ParentForm_StringName format from above? ParentForm becomes the section and StringName becomes the key.

-------- contents of EnglishUS.lng -------- 
[MainForm] 
Button1Text=Click me for a new dialog/form 
Label1Text=Hello, I'm a text label on the main form 
------------------------------------------------- 

To create a new language, simply open an existing language file and save it as a new name and change the strings accordingly:

-------- contents of PigLatin.lng -------- 
[MainForm] 
Button1Text=ickClay emay orfay away ewnay ialog/formday 
Label1Text=elloHay, I'mway away exttay abellay onway ethay ainmay ormfay 
------------------------------------------------- 

Applying the Language to a Dialog or Sub-Form

If a sub-form (dialog, etc.) needs language access, you can use the same approach that you used in the main form:

Add the sub-form’s strings to the ApplicationStrings class:

/// This is at the bottom of the LanguageLoader.cs file:
//
public class ApplicationStrings
{
    public String MainForm_Button1Text = "Click me for a new dialog/form";
    public String MainForm_Label1Text = "Hello, I'm a text label on the main form";
    // these are new strings to be used in the dialog
    public String DialogForm_Label1Text = "I'm the top label";
    public String DialogForm_Label2Text = "I'm the bottom label";
}

Put the strings on the form by creating and calling a “UpdateLanguageOnControls” method just like the one on the main form: 

//
// These are in the sub-form’s source file
//
// inside the DialogForm.cs file
private void UpdateLanguageOnControls()
{
    // this function places language specific text on all "skin-able" text items.
    label1.Text = LanguageLoader.appStrings.DialogForm_Label1Text;
    label2.Text = LanguageLoader.appStrings.DialogForm_Label2Text;
}

private void DialogForm_Load(object sender, EventArgs e)
{
    UpdateLanguageOnControls();
}

Closing

So there it is: a quick (and perhaps dirty) approach to multi-lingual apps that allows users to create their own languages. I'd love your feedback so let the postings fly! Or in other words: oSay erethay itway isway: away uickqay and(ay erhapspay irty)day approachway otay ulti-lingualmay appsway atthay allowway usersway otay eatecray Special thanks to the Pig Latin converter at: http://www.onlineconversion.com/pig_latin.htm.

History

  • 25th September, 2009: Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here