WinForms本地化。如何更改菜单的语言

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WinForms本地化。如何更改菜单的语言相关的知识,希望对你有一定的参考价值。

编辑:虽然有用,但“重复”问题并没有给出这个问题的答案。首先,这里的主题是菜单,所以请不要将此问题标记为不是问题。

我一直在努力正确理解如何本地化应用程序。现在我有一个带有标签,菜单和列表框的表单。我已经对表单进行了本地化,现在我有三个resx文件。

我使用Z.R.T. answer来实现列表框以在运行时更改语言。而不是他使用的ApplyLocalization的实施

 public void ApplyLocalization(CultureInfo ci)
   {
    //button1.Text = Properties.Resources.button;
    ComponentResourceManager componentResourceManager = new ComponentResourceManager(this.GetType());

    foreach (Control c in this.Controls)
      {
       componentResourceManager.ApplyResources(c, c.Name, ci);
       }

    }

有了这个,我只能成功翻译标签。

调试过程我可以看到有三个控件:(列表框,标签和菜单)。对于列表框,ApplyResources什么都不做。对于标签,它确实改变了标签的语言。问题出在菜单上。当c是menuStrip时,ApplyResources仅将其应用于menuStrip,而不是应用于需要翻译的菜单选项。 (实际上同样的事情发生在列表框中,因为列表框的内容也没有被翻译)

我的问题是如何将资源应用于菜单的内部(子菜单),以便菜单内容也被翻译?

答案

您的功能有一些问题:

  • 您的函数只是循环遍历表单的直接子控件。它不会检查控件层次结构中的所有控件。例如,托管在面板等容器中的控件不在表单的Controls集合中。
  • 你的功能也缺少像ContextMenu这样的组件,这些组件不在表单的Controls集合中。
  • 该函数以相同的方式处理所有控件,而某些控件需要自定义逻辑。问题不仅限于MenuListBox。你需要具体的逻辑ComboBoxListBoxListViewTreeViewDataGridViewToolStripContextMenuStripMenuStripStatusStrip以及其他一些我忘记提及的控件。例如,您可以在ComboBox中找到this post的逻辑。

重要说明:我认为将选定的文化保存在一个设置中然后关闭并重新打开表单或整个应用程序并在显示表单之前应用文化或在Main方法中是更好的选择。

无论如何,在这里我将在这里分享一个解决方案。被告知解决方案不会解决我上面提到的所有问题,但解决了MenuStripToolStrip的问题。

虽然您可以从下面的代码中学习新的东西,但我认为这仅仅是为了学习目的。一般情况下,我建议您再次阅读重要说明!

第1步 - 查找MenuStripToolStrip的所有项目:

using System.Collections.Generic;
using System.Windows.Forms;
public static class ToolStripExtensions
{
    public static IEnumerable<ToolStripItem> AllItems(this ToolStrip toolStrip)
    {
        return toolStrip.Items.Flatten();
    }
    public static IEnumerable<ToolStripItem> Flatten(this ToolStripItemCollection items)
    {
        foreach (ToolStripItem item in items)
        {
            if (item is ToolStripDropDownItem)
                foreach (ToolStripItem subitem in 
                    ((ToolStripDropDownItem)item).DropDownItems.Flatten())
                        yield return subitem;
            yield return item;
        }
    }
}

第2步 - 创建一个获取所有控件的方法:

using System.Collections.Generic;
using System.Windows.Forms;
public static class ControlExtensions
{
    public static IEnumerable<Control> AllControls(this Control control)
    {
        foreach (Control c in control.Controls)
        {
            yield return c;
            foreach (Control child in c.Controls)
                yield return child;
        }
    }
}

第3步 - 创建ChangeLanguage方法并为不同的控件添加逻辑,例如在下面的代码中,我添加了MenuStrip的逻辑,它来自ToolStrip

private void ChangeLanguage(string lang)
{
    var rm = new ComponentResourceManager(this.GetType());
    var culture = CultureInfo.CreateSpecificCulture(lang);
    Thread.CurrentThread.CurrentCulture = culture;
    Thread.CurrentThread.CurrentUICulture = culture;
    foreach (Control c in this.AllControls())
    {
        if (c is ToolStrip)
        {
            var items = ((ToolStrip)c).AllItems().ToList();
            foreach (var item in items)
                rm.ApplyResources(item, item.Name);
        }
        rm.ApplyResources(c, c.Name);
    }
}

第4步 - 调用ChangeLanguage方法:

ChangeLanguage("fa-IR");

以上是关于WinForms本地化。如何更改菜单的语言的主要内容,如果未能解决你的问题,请参考以下文章

如何通过应用语言本地化 iOS 通知

WinForms本地化。该语言不反映默认的resx文件

如何更改 Android 中各个片段的 ActionBar 颜色?

在方向更改时保留列表片段中的列表

WinForms 中的托管线程如何使用“this->”在回调函数中访问表单元素(更改值等)

如何将 winforms 对话框附加到现有的工具栏/菜单栏(编译的 C++ 应用程序)?