在C#中如何在不同的表单语言之间切换?

huangapple go评论68阅读模式
英文:

how switch between form languages in c#?

问题

Here's the translated portion of your text:

"我有一个带有11个窗体的C# Windows窗体应用程序。我使用所有窗体的语言属性来设计它们的两种语言(默认语言和美国英语)。在我的设置窗体中,我有2个单选按钮,当用户单击它们时,所有窗体的语言都会更改。我找到了两个示例,但都无法正常工作。如何解决这个问题?

这是我的第一次尝试:(不起作用,会破坏窗体上控件的布局)

private void radioButtonDefault_Click(object sender, EventArgs e)
{
    Thread.CurrentThread.CurrentUICulture = CultureInfo.CurrentUICulture;
    // 重新加载窗体或控件以应用新语言
    this.Controls.Clear();
    InitializeComponent();
}

private void radioButtonEnglish_Click(object sender, EventArgs e)
{
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
    // 重新加载窗体或控件以应用新语言
    this.Controls.Clear();
    InitializeComponent();
}

这是我的第二次尝试:(也无法正常运行,出现太多错误)

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();
    // 加载默认语言的资源
    System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SettingForm));
    resources.ApplyResources(this, "$this");
    // 将资源应用于窗体的所有控件
    ApplyResources(this, this.Name, CultureInfo.CurrentUICulture);
    this.ResumeLayout(false);
}

private void SwitchToEnglish()
{
    this.SuspendLayout();
    this.Localizable = true;
    this.components = new System.ComponentModel.Container();
    // 加载英语语言的资源
    System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SettingForm));
    resources.ApplyResources(this, "$this");
    // 将资源应用于窗体的所有控件
    ApplyResources(this, this.Name, CultureInfo.GetCultureInfo("en-US"));
    this.ResumeLayout(false);
}

如何解决我的问题?请帮忙。"

If you have any specific questions or need further assistance with your code, please let me know.

英文:

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?

答案1

得分: 2

Change language at run-time

在显示主界面之前,设置语言的正确方式是在启动时进行。因此,对于主表单,最好在启动时执行此操作,否则您需要仔细编写一个考虑到控件之间差异的逻辑。这并不像在链接的帖子中所展示的那样简单。例如,ComboBox、ListBox、ListView、TreeView、DataGridView、ToolStrip、ContextMenuStrip、MenuStrip、StatusStrip 或者其他一些控件需要不同于其他控件的逻辑。

如果出于任何原因您希望继续尝试在运行时重新加载资源,请参考我的示例 如何在运行时更改菜单的语言,但我不建议在生产环境中使用它,而是建议依赖于重新启动应用程序。

Change language with restart

如果您想知道如何在重新启动应用程序时更改语言,我会这样处理:

  • 我会使用应用程序设置来存储所选的语言。
  • 我会在启动时设置语言。
  • 我会定义一个受支持语言的列表,并使用代码在主窗体的菜单下显示它们。
  • 在菜单项的单击事件处理程序中,我会将所选的语言保存在设置中,并在用户允许的情况下重新启动应用程序。

在C#中如何在不同的表单语言之间切换?

  1. 我会向项目中添加一个 Settings.settings 文件。然后我会添加一个类型为字符串的 Culture 设置,其值等于我想要用作默认文化的文化,比如 "fa-IR"。

    在C#中如何在不同的表单语言之间切换?

  2. 在 program.cs 中,我会定义受支持的文化列表,并根据设置中的值设置当前线程的当前文化和当前 UI 文化:

    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. 然后在主窗体中,我会添加一个语言菜单项,比如 languageToolStripMenuItem。然后在窗体启动时,我会将受支持的语言作为菜单项添加,并根据设置设置选定的语言,同时添加一个单击事件处理程序以保存在选择新语言时的设置,并询问是否重新启动应用程序:

    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("要应用所选语言,您需要重新启动应用程序。\n" +
                    "您要现在重新启动吗?\n" +
                    "如果选择否或取消,语言将在下次打开应用程序时生效。",
                    "重新启动应用程序?",
                    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;
    }
    
英文:

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.

在C#中如何在不同的表单语言之间切换?

  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".

    在C#中如何在不同的表单语言之间切换?

  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[] {
                &quot;fa-IR&quot;,
                &quot;en-US&quot;,
            };
            [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) =&gt;
            {
                var selected = (ToolStripMenuItem)sender;
                selected.Checked = true;
                selected.Owner.Items.OfType&lt;ToolStripMenuItem&gt;()
                    .Except(new[] { selected })
                    .ToList().ForEach(x =&gt; x.Checked = false);
                Settings.Default.Culture = (string)selected.Tag;
                Settings.Default.Save();
                if (MessageBox.Show(&quot;To apply the selected language you &quot; +
                    &quot;need to restart the application.\n&quot; +
                    &quot;Do you want to restart now?\n&quot; +
                    &quot;If you choose no or cancel, the language &quot; +
                    &quot;applies the next time you open the application.&quot;,
                    &quot;Restart application?&quot;,
                    MessageBoxButtons.YesNoCancel,
                    MessageBoxIcon.Question,
                    MessageBoxDefaultButton.Button3) == DialogResult.Yes)
                {
                    Application.Restart();
                }
            };
            languageToolStripMenuItem.DropDownItems.Add(cultureItem);
        }
        var item = languageToolStripMenuItem.DropDown.Items
            .OfType&lt;ToolStripMenuItem&gt;().Where(x =&gt; $&quot;{x.Tag}&quot; == Settings.Default.Culture)
            .FirstOrDefault();
        if (item != null)
            item.Checked = true;
    }
    

huangapple
  • 本文由 发表于 2023年5月7日 14:56:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76192571.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定