Verwendung der Lokalisierung in C #

268

Ich kann die Lokalisierung einfach nicht zum Laufen bringen.

Ich habe eine Klassenbibliothek. Jetzt möchte ich dort Resx- Dateien erstellen und einige Werte basierend auf der Thread-Kultur zurückgeben.

Wie kann ich das machen?

J L.
quelle
PS: Stellen Sie sicher, dass Sie die kostenlose Microsoft MAT-Erweiterung (Multilingual App Toolkit) für Visual Studio installiert haben
;-)

Antworten:

571
  • Fügen Sie Ihrem Projekt eine Ressourcendatei hinzu (Sie können sie als "strings.resx" bezeichnen), indem Sie wie folgt vorgehen:
    Klicken Sie im Projekt mit der rechten Maustaste auf Eigenschaften , wählen Sie im Kontextmenü Hinzufügen -> Neues Element ... und dann in der Liste von Visual C # -Elemente wählen "Ressourcendatei" und benennen sie strings.resx.
  • Fügen Sie der resx-Datei eine Zeichenfolgenressource hinzu und geben Sie ihr einen guten Namen (Beispiel: Benennen Sie sie mit "Hallo" und geben Sie ihr den Wert "Hallo").
  • Speichern Sie die Ressourcendatei ( Hinweis: Dies ist die Standardressourcendatei , da sie keinen aus zwei Buchstaben bestehenden Sprachcode enthält.)
  • Fügen Sie Ihrem Programm Verweise hinzu: System.ThreadingundSystem.Globalization

Führen Sie diesen Code aus:

Console.WriteLine(Properties.strings.Hello);

Es sollte "Hallo" drucken.

Fügen Sie nun eine neue Ressourcendatei mit dem Namen "strings.fr.resx" hinzu (beachten Sie den Teil "fr"; dieser enthält Ressourcen in französischer Sprache). Fügen Sie eine Zeichenfolgenressource mit demselben Namen wie in strings.resx hinzu, jedoch mit dem Wert in Französisch (Name = "Hallo", Wert = "Salut"). Wenn Sie nun den folgenden Code ausführen, sollte Salut gedruckt werden:

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

