Click here to Skip to main content
15,881,044 members
Articles / Desktop Programming / Windows Forms

How To Translate Your Forms Application

Rate me:
Please Sign up or sign in to vote.
4.22/5 (11 votes)
7 Apr 2010Ms-PL3 min read 39.1K   524   32   18
Translate your forms application to multiple languages with ease

Introduction

Translating your application to multiple languages can be very hard. Fortunately, with this code you will just have to write the translated version of each sentence in a text file.

Small note: Please excuse me for providing you with a Visual Studio 2010 solution, you can modify it by opening it in Notepad and changing 2010 to 2008. It will work just fine.

How It Works

When you call the Translate("Language Here") method, the application checks if that selected language exists. By "exists", I mean if there is any text file with the translations in the "Languages" folder. If the language exists, it opens the text file, reads the data and starts translating. If not, it creates the text file.

That text file will contain the text of all the controls on your form, followed by an equal sign. What is before the equal sign is the original text, and what is after is the translated word. Write the translation after the equal mark, and then call the Translate() method again. You will see that your controls' text will be changed.

Using the Code

The code is well commented, but you still need to know the order of execution.

I started by writing the constructor:

C#
public Translator(Form toTranslate, string defaultLanguage)
{
    //Initializing variables
    mainForm = toTranslate;
    Default = defaultLanguage;
    CurrentLanguage = defaultLanguage;
            
    //Creating languages directory if it does not exist
    if (!Directory.Exists("Languages"))
    {
        Directory.CreateDirectory("Languages");
    }

    //We translate to the default language
    Translate(Default);
}

When we initialize the translator, we will have to pass as parameters the form we want to translate, and our default language.

We translate to the default language because, if this is the first time we call the method, the default language file does not exist. We will use the language file with the default language as a point of reference when translating from a language to another. Let's say I translate from French to Japanese, I need to translate to the default language first, and then to Japanese. Therefore, we will have a file with the default language that will contain the same words to the left and right of the equal mark.

Next, the variables we will use:

C#
//These variables hold the values 
//of the form we want to translate, the default 
//language, and the current language
Form mainForm;
string Default;
string CurrentLanguage;

//This is used in the words array
struct wordsList
{
    public string Original, Translated;
};

The wordsList struct is for a easier usage of the Words[] array.

The rest of the code works like this:

In the Translate() method, we check if the current language is the default language. If it isn't we translate it to the default language. If it is, then we check if the language we selected exists. If it does, we open the text file with the translation, and we load the lines into the Words[] array:

C#
//Reading data from text file
StreamReader langIn = File.OpenText("Languages\\" + Language);
//While not end of file, we read the lines
//in the Words array
while (!langIn.EndOfStream)

{
string Line = langIn.ReadLine();
Words[number] = new wordsList();
Words[number].Original = Line.Substring(0, Line.LastIndexOf("="));
Words[number].Translated = Line.Substring(Line.LastIndexOf("=") + 1);
number++;
}

langIn.Close();

We incremented the size of the Words array as we add items to it. The words to the left of the equal mark in the text file are the original words, and the one to the right, the translated version.

After we load the words, we loop through each control on the form and check if any of the words match the text of the control. If it does, we change the text to the translated version:

C#
foreach (Control control in mainForm.Controls)
{
//We loop through all the controls
//and the words array, and if any of the 
//controls has the text property 
//to match the orginal word in the array,
//we replace it with the translated version
for (int i = 0; i <= number; i++)
{
if (control.Text == Words[i].Original)
{
control.Text = Words[i].Translated;
break;
}
}
}

Finally, we check if there are any new words on the form. We loop thorough the controls and check if any of the words match the text of that control. If no word matches the control's text, we add it to the Words[] array.

Later, we rewrite the text file with all the words array. This way, if the language file does not originally exist, we create it:

C#
bool newWords = false;
foreach (Control control in mainForm.Controls)
{
//We assume it's new
bool ok = true;
for (int i = 0; i <= number; i++)
{
//If the word exists or it is empty "", we skip it
if (control.Text == Words[i].Original || control.Text == "")
ok = false;
}
//If it's a new word, we add it to the array
if (ok)
{
newWords = true;
Words[number] = new wordsList();
Words[number].Original = control.Text;
Words[number].Translated = "";
number++;
}
}
//We save the new words if any
if (newWords)
{
StreamWriter langOut = new StreamWriter("Languages\\" + Language);
for (int i = 0; i <= number; i++)
{
langOut.WriteLine(Words[i].Original + "=" + Words[i].Translated);
}
langOut.Close();
}

While all of this might translate our controls, if we have a message box to show, MessageBox.Show("Hello World"); it will not be translated. The following code can be used to translate any string inside your source code:

