WinForms本地化.如何更改菜单语言 [英] WinForms localization. How to change the language of a Menu
问题描述
尽管有用,但重复"问题并未给出此问题的答案.首先,这里的主题是菜单,所以请不要将此问题标记为不是.
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.
该函数以相同的方式处理所有控件,而某些控件需要自定义逻辑.问题不仅限于Menu
或ListBox
.您需要用于ComboBox
,ListBox
,ListView
,TreeView
,DataGridView
,ToolStrip
,ContextMenuStrip
,MenuStrip
,StatusStrip
的特定逻辑,也许还有一些我忘记提及的控件.例如,您可以在这篇文章中找到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.
无论如何,我在这里分享一个解决方案.知道该解决方案不会解决我上面提到的所有问题,但可以解决MenuStrip
和ToolStrip
的问题.
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步-查找MenuStrip
或ToolStrip
的所有项目:
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屋!