1

Hi I have C# windows form with 11 forms. I use language Properties of All forms to design them in 2 language (default and English united state). In my setting form I have 2 radio button and I want when user click on them the languages of all form change. I find 2 example for this but none of them work how to do this?

this is my first try: (not working and Messing up the placement of controls on the form)

 private void radioButtonDefault_Click(object sender, EventArgs e)
        {
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CurrentUICulture;
            // Reload the form or the controls to apply the new language
            this.Controls.Clear();
            InitializeComponent();
        }

        private void radioButtonEnglish_Click(object sender, EventArgs e)
        {
            Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
            // Reload the form or the controls to apply the new language
            this.Controls.Clear();
            InitializeComponent();
        }

this is my Second try: (not run get too many error)

private void radioButtonDefault_Click(object sender, EventArgs e)

{
    SwitchToDefaultLanguage();
}

private void radioButtonEnglish_Click(object sender, EventArgs e)
{
    SwitchToEnglish();
}

private static void ApplyResources(Control control, string name, CultureInfo culture)
{
    System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(control.GetType(), name, culture);
    control.Text = resources.GetString("$this.Text");
    foreach (Control child in control.Controls)
    {
        ApplyResources(child, child.Name, culture);
    }
}

private void SwitchToDefaultLanguage()
{
    this.SuspendLayout();
    this.Localizable = true;
    this.components = new System.ComponentModel.Container();
    // Load the resources for the default language
    System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SettingForm));
    resources.ApplyResources(this, "$this");
    // Apply the resources to all the controls of the form
    ApplyResources(this, this.Name, CultureInfo.CurrentUICulture);
    this.ResumeLayout(false);
}

private void SwitchToEnglish()
{
    this.SuspendLayout();
    this.Localizable = true;
    this.components = new System.ComponentModel.Container();
    // Load the resources for the English language
    System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SettingForm));
    resources.ApplyResources(this, "$this");
    // Apply the resources to all the controls of the form
    ApplyResources(this, this.Name, CultureInfo.GetCultureInfo("en-US"));
    this.ResumeLayout(false);
}

how can solve my problem? please help?

sadegh
  • 103
  • 5
  • 1
    It's been a long time since I've used Winforms so I can't really answer your question - but you should read [Globalizing Windows Forms applications](https://learn.microsoft.com/en-us/dotnet/desktop/winforms/advanced/globalizing-windows-forms?view=netframeworkdesktop-4.8) – Zohar Peled May 07 '23 at 08:03
  • 1
    See these questions [Proper way to change language at runtime](https://stackoverflow.com/questions/11711426/proper-way-to-change-language-at-runtime) [How do I change the culture of a WinForms application at runtime?](https://stackoverflow.com/questions/7556367/how-do-i-change-the-culture-of-a-winforms-application-at-runtime) – John Wu May 07 '23 at 08:34
  • The proper way of setting the language, is at the startup before showing the main form, otherwise you need to carefully write a logic which considers the differences between controls. It's not as easy as it's shown in the linked posts. For example MenuStrip, or ComboBox need different logic. If for any reason you'd like to continue your attempt to reload resources at runtime, take a look at my example [here](https://stackoverflow.com/a/52179254/3110834), but to be honest, I'd not use it in production and I'd rely on restarting the application. – Reza Aghaei May 07 '23 at 23:01

1 Answers1

2

Change language at run-time

The proper way of setting the language is before showing main. So for the main form, it's best to do it in startup, otherwise you need to carefully write a logic which considers the differences between controls. It's not as easy as it's shown in the linked posts. For example ComboBox, ListBox, ListView, TreeView, DataGridView, ToolStrip, ContextMenuStrip, MenuStrip, StatusStrip or maybe a few other controls need different logic than other controls.

If for any reason you'd like to continue your attempt to reload resources at runtime, take a look at my example How to change language of a menu at run-time, but I'd not use it in production and I'd rely on restarting the application.

Change language with restart

If you'd like to know how to do it with restarting the application, this is how I'll handle it:

  • I'll use application settings to store the selected language.
  • I'll set the language at startup
  • I'll define a list of supported languages and using code, I'll show those under a menu in the main form.
  • In the click event handler of the menu items, I save the selected language in the setting, and restart the app with user's permission.

enter image description here

  1. I'll add a Settings.settings file to the project. Then I'll add a Culture setting having string as type with a value equal to the culture that I'd like to use as default culture, let's say "fa-IR".

    enter image description here

  2. At the program.cs, I'll define list of supported cultures, and I'll set the current culture and current UI culture of the current thread, based on the value that I have in the settings:

    using System.Globalization;
    namespace WinFormsSample
    {
        internal static class Program
        {
            public static string[] SupportedCultures = new[] {
                "fa-IR",
                "en-US",
            };
            [STAThread]
            static void Main()
            {
                ApplicationConfiguration.Initialize();
                var culture = Settings.Default.Culture;
                if(SupportedCultures.Contains(culture))
                {
                    Thread.CurrentThread.CurrentUICulture =
                        Thread.CurrentThread.CurrentCulture =
                        CultureInfo.GetCultureInfo(Settings.Default.Culture);
                }
                Application.Run(new Form1());
            }
        }
    }
    
  3. Then in the main form, I'll add a menu item for language, let's say languageToolStripMenuItem. Then at the startup of the form, I'll add the supported languages as menu items and set the selected one based on the settings, and also add a click event handler to save the settings when a new language is selected and then asking to restart the app:

    public Form1()
    {
        InitializeComponent();
        foreach (var culture in Program.SupportedCultures)
        {
            var cultureItem = new ToolStripMenuItem();
            cultureItem.Text = CultureInfo.GetCultureInfo(culture).NativeName;
            cultureItem.Tag = culture;
            cultureItem.Click += (sender, args) =>
            {
                var selected = (ToolStripMenuItem)sender;
                selected.Checked = true;
                selected.Owner.Items.OfType<ToolStripMenuItem>()
                    .Except(new[] { selected })
                    .ToList().ForEach(x => x.Checked = false);
                Settings.Default.Culture = (string)selected.Tag;
                Settings.Default.Save();
                if (MessageBox.Show("To apply the selected language you " +
                    "need to restart the application.\n" +
                    "Do you want to restart now?\n" +
                    "If you choose no or cancel, the language " +
                    "applies the next time you open the application.",
                    "Restart application?",
                    MessageBoxButtons.YesNoCancel,
                    MessageBoxIcon.Question,
                    MessageBoxDefaultButton.Button3) == DialogResult.Yes)
                {
                    Application.Restart();
                }
            };
            languageToolStripMenuItem.DropDownItems.Add(cultureItem);
        }
        var item = languageToolStripMenuItem.DropDown.Items
            .OfType<ToolStripMenuItem>().Where(x => $"{x.Tag}" == Settings.Default.Culture)
            .FirstOrDefault();
        if (item != null)
            item.Checked = true;
    }
    
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398