Я просто не могу заставить локализацию работать.
У меня есть библиотека классов. Теперь я хочу создать файлы resx и вернуть некоторые значения, основанные на культуре потоков.
Как я могу это сделать?
Я просто не могу заставить локализацию работать.
У меня есть библиотека классов. Теперь я хочу создать файлы resx и вернуть некоторые значения, основанные на культуре потоков.
Как я могу это сделать?
Ответы:
strings.resx.System.ThreadingиSystem.GlobalizationЗапустите этот код:
Console.WriteLine(Properties.strings.Hello);
Должно быть напечатано «Привет».
Теперь добавьте новый файл ресурсов с именем "strings.fr.resx" (обратите внимание на часть "fr"; она будет содержать ресурсы на французском языке). Добавьте строковый ресурс с тем же именем, что и в strings.resx, но со значением на французском языке (Name = "Hello", Value = "Salut"). Теперь, если вы запустите следующий код, он должен напечатать Salut:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");
Console.WriteLine(Properties.strings.Hello);
Что происходит, так это то, что система будет искать ресурс для "FR-FR". Он не найдет его (поскольку мы указали «fr» в вашем файле »), а затем вернется к проверке« fr », которую он находит (и использует).
Следующий код выведет «Hello»:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
Console.WriteLine(Properties.strings.Hello);
Это связано с тем, что он не находит никаких ресурсов «en-US», а также ресурсов «en», поэтому он вернется к значению по умолчанию, которое мы добавили с самого начала.
При необходимости вы можете создавать файлы с более конкретными ресурсами (например, strings.fr-FR.resx и strings.fr-CA.resx для французского во Франции и Канаде соответственно). В каждый такой файл вам нужно будет добавить ресурсы для тех строк, которые отличаются от ресурса, к которому он будет возвращен. Поэтому, если текст одинаков во Франции и Канаде, вы можете поместить его в strings.fr.resx, в то время как строки, отличающиеся на канадском французском языке, могут перейти в strings.fr-CA.resx.
Access Modifierдолжен быть установлен Publicдля класса ресурса, который будет создан. Класс не обязательно находится в пространстве имен Properties, это место, где вы размещаете файл .resx.
Это довольно просто, на самом деле. Например, создайте новый файл ресурсов Strings.resx. Установите Access Modifierв Public. Используйте шаблон файла apprioriate, чтобы Visual Studio автоматически сгенерировал класс средства доступа (имя будетStrings в этом случае ). Это ваш язык по умолчанию.
Теперь, когда вы хотите добавить, скажем, немецкую локализацию, добавьте локализованный файл resx. Это будет обычно Strings.de.resxв этом случае. Если вы хотите добавить дополнительную локализацию, скажем, для Австрии, вы дополнительно создадите Strings.de-AT.resx.
Теперь создайте строку - скажем, строку с именем HelloWorld . В вашем Strings.resx, добавьте эту строку со значением «Hello, world!». В Strings.de.resxдобавьте «Привет, Welt!». И вStrings.de-AT.resx добавьте «Servus, Welt!». Это так далеко.
Теперь у вас есть этот сгенерированный Stringsкласс, и у него есть свойство с геттеромHelloWorld . При получении этого свойства загрузится "Servus, Welt!" когда в качестве локали используется de-AT, «Привет, Welt!», когда в качестве локали используется любая другая локаль (включая de-DE и de-CH), и «Hello, World!», если в качестве локали используется что-то еще. Если строка отсутствует в локализованной версии, менеджер ресурсов будет автоматически идти вверх по цепочке, от самого специализированного к инвариантному ресурсу.
Вы можете использовать ResourceManagerкласс для большего контроля над тем, как именно вы загружаете вещи. Сгенерированный Stringsкласс использует это также.
В дополнение к отличному ответу @Fredrik Mörk на строки, чтобы добавить локализацию в форму, сделайте следующее:
"Localizable"дляtrueLanguage свойство нужный вам язык (из приятного выпадающего списка)Изменить: Эта статья MSDN по локализации Windows Forms не является той, которую я связал, но может пролить больше света, если это необходимо. (старый был забран)
Отличный ответ Ф.Мёрка. Но если вы хотите обновить перевод или добавить новые языки после выпуска приложения, вы застряли, потому что вам всегда нужно перекомпилировать его для создания resources.dll.
Вот решение для ручной компиляции ресурсов DLL. Он использует средства resgen.exe и al.exe (устанавливаются вместе с SDK).
Скажем, у вас есть файл ресурсов Strings.fr.resx, вы можете скомпилировать dll ресурсов с помощью следующего пакета:
resgen.exe /compile Strings.fr.resx,WpfRibbonApplication1.Strings.fr.resources
Al.exe /t:lib /embed:WpfRibbonApplication1.Strings.fr.resources /culture:"fr" /out:"WpfRibbonApplication1.resources.dll"
del WpfRibbonApplication1.Strings.fr.resources
pause
Не забудьте сохранить оригинальное пространство имен в именах файлов (здесь «WpfRibbonApplication1»)
Исправление и проработка ответа @Fredrik Mörk .
strings.resxфайл ресурсов в свой проект (или другое имя файла)Access Modifierв Public(на strings.resxвкладке открытого файла)Hello, значение Hello)Visual Studio автоматически генерирует соответствующий stringsкласс, который фактически помещается в strings.Designer.cs. Класс находится в том же пространстве имен, в котором вы ожидаете разместить вновь созданный .csфайл.
Этот код всегда печатается Hello, потому что это ресурс по умолчанию, а ресурсы для конкретного языка недоступны:
Console.WriteLine(strings.Hello);
Теперь добавьте новый языковой ресурс:
strings.fr.resx(для французского)Hello, значение Salut)Следующий код печатает Salut:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");
Console.WriteLine(strings.Hello);
Какой ресурс используется, зависит от Thread.CurrentThread.CurrentUICulture. Он устанавливается в зависимости от языковой настройки пользовательского интерфейса Windows или может быть установлен вручную, как в этом примере. Узнайте больше об этом здесь .
Вы можете добавить специфичные для страны ресурсы, такие как strings.fr-FR.resxилиstrings.fr-CA.resx .
Используемая строка определяется в следующем порядке приоритета:
strings.fr-CA.resxstrings.fr.resxstrings.resxОбратите внимание, что языковые ресурсы генерируют спутниковые сборки .
Также узнайте, как CurrentCultureотличается от CurrentUICulture здесь .
В дополнение к @Eric Bole-Feysot :
Благодаря спутниковым сборкам локализация может быть создана на основе файлов .dll / .exe . Сюда:
Существует малоизвестный инструмент под названием LSACreator (бесплатный для некоммерческого использования или покупки), который позволяет создавать локализацию на основе файлов .dll / .exe. Фактически, внутри (в каталоге языкового проекта) он создает / управляет локализованными версиями файлов resx и компилирует сборку аналогично тому, как описывал @Eric Bole-Feysot .
ResourceManager и .resx немного грязные.
Вы можете использовать Lexical.Localization ¹, который позволяет встраивать значения по умолчанию и значения, специфичные для культуры, в код и расширяться во внешних файлах локализации для других культур (таких как .json или .resx).
public class MyClass
{
/// <summary>
/// Localization root for this class.
/// </summary>
static ILine localization = LineRoot.Global.Type<MyClass>();
/// <summary>
/// Localization key "Ok" with a default string, and couple of inlined strings for two cultures.
/// </summary>
static ILine ok = localization.Key("Success")
.Text("Success")
.fi("Onnistui")
.sv("Det funkar");
/// <summary>
/// Localization key "Error" with a default string, and couple of inlined ones for two cultures.
/// </summary>
static ILine error = localization.Key("Error")
.Format("Error (Code=0x{0:X8})")
.fi("Virhe (Koodi=0x{0:X8})")
.sv("Sönder (Kod=0x{0:X8})");
public void DoOk()
{
Console.WriteLine( ok );
}
public void DoError()
{
Console.WriteLine( error.Value(0x100) );
}
}
¹ (я хранитель этой библиотеки)
Обычно вы помещаете свои переводы в файлы ресурсов, например resources.resx.
Каждая конкретная культура имеет свое имя, например resources.nl.resx, resources.fr.resx, resources.de.resx,…
Теперь самая важная часть решения - поддерживать ваши переводы. В Visual Studio установите инструмент Microsoft MAT: Multilingual App Toolkit (MAT). Работает с winforms, wpf, asp.net (core), uwp,…
В целом, например, для решения WPF, в проекте WPF
[assembly: System.Resources.NeutralResourcesLanguage("en")]Вы увидите, что будет создана новая папка с названием «MultilingualResources», содержащая ....nl.xlfфайл.
Единственное, что вам теперь нужно сделать, это:
(Файлы .xlf должны открываться с помощью «Многоязычного редактора», если это не так, щелкните правой кнопкой мыши файл .xlf, выберите «Открыть с помощью…» и выберите «Многоязычный редактор».
Радоваться, веселиться! теперь вы также можете видеть то, что не было переведено, экспортировать переводы в xlf во внешние переводческие компании, импортировать их снова, перерабатывать переводы из других проектов и т. д ...
Больше информации: