c# - ComboBoxes 如何将字符串资源用于项目文本?
问题描述
使用 C# 和 WinForms,我可以将表单设置为可本地化,在其上放置标签,并为标签设置所需语言的文本。文本将作为字符串资源存储在每种语言的一个资源文件中。然后,用户可以选择一种语言,表单上的所有标签都会更改为正确的语言。
这似乎不适用于组合框。我可以将项目添加到可本地化表单的组合框中,它们将使用 ComboBox1.Item、ComboBox1.Item1 和 ComboBox1.Item2 等名称存储在资源文件中,但组合框更改时显示的文本不会更改。
我已经看到了关于如何本地化组合框的各种建议,基于将它们绑定到字典或元组列表,但在我看来,如果项目存储在资源字符串中,应该有一些更自动的方式来使用这些资源字符串. 在那儿?
编辑:这应该是一个最小的例子。表单有一个文本框、一个按钮、一个标签和一个组合框。标签和组合框各有法语 (fr-FR) 和西班牙语 (es-ES) 的资源。在文本框中输入语言名称,按钮使用以下方法更改表单的语言:
private void ChangeLanguage(string lang)
{
ComponentResourceManager crm = new ComponentResourceManager(typeof(Form2));
CultureInfo culture = CultureInfo.CreateSpecificCulture(lang);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
foreach (Control c in this.Controls)
{
crm.ApplyResources(c, c.Name, culture);
}
}
结果是标签的文本发生了变化,但组合框项的文本没有发生变化。
解决方案
如果您关闭并重新打开表单,一切都会正常工作。但是,如果您想在不关闭表单的情况下更改文化,则需要添加额外的处理ComboBox
:
if (c is ComboBox)
{
var combo = (ComboBox)c;
var count = combo.Items.Count;
combo.Items.Clear();
combo.BeginUpdate();
for (int i = 0; i < count; i++)
{
var number = i == 0 ? "" : $"{i}";
var item = crm.GetString($"{c.Name}.Items{number}");
combo.Items.Add(item);
}
combo.EndUpdate();
}
crm.ApplyResources(c, c.Name);
另请记住,您的函数只是将资源应用于表单上的控件,它忽略了嵌套控件。例如,如果某些控件托管在面板上,它将忽略它们。要解决此问题,请查看此帖子。
笔记:
一般来说,我建议重新启动表单以应用新语言,因为自定义逻辑不限于ComboBox
,您需要特定逻辑ComboBox
, ListBox
, ListView
, TreeView
, DataGridView
, ToolStrip
, ContextMenuStrip
, MenuStrip
,StatusStrip
也许还有其他我忘记提及的控件。
简而言之,我相信将选定的文化保存在一个环境中,然后Application.Restart()
在方法中应用文化Main
是您正在寻找的。
推荐阅读
- bash - 别名中的导出在 Bash 中不起作用
- javascript - Javascript - 避免模块循环依赖(组织问题?)
- mysql - 这个自内连接查询是如何工作的?
- c# - Xamarin Mac FFmpeg 启动路径无法访问
- hyper-v - 我无法在 hyper-v 中部署 Windows 11
- c++ - 如何覆盖我的项目中的柯南共享选项?
- visual-studio-code - 是否可以在 Linux 中使用 vscode-car-plugin 创建 .car 文件?
- webpack - 如何解决这个问题:gulp-inject 没有注入 _custom.scss 和 portal_normal.ftl
- bash - 如何将具有多个标志的字符串分配给可在命令中重用的变量?
- javascript - 复选框起作用,但没有动画