Я просто не могу заставить локализацию работать.
У меня есть библиотека классов. Теперь я хочу создать файлы 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"
дляtrue
Language
свойство нужный вам язык (из приятного выпадающего списка)Изменить: Эта статья 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.resx
strings.fr.resx
strings.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 во внешние переводческие компании, импортировать их снова, перерабатывать переводы из других проектов и т. д ...
Больше информации: