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

标签 c# winforms menu localization listbox

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

我一直在尝试正确理解如何本地化应用程序。 现在我有一个带有标签、菜单和列表框的表单。 我已经本地化了表单,现在我有了三个 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。您需要 ComboBoxListBoxListViewTreeViewDataGridView 的特定逻辑, ToolStripContextMenuStripMenuStripStatusStrip 也许还有一些我忘记提及的其他控件。例如,您可以在 this post 中找到 ComboBox 的逻辑。 .

Important Note: I believe saving the selected culture in a setting and then closing and reopening the form or the whole application and applying culture before showing the form or in Main method is a better option.

无论如何,我在这里分享一个解决方案。请注意,该解决方案不会解决我上面提到的所有问题,但可以解决 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");

关于c# - WinForms 本地化。如何更改菜单的语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52178064/

相关文章:

c# - 将 Windows 窗体设置为最底部

c# - 读取和处理 XML 文件

css - 创建此菜单栏的工具

java - 二进制 XML 文件行 #52 : Binary XML file line #52: Error inflating class com. Askira.loopingviewpager.LoopingViewPager

c# - Asp.Net Mvc - 如何在共享 View 中有一个 "controller"

C# ASP.Net 花式按钮

c# - .NET Compact Framework - 基于 Cookie 的 Web 服务访问

c# - 使用 nhibernate 检索单个行和列并将其转换为字符串

c# - 验证 datagridview 文本框列中的 float

jQuery .slideToggle 不产生屏幕变化