Как использовать локализацию в C #

268

Я просто не могу заставить локализацию работать.

У меня есть библиотека классов. Теперь я хочу создать файлы resx и вернуть некоторые значения, основанные на культуре потоков.

Как я могу это сделать?

JL.
источник
PS: убедитесь, что вы установили бесплатное расширение Microsoft MAT (Multilingual App Toolkit) для visual studio ;-)
juFo

Ответы:

571
  • Добавьте файл ресурсов в свой проект (вы можете назвать его «strings.resx»), выполнив следующие действия:
    Щелкните правой кнопкой мыши Свойства в проекте, выберите « Добавить» -> «Новый элемент» ... в контекстном меню, затем в списке Выбор элементов Visual C # «Файл ресурсов» и назовите его strings.resx.
  • Добавьте строку resouce в файл resx и дайте ей правильное имя (пример: назовите ее «Hello» и дайте ей значение «Hello»)
  • Сохраните файл ресурсов ( примечание: это будет файл ресурсов по умолчанию , так как он не имеет двухбуквенного кода языка)
  • Добавьте ссылки на вашу программу: 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.

Фредрик Мёрк
источник
24
Ответ может содержать ссылку на «закулисную» сантехнику, выполняемую Visual Studio здесь: файл resx.designer.cs, обеспечивающий работу intellisense; сателлитные сборки, скомпилированные с библиотекой классов, которые необходимо развернуть с помощью скомпилированной сборки, и любые последующие проекты, использующие ее и т. д. Ответ прост и понятен, но не помогает объяснить, где что-то может пойти не так, например, если Вы не используете Visual Studio.
Тао
13
+1 пост! Вместо того, чтобы создавать файлы вручную, попробуйте Zeta Resource Editor ( zeta-resource-editor.com/index.html ). Это бесплатно и поможет вам делать такие переводы НАМНОГО быстрее, чем просто в VS.
Killnine
4
Access Modifierдолжен быть установлен Publicдля класса ресурса, который будет создан. Класс не обязательно находится в пространстве имен Properties, это место, где вы размещаете файл .resx.
Андрей Моисеев
3
Имейте в виду, что в VS 2017 resx с локализацией в winform не работает из-за ошибки (по крайней мере, до версии 15.4). Билет доступен: developercommunity.visualstudio.com/content/problem/63772/…
muccix
4
Начиная с версии .NET 4.5 также можно использовать System.Globalization.CultureInfo.DefaultThreadCurrentCulture вместо Thread.CurrentThread.CurrentUICulture, чтобы вы могли менять локаль для всего приложения вместо потока за потоком
GrixM
41

Это довольно просто, на самом деле. Например, создайте новый файл ресурсов 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класс использует это также.

OregonGhost
источник
как установить локаль?
Матеус Симон
1
@MatheusSimon: Вам не нужно. По умолчанию используется текущая локаль пользователя. Если вы хотите принудительно установить определенный языковой стандарт (например, чтобы позволить пользователям изменять язык вручную), вы должны установить System.Threading.Thread.CurrentCulture и CurrentUICulture в каждом потоке , вероятно, до того, как какие-либо ресурсы будут загружены в первый раз. Для этого проще перезапустить приложение, чем обновлять во время выполнения.
OregonGhost
15

В дополнение к отличному ответу @Fredrik Mörk на строки, чтобы добавить локализацию в форму, сделайте следующее:

  • Установите в форме свойства «сек "Localizable"дляtrue
  • Изменить форму Language свойство нужный вам язык (из приятного выпадающего списка)
  • Переведите элементы управления в эту форму и переместите их в случае необходимости (вставьте эти действительно длинные полные французские предложения!)

Изменить: Эта статья MSDN по локализации Windows Forms не является той, которую я связал, но может пролить больше света, если это необходимо. (старый был забран)

noelicus
источник
Статья MSDN больше не доступна, любая замена?
fuomag9
Не уверен - я связал лучшее, что я мог видеть, но я не могу вспомнить, какой была статья 7 лет назад;)
noelicus
14

Отличный ответ Ф.Мёрка. Но если вы хотите обновить перевод или добавить новые языки после выпуска приложения, вы застряли, потому что вам всегда нужно перекомпилировать его для создания 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»)

Эрик Боле-Фейсот
источник
2
Спасибо за комментарий о сохранении пространства имен (y), которое, если оно пропущено, не вызовет никаких ошибок, а просто вернется к резервному ресурсу.
Mosca Pt
11

Исправление и проработка ответа @Fredrik Mörk .

  • Добавить strings.resxфайл ресурсов в свой проект (или другое имя файла)
  • Установите Access Modifierв Public(на strings.resxвкладке открытого файла)
  • Добавьте строку resouce в файл 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 здесь .

Андрей Моисеев
источник
1

В моем случае

[assembly: System.Resources.NeutralResourcesLanguage("ru-RU")]

в AssemblyInfo.cs помешали вещам работать как обычно.

Александр
источник
0

В дополнение к @Eric Bole-Feysot :

Благодаря спутниковым сборкам локализация может быть создана на основе файлов .dll / .exe . Сюда:

  • исходный код (проект VS) может быть отделен от языкового проекта,
  • добавление нового языка не требует перекомпиляции проекта,
  • перевод может быть сделан даже конечным пользователем.

Существует малоизвестный инструмент под названием LSACreator (бесплатный для некоммерческого использования или покупки), который позволяет создавать локализацию на основе файлов .dll / .exe. Фактически, внутри (в каталоге языкового проекта) он создает / управляет локализованными версиями файлов resx и компилирует сборку аналогично тому, как описывал @Eric Bole-Feysot .

Томаш Малик
источник
0

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) );
    }
}

¹ (я хранитель этой библиотеки)

Тег
источник
0

Обычно вы помещаете свои переводы в файлы ресурсов, например 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

  • Установите расширение Microsoft MAT для Visual Studio.
  • В обозревателе решений перейдите к своему проекту> Свойства> AssemblyInfo.cs
  • Добавьте в AssemblyInfo.cs ваш нейтральный язык по умолчанию (в моем случае английский): [assembly: System.Resources.NeutralResourcesLanguage("en")]
  • Выберите свой проект в обозревателе решений и в Visual Studio в верхнем меню нажмите «Инструменты»> «Многоязычный инструментарий приложения»> «Включить выбор», чтобы включить MAT для проекта.
    • Теперь щелкните правой кнопкой мыши проект в обозревателе решений, выберите «Многоязычный набор инструментов приложения»> «Добавить языки перевода…» и выберите язык, для которого вы хотите добавить переводы. например, голландский.

Вы увидите, что будет создана новая папка с названием «MultilingualResources», содержащая ....nl.xlfфайл.

Единственное, что вам теперь нужно сделать, это:

  1. добавьте ваш перевод в ваш файл resources.resx по умолчанию (в моем случае английский)
  2. Переведите, щелкнув файл .xlf (НЕ файл .resx), поскольку файлы .xlf будут создавать / обновлять файлы .resx.

(Файлы .xlf должны открываться с помощью «Многоязычного редактора», если это не так, щелкните правой кнопкой мыши файл .xlf, выберите «Открыть с помощью…» и выберите «Многоязычный редактор».

Радоваться, веселиться! теперь вы также можете видеть то, что не было переведено, экспортировать переводы в xlf во внешние переводческие компании, импортировать их снова, перерабатывать переводы из других проектов и т. д ...

Больше информации:

ЮФО
источник