I want my application to support multiple UI-languages (aka i18n). To do so, I have built the static class below, to automatically translate the form and all its contents to the desired language. It looks into a resource file for the user's Culture, and replaces the .Text properties of the controls with the strings it finds there, or falls-back to the initial strings, which is English.Usage is calling TranslateForm(this) from each form's constructor.Two concerns about my code:* The overloading of the Translate method. I didn't find any way to overcome this.* The special handling of different controls, which seems unnecessary.I'm not a professional programmer, so any correction / enhancement / fix to my code is more than welcomed!using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Threading;using System.Globalization;using System.Resources;using System.Reflection;using System.Runtime.InteropServices;using System.Collections;namespace blahblah{    static class TranslationHelper    {        static private ResourceManager rm = null;        static private CultureInfo default_ci = null;        static private CultureInfo lang_ci = null;        /// <summary>        /// translate control into the specific lang, or leave it untranslated if no translation string found        /// </summary>        /// <param name=ctrl></param>        /// <param name=lang></param>        static private void Translate(Control ctrl, string lang)        {            string str = TranslateString(ctrl.Name, lang);            if (str != null)                ctrl.Text = str;        }        static private void Translate(ToolStripMenuItem o, string lang)        {            string str = TranslateString(o.Name, lang);            if (str != null)                o.Text = str;        }        static private void Translate(ToolStripItem o, string lang)        {            string str = TranslateString(o.Name, lang);            if (str != null)                o.Text = str;        }        static private void Translate(Form o, string lang)        {            string str = TranslateString(o.Name, lang);            if (str != null)                o.Text = str;        }        /// <summary>        /// returns the <c>name</c> string from the <c>lang</c> resource        /// </summary>        /// <param name=name>string/key name</param>        /// <param name=lang>the language to translate to</param>        /// <returns>a translated string for <c>name</c></returns>        static public string TranslateString(string name, string lang)        {            if (lang_ci == null || !lang_ci.TwoLetterISOLanguageName.Equals(lang))                lang_ci = new CultureInfo(lang);            try            {                return rm.GetString(name, lang_ci);            }            catch (Exception)            {                // no translation yet                try                {                    return rm.GetString(name, default_ci);                }                catch (Exception)                {                    return null;                    //MessageBox.Show(ex.Message.ToString(), name);                    //System.Console.WriteLine(ex.Message.ToString());                }            }        }        static public void TranslateForm(string lang, Form parent)        {            if (rm == null)                rm = new ResourceManager(etimet.i18nResources.i18n, Assembly.GetExecutingAssembly(), null);            if (default_ci == null)                default_ci = new CultureInfo(en);            // handle direction            if (Program.conf.CurrentLang.Equals(he) || Program.conf.CurrentLang.Equals(ar) || Program.conf.CurrentLang.Equals(fa))            {                parent.RightToLeft = RightToLeft.Yes;            }            else            {                parent.RightToLeft = RightToLeft.No;            }            // translate the form itself            Translate(parent, lang);            // translate all the children controls, recursively            Control.ControlCollection c = parent.Controls;            foreach (Control o in c)            {                // special handling for the menu                if (o.GetType() == typeof(MenuStrip))                {                    foreach (ToolStripMenuItem it in ((MenuStrip)o).Items)                    {                        Translate(it, lang);                        //MessageBox.Show(it.Text);                        foreach (ToolStripItem f in it.DropDownItems)                        {                            if (typeof(ToolStripSeparator) != f.GetType())                                Translate(f, lang);                        }                    }                }                RecursiveTranslateCtrl(lang, o);            }        }        static private void RecursiveTranslateCtrl(string lang, Control ctrl)        {            Translate(ctrl, lang);            foreach (Control c in ctrl.Controls)            {                RecursiveTranslateCtrl(lang, c);            }        }    }}
Automatic translation of forms
c#;.net
There are built in mechanisms for automatically switching an entire form to use text from culture-specific resource files and it is more powerful than just setting the text property (ToolTips for example). The only times you should need to manually load from the resource file are for things like message boxes, but unless you need your application to block while displaying an alert you might as well use balloon tips which are localizable as well. This is an easy place to start. It will also be more efficient as the controls themselves are localization aware so there's no need to loop through anything.