Was passiert ist, dass das System nach einer Ressource für "fr-FR" sucht. Es wird keine gefunden (da wir "fr" in Ihrer Datei angegeben haben "). Es wird dann auf die Suche nach" fr "zurückgegriffen, die es findet (und verwendet).

Der folgende Code gibt "Hallo" aus:

Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
Console.WriteLine(Properties.strings.Hello);

Dies liegt daran, dass keine "en-US" -Ressource und auch keine "en" -Ressource gefunden wird, sodass auf die Standardeinstellung zurückgegriffen wird, die wir von Anfang an hinzugefügt haben.

Bei Bedarf können Sie Dateien mit spezifischeren Ressourcen erstellen (z. B. strings.fr-FR.resx und strings.fr-CA.resx für Französisch in Frankreich bzw. Kanada). In jeder dieser Dateien müssen Sie die Ressourcen für die Zeichenfolgen hinzufügen, die sich von der Ressource unterscheiden, auf die zurückgegriffen werden würde. Wenn ein Text in Frankreich und Kanada identisch ist, können Sie ihn in strings.fr.resx einfügen, während Zeichenfolgen, die sich in kanadischem Französisch unterscheiden, in strings.fr-CA.resx eingefügt werden können.

Fredrik Mörk
quelle
24
Die Antwort könnte sich auf die Installation hinter den Kulissen beziehen, die von Visual Studio hier ausgeführt wird: resx.designer.cs-Datei, damit die Intellisense funktioniert; Satellitenassemblys, die mit der Klassenbibliothek kompiliert wurden und mit der kompilierten Assembly und späteren Projekten, die sie verwenden, bereitgestellt werden müssen usw. Die Antwort ist nett und einfach, aber es hilft nicht zu erklären, wo etwas schief gehen könnte, z. B. wenn Sie verwenden Visual Studio nicht.
Tao
13
+1 Beitrag! Versuchen Sie es mit Zeta Resource Editor ( zeta-resource-editor.com/index.html ), anstatt Dateien manuell zu erstellen . Es ist kostenlos und hilft Ihnen, diese Art von Übersetzungen VIEL schneller als nur in VS zu machen.
Killnine
4
Access Modifiersollte Publicfür die zu generierende Ressourcenklasse festgelegt werden. Die Klasse befindet sich nicht unbedingt im Eigenschaften-Namespace. Hier platzieren Sie die .resx-Datei.
Andrey Moiseev
3
Beachten Sie, dass in VS 2017 resx mit Lokalisierung in Winform aufgrund eines Fehlers nicht funktioniert (zumindest bis Version 15.4). Ein Ticket ist erhältlich: Developercommunity.visualstudio.com/content/problem/63772/…
Muccix
4
Ab .NET 4.5 ist es auch möglich, System.Globalization.CultureInfo.DefaultThreadCurrentCulture anstelle von Thread.CurrentThread.CurrentUICulture zu verwenden, sodass Sie das Gebietsschema für die gesamte Anwendung anstelle von Thread für Thread
ändern
41

Eigentlich ist es ganz einfach. Erstellen Sie beispielsweise eine neue Ressourcendatei Strings.resx. Set Access Modifierzu Public. Verwenden Sie die entsprechende Dateivorlage, damit Visual Studio automatisch eine Accessor-Klasse generiert ( Stringsin diesem Fall lautet der Name ). Dies ist Ihre Standardsprache.

Wenn Sie beispielsweise die deutsche Lokalisierung hinzufügen möchten, fügen Sie eine lokalisierte Resx-Datei hinzu. Dies ist normalerweise Strings.de.resxin diesem Fall der Fall. Wenn Sie beispielsweise für Österreich eine zusätzliche Lokalisierung hinzufügen möchten, erstellen Sie zusätzlich eine Strings.de-AT.resx.

Erstellen Sie nun eine Zeichenfolge - sagen wir eine Zeichenfolge mit dem Namen HelloWorld. Fügen Sie in Ihrem Strings.resxdiesen String mit dem Wert "Hallo Welt!" Hinzu. In Strings.de.resx, fügen Sie "Hallo, Welt!". Und Strings.de-AT.resxfügen Sie "Servus, Welt!" Hinzu. Das war's soweit.

Jetzt haben Sie diese generierte StringsKlasse und sie hat eine Eigenschaft mit einem Getter HelloWorld. Wenn Sie diese Eigenschaft erhalten, wird "Servus, Welt!" Wenn Ihr Gebietsschema de-AT ist, "Hallo Welt! Wenn Ihr Gebietsschema ein anderes Gebietsschema ist (einschließlich de-DE und de-CH), und" Hallo Welt! ", wenn Ihr Gebietsschema etwas anderes ist. Wenn eine Zeichenfolge ist In der lokalisierten Version fehlt der Ressourcenmanager automatisch die Kette, von der spezialisiertesten zur invarianten Ressource.

Sie können die ResourceManagerKlasse verwenden, um mehr Kontrolle darüber zu erhalten, wie genau Sie Dinge laden. Die generierte StringsKlasse verwendet es ebenfalls.

OregonGhost
quelle
Wie stelle ich das Gebietsschema ein?
Matheus Simon
1
@ MatheusSimon: Das musst du nicht. Standardmäßig wird das aktuelle Gebietsschema des Benutzers verwendet. Wenn Sie ein bestimmtes Gebietsschema erzwingen möchten (z. B. um Benutzern das manuelle Ändern der Sprache zu ermöglichen), müssen Sie System.Threading.Thread.CurrentCulture und CurrentUICulture in jedem Thread festlegen , wahrscheinlich bevor Ressourcen zum ersten Mal geladen werden. Es ist einfacher, eine Anwendung dafür neu zu starten, als zur Laufzeit zu aktualisieren.
OregonGhost
15

Um die Lokalisierung zu einem Formular hinzuzufügen , gehen Sie wie folgt vor: @Fredrik Mörks großartige Antwort auf Zeichenfolgen :

  • Setzen Sie die Eigenschaft des Formulars"Localizable" auftrue
  • Ändern Sie die LanguageEigenschaft des Formulars in die gewünschte Sprache (aus einem netten Dropdown-Menü mit allen in).
  • Übersetzen Sie die Steuerelemente in diese Form und verschieben Sie sie bei Bedarf (quetschen Sie die wirklich langen französischen Sätze ein!).

Bearbeiten: Dieser MSDN-Artikel zum Lokalisieren von Windows Forms ist nicht der ursprüngliche, den ich verlinkt habe ... kann aber bei Bedarf mehr Licht ins Dunkel bringen. (der alte wurde weggenommen)

Noelicus
quelle
Der msdn Artikel ist nicht mehr verfügbar, irgendein Ersatz?
fuomag9
Ich bin mir nicht sicher - ich habe den besten verlinkt, den ich sehen konnte, aber ich kann mich nicht erinnern, wie der Artikel vor 7 Jahren war;)
noelicus
14

