it-swarm.com.de

So verwenden Sie die Lokalisierung in C #

Ich kann die Lokalisierung einfach nicht zum Laufen bringen. 

Ich habe eine Klassenbibliothek. Jetzt möchte ichresx-Dateien darin erstellen und einige Werte zurückgeben, die auf der Thread-Kultur basieren. 

Wie kann ich das machen?

245
JL.
  • Fügen Sie Ihrem Projekt eine Ressourcendatei hinzu (Sie können es "strings.resx" nennen), indem Sie folgendermaßen vorgehen: 
    Klicken Sie mit der rechten Maustaste auf Eigenschaften im Projekt, wählen Sie Hinzufügen -> Neuer Eintrag ... im Kontextmenü und dann in der Liste der Visual C # -Elemente pick "Ressourcendatei" und nennen Sie es strings.resx.
  • Fügen Sie der resx-Datei eine Zeichenfolge hinzu und geben Sie einen guten Namen (Beispiel: Nennen Sie "Hello" und geben Sie den Wert "Hello" ein.)
  • Speichern Sie die Ressourcendatei ( Hinweis: Dies ist die Standardeinstellung Ressourcendatei, da sie keinen aus zwei Buchstaben bestehenden Sprachencode hat.)
  • Fügen Sie Ihrem Programm Verweise hinzu: System.Threading und System.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 auf Französisch). Fügen Sie eine String-Ressource mit demselben Namen wie in strings.resx hinzu, jedoch mit dem französischen Wert (Name = "Hello", Value = "Salut"). Wenn Sie jetzt 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 finden (da wir in Ihrer Datei "fr" angegeben haben), und dann auf "fr" zurückgreifen, das es findet (und verwendet).

Der folgende Code wird "Hallo" drucken:

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

Das liegt daran, dass es keine "en-US" -Ressource und auch keine "en" -Ressource findet. Daher wird es auf den Standardwert zurückgesetzt, der von Anfang an hinzugefügt wurde.

Sie können bei Bedarf 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 sie zurückgreifen würde. Wenn also ein Text in Frankreich und Kanada derselbe ist, können Sie ihn in strings.fr.resx einfügen, während in kanadischem Französisch unterschiedliche Strings in strings.fr-CA.resx gehen können.

527
Fredrik Mörk

Es ist eigentlich ganz einfach. Erstellen Sie eine neue Ressourcendatei, zum Beispiel Strings.resx. Setzen Sie Access Modifier auf Public. Verwenden Sie die Vorlage für die autorisierte Datei, damit Visual Studio automatisch eine Accessor-Klasse generiert (in diesem Fall lautet der Name Strings). Dies ist Ihre Standardsprache.

Wenn Sie beispielsweise deutsche Lokalisierung hinzufügen möchten, fügen Sie eine lokalisierte ResX-Datei hinzu. In diesem Fall ist dies normalerweise Strings.de.resx. Wenn Sie beispielsweise eine zusätzliche Lokalisierung für Österreich hinzufügen möchten, erstellen Sie zusätzlich einen Strings.de-AT.resx.

Erstellen Sie nun eine Zeichenfolge - sagen wir eine Zeichenfolge mit dem Namen HelloWorld. Fügen Sie in Ihrem Strings.resx diese Zeichenfolge mit dem Wert "Hallo, Welt!" Hinzu. Fügen Sie in Strings.de.resx "Hallo, Welt!" Hinzu. Fügen Sie in Strings.de-AT.resx "Servus, Welt!" Hinzu. Das ist es soweit.

Nun haben Sie diese generierte Strings-Klasse und eine Eigenschaft mit einem Getter HelloWorld. Wenn Sie diese Eigenschaft erhalten, wird "Servus, Welt!" Geladen. Wenn Ihr Gebietsschema de-AT ist, "Hallo, Welt!", wenn Ihr Gebietsschema irgendein 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 am meisten spezialisierten zur invarianten Ressource.

Sie können die Klasse ResourceManager verwenden, um mehr Kontrolle darüber zu haben, wie genau Sie Dinge laden. Die generierte Strings-Klasse verwendet sie ebenfalls.

