WinForms本地化.如何更改菜单语言 [英] WinForms localization. How to change the language of a Menu

查看:93
本文介绍了WinForms本地化.如何更改菜单语言的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尽管有用,但重复"问题并未给出此问题的答案.首先,这里的主题是菜单,所以请不要将此问题标记为不是.

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.

我一直试图正确理解如何本地化应用程序. 现在,我有一个带有标签,菜单和列表框的表单. 我已经本地化了表格,所以现在我有了三个resx文件.

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.

我使用了 Z.R.T.答案以实施列表框以在运行时更改语言.我没有使用他的ApplyLocalization实施方式

I used Z.R.T. answer to implement the listbox to change the language on runtime. Instead of his implementation of ApplyLocalization I used

 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.

调试过程中,我看到有三个控件:(列表框,标签和菜单).对于列表框,ApplyResources不执行任何操作.对于标签,它确实会更改标签的语言.问题出在菜单上.当c是menuStrip时,ApplyResources仅将其应用于menuStrip,而不将其应用于需要翻译的菜单选项. (实际上,由于列表框的内容也未翻译,因此列表框也会发生相同的事情)

Debugging the process I can see that there are three Controls: (The listbox, the label and the menu). For the listbox ApplyResources do nothing. 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. (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:

  • 您的函数只是在窗体的直接子控件上循环.它不是检查控件层次结构中的所有控件.例如,在面板之类的容器中托管的控件不在表单的Controls集合中.

您的函数还缺少诸如ContextMenu的组件,这些组件不在表单的Controls集合中.

Your function is also missing components like ContextMenu which are not in Controls collection of the form.

该函数以相同的方式处理所有控件,而某些控件需要自定义逻辑.问题不仅限于MenuListBox.您需要用于ComboBoxListBoxListViewTreeViewDataGridViewToolStripContextMenuStripMenuStripStatusStrip的特定逻辑,也许还有一些我忘记提及的控件.例如,您可以在这篇文章中找到ComboBox的逻辑.

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. You need specific logic for ComboBox, ListBox, ListView, TreeView, DataGridView, ToolStrip, ContextMenuStrip, MenuStrip, StatusStrip and maybe some other controls which I forget to mention. For example you can find the logic for ComboBox in this post.

重要提示::我相信将所选区域性保存到设置中,然后关闭 并重新打开表格或整个应用程序并应用文化 在显示表单之前或在Main方法中是一个更好的选择.

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的问题.

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.

尽管您可以从下面的代码中学到新知识,但我认为这只是出于学习目的.通常,我建议您再次阅读重要说明!

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!

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

Step 1 - Find all items of the MenuStrip or ToolStrip:

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步-创建一种获取所有控件的方法:

Step 2 - Create a method to get all controls:

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:

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:

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本地化.如何更改菜单语言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