How do I change the culture of a WinForms application at runtime
Asked Answered
V

3

15

I have created Windows Form Program in C#. I have some problems with localization. I have resource files in 2 languages(one is for english and another is for french). I want to click each language button and change language at runtime.

But when i am clicking on button, it doesn't work. i am using this code.

private void btnfrench_Click(object sender, EventArgs e)
{
    getlanguage("fr-FR");
}

private void getlanguage(string lan)
{
    foreach (Control c in this.Controls)
    {
        ComponentResourceManager cmp = 
            new ComponentResourceManager(typeof(BanksForm));
        cmp.ApplyResources(c, c.Name, new CultureInfo(lan));
    }
}

would any pls help on this......

Many Thanks....

Veterinarian answered 26/9, 2011 at 14:9 Comment(0)
C
32

This worked:

private void button1_Click(object sender, EventArgs e)
{
    System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("fr-BE");
    ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1));
    resources.ApplyResources(this, "$this");
    applyResources(resources, this.Controls);
}

private void applyResources(ComponentResourceManager resources, Control.ControlCollection ctls)
{
    foreach (Control ctl in ctls)
    {
        resources.ApplyResources(ctl, ctl.Name);
        applyResources(resources, ctl.Controls);
    }
}

Be careful to avoid adding whistles like this that nobody will ever use. It at best is a demo feature, in practice users don't change their native language on-the-fly.

Chapman answered 26/9, 2011 at 16:34 Comment(0)
V
8

You might have to call ApplyResources recursively on the controls:

private void btnfrench_Click(object sender, EventArgs e)
{
    ApplyResourceToControl(
        this, 
        new ComponentResourceManager(typeof(BanksForm)), 
        new CultureInfo("fr-FR"))
}

private void ApplyResourceToControl(
   Control control, 
   ComponentResourceManager cmp, 
   CultureInfo cultureInfo)
{
    cmp.ApplyResources(control, control.Name, cultureInfo);

    foreach (Control child in control.Controls)
    {
        ApplyResourceToControl(child, cmp, cultureInfo);
    }
}
Vidavidal answered 26/9, 2011 at 14:26 Comment(0)
M
3

Updating the CultureInfo at runtime might reset component size. This code preserves the size and position of the controls (there will still be visible flickering though, which using SuspendLayout() couldn't fix)


    private void langItem_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
    {
        //I store the language codes in the Tag field of list items
        var itemClicked = e.ClickedItem;
        string culture = itemClicked.Tag.ToString().ToLower();

        Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture);
        ApplyResourceToControl(
        this,
        new ComponentResourceManager(typeof(GUI)),
        new CultureInfo(culture));           
    }

    private void ApplyResourceToControl(
       Control control,
       ComponentResourceManager cmp,
       CultureInfo cultureInfo)
    {
        foreach (Control child in control.Controls)
        {
            //Store current position and size of the control
            var childSize = child.Size;
            var childLoc = child.Location;
            //Apply CultureInfo to child control
            ApplyResourceToControl(child, cmp, cultureInfo);
            //Restore position and size
            child.Location = childLoc;
            child.Size = childSize;
        }
        //Do the same with the parent control
        var parentSize = control.Size;
        var parentLoc = control.Location;
        cmp.ApplyResources(control, control.Name, cultureInfo);
        control.Location = parentLoc;
        control.Size = parentSize;
    }
Misadvise answered 3/4, 2017 at 8:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.