首页 > 解决方案 > 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);
    }

}

结果是标签的文本发生了变化,但组合框项的文本没有发生变化。

标签: c#.netwinformslocalization

解决方案


如果您关闭并重新打开表单,一切都会正常工作。但是,如果您想在不关闭表单的情况下更改文化,则需要添加额外的处理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, MenuStripStatusStrip也许还有其他我忘记提及的控件。

简而言之,我相信将选定的文化保存在一个环境中,然后Application.Restart()在方法中应用文化Main是您正在寻找的。


推荐阅读