C#
public string tr(string toTranslate)
        {
            wordsList[] Words = new wordsList[1000];
            int number = 0; //Counter for Words[]
            Words[number] = new wordsList();

            //Checking if language exists
            if (File.Exists("Languages\\" + CurrentLanguage))
            {
                #region Reading
                //Reading data from text file
                StreamReader langIn = File.OpenText("Languages\\" + CurrentLanguage);
                //While not end of file, we read the lines
                //in the Words array
                while (!langIn.EndOfStream)
                {
                    string Line = langIn.ReadLine();
                    Words[number] = new wordsList();
                    Words[number].Original = Line.Substring(0, Line.LastIndexOf("="));
                    Words[number].Translated = 
			Line.Substring(Line.LastIndexOf("=") + 1);
                    number++;
                }
                langIn.Close();
                #endregion
                #region Translating
                for (int i = 0; i <= number; i++)
                {
                    if (toTranslate== Words[i].Original)
                    {
                        return Words[i].Translated;
                    }
                }
                #endregion
                #region Adding to translation file                    
                StreamWriter langOut = new StreamWriter
				("Languages\\" + CurrentLanguage);
                for (int i = 0; i <= number; i++)
                {
                    langOut.WriteLine(Words[i].Original + "=" + Words[i].Translated);
                }
                langOut.WriteLine(toTranslate + "=");
                langOut.Close();
                #endregion
            }

            return toTranslate;
        } 

To use it:

C#
MessageBox.Show(translator.tr("Hello World"));

It will automatically translate it to the current language.

What is NOT Implemented

This current code will not translate menus or context menus. I am planning to complete this article once I write the code for the menus.

Also, you can't add words or sentences that contain the equal sign, because the words will be read wrong:

C#
string Line = langIn.ReadLine();
Words[number] = new wordsList();
Words[number].Original = Line.Substring(0, Line.LastIndexOf("="));
Words[number].Translated = Line.Substring(Line.LastIndexOf("=") + 1);
number++; 

I hope you enjoyed this article, more coming soon.

History

  • Apr/8/10 - Added the possibility to translate strings inside the source code.
    C#
    MessageBox.Show(translator.tr("Hello World")); 

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionS Pin
Star.2009.Soft20-May-14 22:05
Star.2009.Soft20-May-14 22:05 
GeneralMy vote of 1 Pin
Claudio Nicora12-Apr-10 23:56
Claudio Nicora12-Apr-10 23:56 
GeneralGreat Article Pin
Gaurav Dudeja India8-Apr-10 20:23
Gaurav Dudeja India8-Apr-10 20:23 
General[My Vote 3] Pin
Jitendra Zaa8-Apr-10 1:49
Jitendra Zaa8-Apr-10 1:49 
GeneralHey. Why you have not used localization features of provided by .Net framework which uses resource files. Pin
FanOfOOPS8-Apr-10 0:52
FanOfOOPS8-Apr-10 0:52 
GeneralRe: Hey. Why you have not used localization features of provided by .Net framework which uses resource files. Pin
Dav28-Apr-10 1:47
Dav28-Apr-10 1:47 
General[My vote of 1] this is horrible!! Pin
Seishin#7-Apr-10 22:58
Seishin#7-Apr-10 22:58 
GeneralRe: [My vote of 1] this is horrible!! Pin
Dav28-Apr-10 1:39
Dav28-Apr-10 1:39 
GeneralRe: [My vote of 1] this is horrible!! Pin
Seishin#8-Apr-10 2:02
Seishin#8-Apr-10 2:02 
GeneralRe: [My vote of 1] this is horrible!! Pin
Dav28-Apr-10 2:43
Dav28-Apr-10 2:43 
GeneralRe: [My vote of 1] this is horrible!! Pin
Seishin#8-Apr-10 4:28
Seishin#8-Apr-10 4:28 
GeneralRe: [My vote of 1] this is horrible!! Pin
Dav28-Apr-10 7:10
Dav28-Apr-10 7:10 
GeneralRe: [My vote of 1] this is horrible!! Pin
Seishin#8-Apr-10 8:03
Seishin#8-Apr-10 8:03 
GeneralGood work Pin
Som Shekhar3-Apr-10 22:55
Som Shekhar3-Apr-10 22:55 
GeneralInteresting Pin
Khaniya3-Apr-10 19:53
professionalKhaniya3-Apr-10 19:53 
GeneralRe: Interesting Pin
Dav23-Apr-10 21:17
Dav23-Apr-10 21:17 
I wanted to keep the article simple. Of course, you can create a dataset and use it with XML files, it would be better since you can add text that contains the equal sign (in this case you can't).
QuestionDo you have any example project ? Pin
Tiep Le3-Apr-10 18:10
Tiep Le3-Apr-10 18:10 
AnswerRe: Do you have any example project ? Pin
Dav23-Apr-10 21:10
Dav23-Apr-10 21:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.