Tolle Antwort von F.Mörk. Wenn Sie jedoch die Übersetzung aktualisieren oder neue Sprachen hinzufügen möchten, sobald die Anwendung veröffentlicht wurde, stecken Sie fest, da Sie sie immer neu kompilieren müssen, um die resources.dll zu generieren.

Hier ist eine Lösung zum manuellen Kompilieren einer Ressourcen-DLL. Es verwendet die Tools resgen.exe und al.exe (mit dem SDK installiert).

Angenommen, Sie haben eine Strings.fr.resx-Ressourcendatei. Sie können eine Ressourcen-DLL mit dem folgenden Stapel kompilieren:

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

Achten Sie darauf, den ursprünglichen Namespace in den Dateinamen beizubehalten (hier "WpfRibbonApplication1").

Eric Bole-Feysot
quelle
2
Vielen Dank für den Kommentar zum Beibehalten des Namespace (y), der - wenn er übersehen wird - keine Fehler erzeugt, sondern einfach zur Fallback-Ressource zurückkehrt.
Mosca Pt
11

Eine Korrektur und Ausarbeitung der Antwort von @Fredrik Mörk .

  • Fügen Sie strings.resxIhrem Projekt eine Ressourcendatei hinzu (oder einen anderen Dateinamen).
  • Stellen Sie Access Modifierauf Public(in der geöffneten strings.resxDatei tab)
  • Fügen Sie der resx-Datei eine Zeichenfolgenressource hinzu: (Beispiel: Name Hello, Wert Hello)
  • Speichern Sie die Ressourcendatei

Visual Studio generiert automatisch eine entsprechende stringsKlasse, in die tatsächlich eingefügt wird strings.Designer.cs. Die Klasse befindet sich im selben Namespace, in dem eine neu erstellte .csDatei abgelegt werden soll.

Dieser Code wird immer gedruckt Hello, da dies die Standardressource ist und keine sprachspezifischen Ressourcen verfügbar sind:

Console.WriteLine(strings.Hello);

Fügen Sie nun eine neue sprachspezifische Ressource hinzu:

  • Hinzufügen strings.fr.resx(für Französisch)
  • Fügen Sie eine Zeichenfolge mit demselben Namen wie zuvor, aber unterschiedlichem Wert hinzu: (Name Hello, Wert Salut)

Der folgende Code wird gedruckt Salut:

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

Welche Ressource verwendet wird, hängt davon ab Thread.CurrentThread.CurrentUICulture. Sie wird abhängig von der Spracheinstellung der Windows-Benutzeroberfläche festgelegt oder kann wie in diesem Beispiel manuell festgelegt werden. Mehr dazu hier .

Sie können länderspezifische Ressourcen wie strings.fr-FR.resxoder hinzufügen strings.fr-CA.resx.

Die zu verwendende Zeichenfolge wird in dieser Prioritätsreihenfolge festgelegt:

  • Aus länderspezifischen Ressourcen wie strings.fr-CA.resx
  • Aus sprachspezifischen Ressourcen wie strings.fr.resx
  • Standardmäßig strings.resx

Beachten Sie, dass sprachspezifische Ressourcen Satellitenassemblys generieren .

Erfahren Sie auch, wie CurrentCulturesich von CurrentUICulture hier unterscheidet .

Andrey Moiseev
quelle
1

In meinem Fall

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

in der AssemblyInfo.cs verhinderte, dass die Dinge wie gewohnt funktionierten.

