简体   繁体   English

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

[英]WinForms localization. How to change the language of a Menu

EDIT: Although useful, the "duplicate" question does not give an answer to this question. 编辑:尽管有用,但“重复”问题并未给出该问题的答案。 First, the main theme here is Menus , so please don't mark this question duplicate to a question that is not. 首先,这里的主题是Menus ,所以请不要将此问题标记为不是。

I have been trying to understand correctly how to localize an application. 我一直试图正确理解如何本地化应用程序。 Right now I have a form with a label, a menu and a listbox. 现在,我有一个带有标签,菜单和列表框的表单。 I have localized the form so that now I have three resx files. 我已经本地化了表单,以便现在有了三个resx文件。

I used ZRT answer to implement the listbox to change the language on runtime. 我使用ZRT答案来实现列表框,以在运行时更改语言。 Instead of his implementation of ApplyLocalization I used 我没有使用他实现的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);
       }

    }

With that I can succesfully translate the label only. 这样,我可以成功地仅翻译标签。

Debugging the process I can see that there are three Controls: (The listbox, the label and the menu). 调试过程中,我看到有三个控件:(列表框,标签和菜单)。 For the listbox ApplyResources do nothing. 对于列表框,ApplyResources不执行任何操作。 For the label it does change the language of the label. 对于标签,它确实会更改标签的语言。 The problem is for the menu. 问题出在菜单上。 When c is the menuStrip, ApplyResources only applies it to the menuStrip, but not the menu options that are the ones that needs to be translated. c是menuStrip时, ApplyResources仅将其应用于menuStrip, ApplyResources将其应用于需要翻译的菜单选项。 (Actually the same thing happens to the listbox since the contents of the listbox are not translated either) (实际上,列表框发生了相同的事情,因为列表框的内容也未翻译)

My question is how can I apply the resources to the internals (submenus) of a menu so that the menu contents also gets translated? 我的问题是如何将资源应用于菜单的内部(子菜单) 以便菜单内容也得到翻译?

There are a few problems in your function: 您的函数中存在一些问题:

  • Your function is just loop over the direct child controls of the form. 您的功能只是循环访问窗体的直接子控件。 It's not checking all the controls in controls hierarchy. 它不是检查控件层次结构中的所有控件。 For example controls which are hosted in containers like panel are not in Controls collection of the form. 例如,在面板之类的容器中托管的Controls不在表单的“ Controls集合中。

  • Your function is also missing components like ContextMenu which are not in Controls collection of the form. 您的函数还缺少不在Controls集合中的诸如ContextMenu组件。

  • The function is treating all controls in the same way, while some controls need a custom logic. 该功能以相同的方式处理所有控件,而某些控件需要自定义逻辑。 The problem is not limited to Menu or ListBox . 该问题不仅限于MenuListBox You need specific logic for ComboBox , ListBox , ListView , TreeView , DataGridView , ToolStrip , ContextMenuStrip , MenuStrip , StatusStrip and maybe some other controls which I forget to mention. 您需要ComboBoxListBoxListViewTreeViewDataGridViewToolStripContextMenuStripMenuStripStatusStrip以及其他一些我可能忘记提及的控件的特定逻辑。 For example you can find the logic for ComboBox in 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. 重要说明:我认为将选定的区域性保存在一个设置中,然后关闭并重新打开该表单或整个应用程序,并在显示该表单之前或在Main方法中应用区域性是更好的选择。

Anyway, here I'll share a solution here. 无论如何,在这里我将分享一个解决方案。 Be informed that the solution will not solve all the problems that I mentioned above, but solves theproblem for MenuStrip and ToolStrip . 知道该解决方案不能解决我上面提到的所有问题,但可以解决MenuStripToolStrip

While you may learn new things from the following piece of code, I assume it's just for learning purpose. 尽管您可以从以下代码中学到新东西,但我认为这只是出于学习目的。 In general I advise you to read the Important note again! 通常,我建议您再次阅读重要说明!

Step 1 - Find all items of the MenuStrip or ToolStrip : 步骤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;
        }
    }
}

Step 2 - Create a method to get all controls: 第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;
        }
    }
}

Step 3 - Create the ChangeLanguage method and add the logic for different controls, for example in the following piece of code, I've added the logic for MenuStrip which is deriving from ToolStrip : 第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);
    }
}

Step 4 - Call the ChangeLanguage method: 第4步 -调用ChangeLanguage方法:

ChangeLanguage("fa-IR");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM