Як використовувати локалізацію в C #


268

Я просто не можу зробити локалізацію для роботи.

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

Як я можу це зробити?


PS: переконайтесь, що ви встановили безкоштовне розширення Microsoft MAT (Multilingual App Toolkit) для візуальної студії ;-)
juFo

Відповіді:


571
  • Додайте файл ресурсу до свого проекту (можна назвати його "strings.resx"), виконавши наступне:
    Клацніть правою кнопкою миші Властивості в проекті, виберіть Додати -> Новий елемент ... у контекстному меню, а потім у списку Візуальні елементи C # виберіть "Файл ресурсів" та назвіть його strings.resx.
  • Додайте рядовий ресурс у файл 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 ", який він знайде (і використовує).

Наступний код надрукує "Привіт":

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, що робить інтелігенційну роботу; супутникові збірки, зібрані з бібліотекою класів, які потрібно розгорнути за допомогою складеної збірки та будь-яких пізніших проектів, які використовують її, тощо. Відповідь є приємною та простою, але це не допомагає пояснити, де все може піти не так, наприклад, якщо ви не використовуєте Visual Studio.
Дао

13
+1 публікація! Замість створення файлів вручну спробуйте редактор ресурсів Zeta ( zeta-resource-editor.com/index.html ). Це безкоштовно і допомагає робити такі види перекладів МНОГО швидше, ніж просто у VS.
Killnine

4
Access Modifierслід встановити Publicдля класу ресурсів, який потрібно створити. Клас не обов'язково знаходиться в просторі імен властивостей, саме там ви розміщуєте файл .resx.
Андрій Мойсеєв

3
Майте на увазі, що у VS 2017 resx з локалізацією у формі win не працює через помилку (принаймні до версії 15.4). Квиток доступний: developercommunity.visualstudio.com/content/problem/63772/…
muccix

4
Станом на .NET 4.5 також можна використовувати System.Globalization.CultureInfo.DefaultThreadCurrentCulture замість Thread.CurrentThread.CurrentUICulture, щоб ви змінили локаль для всієї програми замість
теми

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додайте "Привіт, Вельте!". І в Strings.de-AT.resxдодайте "Сервус, Велт!". Ось це поки що.

Тепер у вас є цей згенерований Stringsклас, і він має властивість із getterHelloWorld . Отримавши цю властивість, ви завантажите "Servus, Welt!" коли у вашому мові de-AT, "Здравствуйте, Welt! коли ваш локаль - це будь-який інший локальний статус (включаючи de-DE та de-CH), і" Hello, World! ", коли ваш локал є чимось іншим. Якщо рядок є відсутній у локалізованій версії, менеджер ресурсів автоматично піде вгору по ланцюгу, від найбільш спеціалізованого до інваріантного ресурсу.

Ви можете використовувати ResourceManagerклас для більшого контролю над тим, як саме ви завантажуєте речі. Створений Stringsклас також використовує його.


як встановити локаль?
Матей Саймон

1
@MatheusSimon: Вам цього не потрібно. За замовчуванням використовується поточний локальний пункт користувача. Якщо ви хочете примусити певний локал (наприклад, дозволити користувачам змінювати мову вручну), вам слід встановити System.Threading.Thread.CurrentCulture та CurrentUICulture в кожному потоці , ймовірно, перед тим, як будь-які ресурси завантажуються вперше. Простіше перезапустити програму для цього, а не оновлювати під час виконання.
OregonGhost

15

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

  • Встановіть в формі властивості «сек "Localizable"дляtrue
  • Змініть Languageвластивість форми на потрібну вам мову (з приємного спадного меню, у якому все це)
  • Перекладіть елементи керування в цю форму і перемістіть їх, якщо потрібно (розкачайте ці дійсно довгі повні французькі речення!)

Редагувати: Ця стаття MSDN про локалізацію форм Windows не є оригінальною, з якою я пов’язана ..., але може пролити більше світла при необхідності. (старого забрали)


Стаття msdn вже недоступна, будь-яка заміна?
fuomag9

Не впевнений - я пов’язав найкраще, що міг бачити, але не можу згадати, якою була стаття 7 років тому;)
noelicus

14

Чудова відповідь Ф.Морка. Але якщо ви хочете оновити переклад або додати нові мови після виходу програми, ви застрягли, тому що вам завжди доведеться перекомпілювати його, щоб створити ресурси.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вкладці файлу)
  • Додайте рядовий ресурс у файл 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

Як правило, ви перекладаєте свої файли у файли ресурсів, наприклад ресурси.resx.

Кожна конкретна культура має іншу назву, наприклад ресурси.nl.resx, resource.fr.resx, resources.de.resx,…

Тепер найважливішою частиною рішення є підтримка ваших перекладів. У Visual Studio встановіть інструмент Microsoft MAT: Багатомовний інструментарій додатків (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. додати переклад у файл за замовчуванням ресурс.resx (у моєму випадку англійською)
  2. Перекладіть, натиснувши .xlf-файл (НЕ файл .resx), оскільки .xlf-файли генерують / оновлять .resx-файли.

(файли .xlf повинні відкриватися за допомогою "Багатомовного редактора", якщо це не так, клацніть правою кнопкою миші на файл .xlf, виберіть "Відкрити за допомогою ..." та виберіть "Багатомовний редактор".

Весело! тепер ви також можете побачити те, що не було перекладено, експортуйте переклади у форматі xlf до зовнішніх перекладацьких компаній, знову імпортуйте їх, переробляйте переклади з інших проектів тощо ...

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.