36
OregonGhost

Große Antwort von F.Mörk. Wenn Sie jedoch die Übersetzung aktualisieren oder neue Sprachen hinzufügen möchten, nachdem 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" (installiert mit dem SDK).

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

Stellen Sie sicher, dass der ursprüngliche Namespace in den Dateinamen beibehalten wird (hier "WpfRibbonApplication1").

14

Zusätzlich dazu @Fredrik Mörks großartige Antwort auf Zeichenketten, localization zu einem Formular hinzuzufügen, führen Sie Folgendes aus:

  • Setzen Sie das Formular -Eigenschaft "Localizable" auf true.
  • Ändern Sie die Language-Eigenschaft des Formulars in die gewünschte Sprache (aus einem Nice-Dropdown-Menü mit allen Einträgen).
  • Übersetzen Sie die Steuerelemente in diesem Formular und verschieben Sie sie bei Bedarf (zerschlagen Sie die wirklich langen, vollständigen französischen Sätze!).

Dieser MSDN-Artikel zum Lokalisieren von Windows Forms enthält weitere Informationen dazu.

14
noelicus

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

  • Fügen Sie Ihrem Projekt eine Strings.resx-Ressourcendatei (oder einen anderen Dateinamen) hinzu.
  • Setzen Sie Access Modifier auf Public (in der geöffneten Registerkarte Strings.resx-Datei).
  • Fügen Sie der resx-Datei eine Zeichenfolge hinzu: (Beispiel: Name Hello, Wert Hello)
  • Speichern Sie die Ressourcendatei

Visual Studio generiert automatisch eine entsprechende Strings-Klasse, die sich tatsächlich in Strings.Designer.cs befindet. Die Klasse befindet sich in demselben Namespace, in dem Sie eine neu erstellte .cs-Datei erwarten würden.

Dieser Code gibt immer Hello aus, 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:

  • Strings.fr.resx hinzufügen (für Französisch)
  • Fügen Sie eine Zeichenfolge mit demselben Namen wie zuvor hinzu, jedoch mit einem anderen Wert: (Name Hello, Wert Salut)

Der folgende Code druckt Salut:

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

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

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

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

  • Von länderspezifischen Ressourcen wie Strings.fr-CA.resx
  • Von sprachspezifischen Ressourcen wie Strings.fr.resx
  • Vom Standardwert Strings.resx

Beachten Sie, dass sprachspezifische Ressourcen Satellitenassemblies erzeugen.

Erfahren Sie auch, wie sich CurrentCulture von CurrentUICulturehier unterscheidet.

9
Andrey Moiseev

In meinem Fall

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

in der AssemblyInfo.cs verhindert, dass die Dinge wie gewohnt funktionieren.

0
Aleksandr

ResourceManager und .resx sind etwas chaotisch.

Sie können Lexical.Localization verwenden, um Standardwerte und kulturspezifische Werte in den Code einzubetten und in externe Lokalisierungsdateien für weitere Kulturen (wie .json oder .resx) zu erweitern.

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
Tag

Zusätzlich zu @Eric Bole-Feysot Antwort:

Dank Satellitenassemblies kann die Lokalisierung basierend auf .dll/.exe -Dateien erstellt werden. Diesen Weg: 

  • quellcode (VS-Projekt) kann vom Sprachprojekt getrennt werden,
  • durch das Hinzufügen einer neuen Sprache muss das Projekt nicht neu kompiliert werden.
  • Übersetzung könnte sogar vom Endbenutzer gemacht werden.

Es gibt ein wenig bekanntes Werkzeug namens LSACreator (kostenlos für nichtkommerziellen Gebrauch oder Kaufoption), mit dem Sie Lokalisierung basierend auf .dll/.exe-Dateien erstellen können. Tatsächlich erstellt/verwaltet es intern (im Verzeichnis des Sprachenprojekts) lokalisierte Versionen von ResX-Dateien und kompiliert eine Assembly auf ähnliche Weise wie @Eric Bole-Feysot beschrieben.

0
Tomasz Malik