Click here to Skip to main content
15,891,513 members
Articles / Programming Languages / C# 5.0
Tip/Trick

Translating Form Applications to Nonstandard Languages

Rate me:
Please Sign up or sign in to vote.
4.33/5 (2 votes)
7 Dec 2014CPOL5 min read 10.8K   56   3   2
Quickly adding alternate languages (Pirate, KJV, ValleyGirl) to your C# form-based application

Introduction

Localizing a forms application should be done using the .NET Framework. That is the right way to do it. But sometimes you want a quick and dirty translation, or you want to translate into a non-language like KJV ("Hittest thou this button"), Pirate ("Arrg! Click this and Die!") VallyGirl ("Like, you know, hit this button"). While the process of translating a form is fairly simple, doing it well can be a bit daunting. This class will hopefully help with that.

It works by having a list of original text, followed by the translated text. The XML file allows you to have multiple "languages", each one with a list of original and translated text.

Background

I had a very simple game that I wanted to translate into "Pirate", and found it was not trivial to do it well. In my search to see if someone had already done it, I found an article for a very basic system here. That version was lacking a fair number of things. I wanted the translation to be bundled with the app, I wanted it to use utf-8 / xml, and it wanted it to translate child controls. I wanted it to load once, save once, be a lot more robust, and a number of other things. So I decided to make my own class.

It should be noted that my code is set up not to be backwards translatable. You change the language choice and then restart the application, instead of switching from one language straight into another. The reason for this is that this class allows you to translate combined strings:

C#
myLabel.Text = Translate("You have ") + 
myNumber.ToString() + " " + Translate("apples");

These combined strings "You have 5 apples" cannot be reversed by looking up the string it was translated into.

Using the Code

You should be able to create an empty class in your project and paste the contents of this class into it. Make sure the "namespace" is correct (use the namespace you have defined on all your other classes / forms).

At the top of the class is a section of variables you should change.

  • DefaultLanguage: This is the default language; the one the form was written/designed/coded in. When the translator is first run, it will make a set of translations for everything on the form under the "DefaultLanguage" language.
  • ProjectResourceString: This is used to find the translation resource inside your project (if you bundle the translation inside your program). It should be your namespace, followed by the string ".Properties.Resources". This allows us to take the translation XML file and bundle it within the project.
  • ResourceName: This is the "filename" of the XML resource file. When you add the translation XML file to your project, this is the resulting name (usually the filename without the .xml at the end).
  • PromptForLang: Set this to true if you want an initial window popping up when you run your application, asking for the initial language to use.
  • firstrun: This skips the code that looks for a resource file bundled in with your program. If it is set to "true", it loads and saves to the "SavePath". It is for use when you are building your translation. Set it to "false" when you want it to only use the resource inside your program.
  • AddLanguage When you want to add a new language to the system. Put the language name here (AddLanguage="Pirate"; SaveWhenDone=true;) and run your program. You should end up with an XML file with all the translation strings needed to make your first translation.
  • SavePath: This is the file name that gets used, hopefully only when you are developing your translation. When you are done, you want to add that file as a resource to your program, set FirstRun=false, and turn off "SaveWhenDone."

The class is set up to have one localizer class for the whole project. That really just cuts down on needing to load/parse the file. For my project, I had a class of "game settings" that I passed to every form / class that needed it. I have my localizer as a public variable in that.

When a program first runs, you should have something like this to do a little setup:

C#
Localizer myTranslator = new Localizer();  //Instantiate the translator

private void Form1_Load(object sender, EventArgs e)
        {
            //Get the list of languages
            List<string> TheLanguages = myTranslator.LanguageList();
            //Retrieve our property/setting where we stored our choice of language
            string ToLanguage = Properties.Settings.Default.ChosenLanguage;
            //Check to see if the language exists (or if we chose "none")
            if (TheLanguages.IndexOf(ToLanguage) < 0)
                ToLanguage = ""; //If we set "", 
                        //we will probably prompt for the language to use
            //Tell the translator what language to use.  Notice we do this before much of anything else
            string otherLanguage = myTranslator.SetLanguage(ToLanguage);

            //We get the chosen language from SetLanguage if we chose something.  Store the choice
            if(otherLanguage != ToLanguage)
            {
                Properties.Settings.Default.ChosenLanguage = otherLanguage;
                Properties.Settings.Default.Save();
            }

            //Now we translate the form.
            myTranslator.Translate(this); //translate the whole form

            //At this point, the form is now translated.           
        }

The above code instantiates the localizer and gets the chosen language from the project settings.

Now, we have a button that translates and launches another form. You can translate the form this way (using just one translator) or pass the class into the other forms so you just have the one translation instance.

C#
private void button1_Click(object sender, EventArgs e)
        {
            //Generate a new form and translate it before we display it
            SubForm newform = new SubForm();
            //The translator already exists, is loaded, and has a chosen language.
            //So we just tell it to translate the form before we load it.
            myTranslator.Translate(newform);
            newform.ShowDialog();
        }

Points of Interest

While it may seem simple to loop through your forms and replace text, it really does not work as well as you might expect. Languages may communicate the same things, but they do so using a different number of words. A good translation system will not be a word-for-word translation, but works by translating the idea. The issue is that you can have buttons that work fine in one language, but do not have enough space in them for the equivalent idea in the translated language.

The text-based translation programs I have worked with used a very similar system as the one in this class; replacing one phrase with the equivalent in another language. But GUI based translations should be more complex, taking into consideration fonts, size of components, and the like. The Microsoft translation system also takes into consideration localization of numbers (using commas instead of periods where they are used in other languages/currencies.)

Where this particular class works well, is when you have nonstandard languages, like "Pirate."

History

  • 7th December, 2014: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


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

Comments and Discussions

 
QuestionBuilt strings don't translate... Pin
GrahamPye8-Dec-14 3:35
GrahamPye8-Dec-14 3:35 
AnswerRe: Built strings don't translate... Pin
BouncyTarget8-Dec-14 8:23
BouncyTarget8-Dec-14 8:23 

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.