Proper way to change language at runtime

Viewed 57968

What is the proper way to change Form language at runtime?

  1. Setting all controls manually using recursion like this
  2. Save language choice to file > Restart Application > Load languge choice before InitializeComponent();
  3. Using Form constructor to replace instance of active from (if this is even possible)
  4. Something else

There is so much half written threads about this but none provides real answer on what is proper way to do this?

UPDATE:
To clarify my question:

Doing something like this:

public Form1()
{
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("de");
    this.InitializeComponent();
}

works fine and all my controls and everything else in resources get translated correctly. And doing something like:

private void button1_Click(object sender, EventArgs e)
{
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("en");
}

does nothing, Form stays in language I set up before InitializeComponent();

5 Answers

Hope this would help anyone, I found it best for me cause i needed to change buttons location according the lang (browse on the right or left of the search box and labels next to text fields).

  1. save a public var on the main that will hold the lang.
  2. created a class which handles the visual part
  3. created xml files that will hold any language data and more (in my xml tag name=object name).
  4. sent that class's constructor the form (to save and work with)
  5. connect to that current xml file

From main form call whenever you want to initialView (part of the view class) and change lang (and more) anytime (just connect to the right xml file):

public void initialView()
{
    //Set rightToLeft values
    initialIndent(mainForm);

    //set visual text values
    initialTxt();
}

private void initialTxt()
{
    // Are there any more controls under mainObj (Form1)?
    Boolean endOfElemsUnderPnl = false;

    // The current Control im working on
    Object curObj = mainForm;

    do
    {
        // MenuStrip needs to be handled separately
        if (typeof(MenuStrip).ToString().Equals(curObj.GetType().ToString()))
        {
            foreach (ToolStripMenuItem miBase in ((MenuStrip)(curObj)).Items)
            {
                miBase.Text = mainForm.dbCon.getData(miBase.Name.ToString());
                foreach (ToolStripMenuItem miInnerNode in miBase.DropDownItems)
                {
                    miInnerNode.Text = mainForm.dbCon.getData(miInnerNode.Name.ToString());
                }
            }
        }

        // Any other Control i have on the form
        else
        {
            ((Control)(curObj)).Text = mainForm.dbCon.getData(((Control)(curObj)).Name.ToString());
        }

        curObj = mainForm.GetNextControl(((Control)(curObj)), true);

        // Are there any more controls under mainObj?
        if (null == curObj)
        {
            endOfElemsUnderPnl = true;
        }

    } while (!endOfElemsUnderPnl);
}

private void initialIndent(frmMyFileManager parent)
{
    if (parent.Language.Equals("Hebrew"))
    {
        parent.RightToLeft = RightToLeft.Yes;
    }
    else if (parent.Language.Equals("English"))
    {
        parent.RightToLeft = RightToLeft.No;
    }
    else
    {
        parent.RightToLeft = RightToLeft.No;
    }
}

And this is an example of how easy it is for my at runtime:

private void selectLanguageToolStripMenuItem_Click(object sender, EventArgs e)
{
    DialogResult res = MessageBox.Show(this, "click yes for english and no for hebrew", "Select language", MessageBoxButtons.YesNoCancel);

    if (DialogResult.Yes == res)
    {
        Language = "English";
    }
    else if (DialogResult.No == res)
    {
        Language = "Hebrew";
    }
    dbCon = new CDBConnector("****\\lang" + Language + ".xml");
    view.initialView();
}
Related