#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.