Aleksandr
quelle
0

Zusätzlich zu @Eric Bole-Feysot Antwort:

Dank Satelliten-Assemblys kann die Lokalisierung basierend auf DLL- / EXE- Dateien erstellt werden. Diesen Weg:

  • Quellcode (VS-Projekt) könnte vom Sprachprojekt getrennt werden,
  • Das Hinzufügen einer neuen Sprache erfordert kein erneutes Kompilieren des Projekts.
  • Die Übersetzung kann sogar vom Endbenutzer vorgenommen werden.

Es gibt ein wenig bekanntes Tool namens LSACreator (kostenlos für nichtkommerzielle Zwecke oder Kaufoptionen), mit dem Sie eine Lokalisierung basierend auf DLL- / EXE-Dateien erstellen können. Intern (im Verzeichnis des Sprachprojekts) werden lokalisierte Versionen von Resx-Dateien erstellt / verwaltet und eine Assembly auf ähnliche Weise wie bei @Eric Bole-Feysot beschrieben kompiliert .

Tomasz Malik
quelle
0

ResourceManager und .resx sind etwas chaotisch.

Sie können Lexical.Localization ¹ verwenden, mit dem Standardwerte und kulturspezifische Werte in den Code eingebettet und in externe Lokalisierungsdateien für weitere Kulturen (wie .json oder .resx) erweitert werden können.

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

¹ (Ich bin Betreuer dieser Bibliothek)

Etikett
quelle
0

Im Allgemeinen legen Sie Ihre Übersetzungen in Ressourcendateien ab, z. B. resources.resx.

Jede spezifische Kultur hat einen anderen Namen, z. B. resources.nl.resx, resources.fr.resx, resources.de.resx,…

Der wichtigste Teil einer Lösung besteht nun darin, Ihre Übersetzungen zu pflegen. Installieren Sie in Visual Studio das Microsoft MAT-Tool: Multilingual App Toolkit (MAT). Funktioniert mit winforms, wpf, asp.net (core), uwp,…

Im Allgemeinen, z. B. für eine WPF-Lösung, im WPF-Projekt

  • Installieren Sie die Microsoft MAT-Erweiterung für Visual Studio.
  • Navigieren Sie im Projektmappen-Explorer zu Projekt> Eigenschaften> AssemblyInfo.cs
  • Fügen Sie in AssemblyInfo.cs Ihre neutrale Standardsprache hinzu (in meinem Fall Englisch): [assembly: System.Resources.NeutralResourcesLanguage("en")]
  • Wählen Sie Ihr Projekt im Projektmappen-Explorer und in Visual Studio aus und klicken Sie im oberen Menü auf "Extras"> "Mehrsprachiges App-Toolkit"> "Auswahl aktivieren", um MAT für das Projekt zu aktivieren.
    • Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, wählen Sie "Multilingual App Toolkit"> "Übersetzungssprachen hinzufügen ..." und wählen Sie die Sprache aus, für die Sie Übersetzungen hinzufügen möchten. zB Niederländisch.

Sie werden sehen, dass ein neuer Ordner mit dem Namen "MultilingualResources" erstellt wird, der eine ....nl.xlfDatei enthält.

Jetzt müssen Sie nur noch Folgendes tun:

  1. Fügen Sie Ihre Übersetzung zu Ihrer Standarddatei resources.resx hinzu (in meinem Fall Englisch).
  2. Übersetzen Sie, indem Sie auf die XLF-Datei (NICHT auf die RESX-Datei) klicken, da die XLF-Dateien die RESX-Dateien generieren / aktualisieren.

(Die XLF-Dateien sollten mit dem "Mehrsprachigen Editor" geöffnet werden. Wenn dies nicht der Fall ist, klicken Sie mit der rechten Maustaste auf die XLF-Datei, wählen Sie "Öffnen mit ..." und wählen Sie "Mehrsprachiger Editor".

Habe Spaß! Jetzt können Sie auch sehen, was nicht übersetzt wurde, Übersetzungen in xlf an externe Übersetzungsunternehmen exportieren, erneut importieren, Übersetzungen aus anderen Projekten recyceln usw.

Mehr Info:

juFo
quelle