Переключение языка (cultureinfo / globalization) не влияет на ToolStripMenuItems

#c# #windows #forms #globalization #cultureinfo

#c# #Windows #формы #глобализация #cultureinfo

Вопрос:

У меня есть проект приложения Windows Forms, а в основной форме у меня есть полоса меню. В каком-то месте в этой строке меню можно выбрать различные языки. Например, если пользователь выбирает «Английский», все в этой основной форме (и другие в будущем) должны быть переведены на английский язык.

Я взял это руководство: нажмите

Это отлично работает с ярлыками и тому подобным, но совсем не работает с пунктами меню tool strip. Они просто остаются с текстом по умолчанию.

Я попытался добавить еще две строки в ChangeLanguage метод:

 private void ChangeLanguage(string lang)
{
    foreach (Control c in this.Controls)
    {
        ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1));
        resources.ApplyResources(c, c.Name, new CultureInfo(lang));
        ComponentResourceManager res2 = new ComponentResourceManager(typeof(ToolStripMenuItem));
        res2.ApplyResources(c, c.Name, new CultureInfo(lang));
    }
}
  

Но он терпит неудачу и говорит:

Не удалось найти какие-либо ресурсы, подходящие для указанной культуры или нейтральной культуры. Убедитесь, что «Система.Windows.Формы.ToolStripMenuItem.resources» был правильно встроен или связан с системой сборки «.Windows.Формы» во время компиляции или что все требуемые вспомогательные сборки доступны для загрузки и полностью подписаны.

Не уверен, как поступить — любая помощь приветствуется.

Ответ №1:

Вы должны удалить последние 2 строки в вашем цикле foreach. В этих строках говорится, что вы ищете информацию о локализации в системе.Windows.Формы.Файл ToolStripMenuItem.resx, но вы хотите посмотреть в файле ресурсов Forms.

ToolStripMenuItems добавляются в коллекцию выпадающих элементов ToolStripItems, а не в коллекцию элементов управления вашей формы. Это может помочь вам решить вашу проблему.

 private void ChangeLanguage(string lang) {
    ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1));
    foreach (Control c in this.Controls) {
        resources.ApplyResources(c, c.Name, new CultureInfo(lang));
    }

    foreach (ToolStripItem item in toolStrip1.Items) {
        if (item is ToolStripDropDownItem)
            foreach (ToolStripItem dropDownItem in ((ToolStripDropDownItem)item).DropDownItems) {
                resources.ApplyResources(dropDownItem, dropDownItem.Name, new CultureInfo(lang));
            }
    }
}
  

Если у вас есть дополнительные выпадающие элементы, вам следует рассмотреть рекурсивный подход.

Редактировать: к моему первому комментарию

 private void ChangeLanguage(string lang) {
    ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1));
    foreach (Control c in this.Controls) {
        resources.ApplyResources(c, c.Name, new CultureInfo(lang));
    }
  

Изменение языка (toolStrip1.Элементы);
}

 private void ChangeLanguage(ToolStripItemCollection collection) {
    foreach (ToolStripItem item in collection) {
        resources.ApplyResources(item, item.Name, new CultureInfo(lang));
        if (item is ToolStripDropDownItem)
            ChangeLanguage(((ToolStripDropDownItem)item).DropDownItems);
    }
}
  

Комментарии:

1. Спасибо, это отчасти работает. Это изменяет только язык выпадающих элементов в строке меню, а не «заголовки» строки меню или если у меня есть дополнительное выпадающее меню внутри первого выпадающего меню.

2. Это то, что я сказал, будет рекурсивным подходом . Вызовите метод в моем редактировании вместо второго цикла foreach . Теперь это гарантирует, что все уровни вашей структуры меню будут зациклены для локализации.

3. Спасибо. Этот код работает для меня. Я не знал, что пункты меню не из Form.Controls.