2009-07-17 4 views
230

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

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

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

ответ

491
  • Добавить файл ресурсов в ваш проект (вы можете назвать это «strings.resx»), выполнив следующие действия:
    правой кнопкой мыши Свойства в проекте, выберите Добавить -> Новый элемент ... в контекстном меню, затем в списке Элементы Visual C# выберите «Файл ресурсов» и назовите его strings.resx.
  • Добавить строку Resouce в Resx файл и дать ему хорошее имя (пример: назовите его «Hello» с и дать ему значение «Hello»)
  • Сохранить файл ресурса (примечание: это будет файл ресурс по умолчанию, так как она не имеет код языка из двух букв)
  • Добавить ссылки на вашу программу: System.Threading и System.Globalization

Выполнить этот код:

Console.WriteLine(Properties.strings.Hello); 

Должен напечатать «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 ан“ресурса, поэтому он вернется к значению по умолчанию, который является тот, который мы добавили из start

При необходимости вы можете создавать файлы с более конкретными ресурсами (например, strings.fr-FR.resx и strings.fr-CA.resx для французского во Франции и Канаде соответственно). В каждом таком файле вам понадобятся в добавьте ресурсы для тех строк, которые отличаются от ресурсов, на которые он будет возвращаться. Поэтому, если текст во Франции и Канаде одинаковый, вы можете поместить его в strings.fr.resx, в то время как строки, которые отличаются на канадском французском, могут переходить в strings.fr-CA.resx.

+20

В ответ можно ссылаться на «закулисную» сантехнику, выполняемую Visual Studio здесь: файл resx.designer.cs, что делает работу intellisense; спутниковые сборки, скомпилированные с библиотекой классов, которые необходимо развернуть с помощью сборной сборки и любых последующих проектов, которые ее используют, и т. д. Ответ прост и прост, но это не помогает объяснить, где ситуация может пойти не так, например, если вы не используете Visual Studio. – Tao

+13

+1 сообщение! Вместо того, чтобы делать файлы вручную, попробуйте редактор ресурсов Zeta (http://www.zeta-resource-editor.com/index.html). Это бесплатно и помогает вам делать эти виды переводов МНОГО быстрее, чем просто в VS. – Killnine

+1

Будет ли .net выбрать язык ОС, а затем автоматически установить для вас информацию о культуре? ... или нам нужно установить CurrentUICulture в код для другого языка? – noelicus

35

Это довольно просто, на самом деле. Создайте новый файл ресурсов, например 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 добавьте «Hallo, Welt!». И в Strings.de-AT.resx добавьте «Servus, Welt!». Это до сих пор.

Теперь у вас есть сгенерированный класс Strings, и он имеет свойство с геттером HelloWorld. Приобретение этого свойства будет загружать «Servus, Welt!» когда ваш язык де-AT, «Hallo, Welt!, когда ваш язык - это любой другой язык (включая de-DE и de-CH) и« Hello, World! », когда ваш язык - это что-то еще. Если строка отсутствует в локализованной версии, диспетчер ресурсов автоматически будет перемещаться по цепочке от наиболее специализированного к инвариантному ресурсу.

Вы можете использовать класс ResourceManager, чтобы узнать больше о том, как именно вы загружаете вещи. Сгенерированный класс Strings использует его также.

11

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

+1

Спасибо за комментарий о сохранении пространства имен (y), который - если пропущен - не будет генерировать никаких ошибок, а просто вернется к резервному ресурсу. –

13

Кроме того большой ответ @Fredrik MORK на строки, чтобы добавить локализацию в виде сделать следующее:

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

Этот MSDN article on Localizing Windows Forms дает дополнительную информацию об этом.

0

В дополнении к @Eric Бол-Feysot ответа:

Благодаря спутниковым узлам, локализация может быть создана на основе .dll/EXE-файлах.Таким образом:

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

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

0

В моем случае

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

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

5

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

  • Добавить файл в Strings.resx ресурсов для вашего проекта (или другой файла)
  • Установите Access Modifier в Public (в открытой вкладке Strings.resx файла)
  • Добавить строку Resouce в Resx файла: (пример: имя Hello, значение Hello)
  • Сохранить файл ресурсов

Visual Studio автогенерацию s соответствующий класс Strings, который фактически размещен в Strings.Designer.cs. Класс находится в том же пространстве имен, что можно было бы ожидать вновь созданный .cs файл, который будет помещен в

Этот код всегда печатает Hello, потому что это ресурс по умолчанию, и нет конкретного языка ресурсы не доступны:.

Console.WriteLine(Strings.Hello); 

Теперь добавьте новый язык конкретного ресурса:

  • Добавить Strings.fr.resx (для французского языка)
  • Добавить строку с тем же именем, предварительно viously, но другое значение: (имя Hello, значение Salut)

Следующий код печатает Salut:

Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR"); 
Console.WriteLine(Strings.Hello); 

Какой ресурс используется, зависит от Thread.CurrentThread.CurrentUICulture. Он устанавливается в зависимости от языка интерфейса пользователя Windows или может быть установлен вручную, как в этом примере. Узнать больше об этом here.

Вы можете добавить ресурсы страны, такие как Strings.fr-FR.resx или Strings.fr-CA.resx.

Строка для использования определяется в этом порядке приоритета:

  • От ресурса конкретной страны, как Strings.fr-CA.resx
  • От конкретного языка ресурса как Strings.fr.resx
  • От умолчанию Strings.resx

Обратите внимание, что ресурсы, специфичные для языка, генерируют satellite assemblies.

Также узнайте, как CurrentCulture отличается от CurrentUICulturehere.