none
Multi-Language in C#.net RRS feed

  • Allgemeine Diskussion

  • Hallo,

    Ich will hier gerne mal eine Diskussion starten um in diesem Thema wieder auf neue (und vielleicht/wahrscheinlich) bessere Ideen zu kommen.

    Also es geht um Programme, die über eine Sprachumschaltung verfügen sollen. Das Umschalten der Sprache habe ich schon realisiert (ein Propertie welches die Sprachauswahl auch nach Beenden des Programms behält und beim umschalten der Sprache (durch ComboBox) wird das Propertie überschrieben und eine Reihe von Methoden zur Neubelegung sämtlicher Labels aufgerufen)

    Interessanter wird es bei der Verwaltung der Sprachdateien. Hier habe ich mir folgendes Schema überlegt:

    Ich habe eine .csv-Datei welche mir alle Übersetzungstexte bereithält. In der erster Spalte steht dabei immer der key und in allen weiteren Spalten die Texte der verschiedenen Sprachen.

    key;Deutsch;English
    sometext;Irgendein Text;some text
    ...

    Damit habe ich immer alle Texte beisammen und kann bequem neue Sprachen einfügen und weiß dann auch gleich welche Texte ich für die neue Sprache brauche.

    Nun kommt allerdings der Teil, welcher mir nicht so gefällt. In meinem Programm möchte ich möglichst einfach auf diese Texte zugreifen. Daher rufe ich die Methode, die mir den Übersetzungstext der aktuellen Sprache liefert immer so auf:

    Language.GetText("sometext");

    In dieser Methode wird dann nach dem Text "sometext" in der .csv-Datei gesucht und der Übersetzungstext der momentanen Sprache zurückgegeben.

    Um allerdings jetzt Tippfehler zu vermeiden -> Language.GetText("soemtext"); habe ich mir folgendes gebaut.

    public static class LanguageCode
    {
    public static string sometext = "sometext";
    }

    Nun habe ich das Risiko eines Tippfehlers nur noch in dieser Klasse und ich kann mir Übersetzungstexte so holen:

    Language.GetText(LanguageCodes.sometext);

    Was mich nun an dieser Geschichte stört, sollte eindeutig sein. Nämlich diese Klasse LanguageCode, in der eine Variable immer ihren eigenen Namen als Wert bekommt. Und die Klasse wird auf Dauer auch sehr sehr lang.

    Hat hierfür jemand eine Idee, wie ich das umgehen kann, aber trotzdem vor Tippfehlern sicher bin?

    Grüße drossmann

    Montag, 4. März 2013 10:22

Alle Antworten

  • Hallo drossmann,

    ein Artikel betreffend der Unterstützung von mehreren Sprachen können Sie unter [1] finden. Dort erklärt man die wichtigsten Punkte, die man bei der Internationalisierung einer Anwendung beachten muss. Unter C# implementiert man solche Funktionalität durch die sogenannte Cultures. Mehr darüber können Sie unter [2] erfahren. Einen Blogeintrag für Anfänger mit Erklärung wie man Cultures verwendet können Sie unter [3] finden. Einen Foreneintrag in dem man dieses ausführlicher erklärt, steht für Sie unter [4] zur Verfügung. Zusätzlich können Sie sich auch Beispielcode von einer implementierten Internationalisierung unter [5] herunterladen.

    [1] http://www.c-sharpcorner.com/UploadFile/sribharadwaj/Internationalization03082006085742AM/Internationalization.aspx
    [2] http://msdn.microsoft.com/de-de/library/system.globalization.cultureinfo.aspx  
    [2] http://www.jimmycollins.org/blog/?p=204  
    [3] http://stackoverflow.com/questions/1142802/how-to-use-localization-in-c-sharp  
    [4] http://code.msdn.microsoft.com/windowsapps/Application-resources-and-cd0c6eaa/view/SourceCode

    Wir hoffen, vielen Besuchern der MSDN Foren durch das Posten dieses Problems und einer möglichen Lösung weiterhelfen zu können.

    Viele Grüße,
    Hristo Valev
    App-Entwickler-Hotline für MSDN Online Deutschland

    Disclaimer:
    Bitte haben Sie Verständnis dafür, dass wir hier auf Rückfragen gar nicht oder nur sehr zeitverzögert antworten können.
    Bitte nutzen Sie für Rückfragen oder neue Fragen den telefonischen Weg über die MSDN Hotline: http://www.msdn-online.de/Hotline
    MSDN Hotline: Schnelle & kompetente Hilfe für Entwickler: kostenfrei!

    Es gelten für die MSDN Hotline und dieses Posting diese Nutzungsbedingungen, Hinweise zu MarkenzeichenInformationen zur Datensicherheit sowie die gesonderten Nutzungsbedingungen für die MSDN Hotline.

    Mittwoch, 6. März 2013 13:57
  • Hallo,

    von Hristo hast du ja schon einiges bekommen. Ich würde dir empfehlen die ganz normalen Mechanismen von der jeweiligen Projektvorlage zu verwenden. In WinForms und Apps ist das recht einfach gestaltet, in WPF eigentlich auch, nur halt "etwas anders". Die Übersetzungen liegen alle in besonderen, speziel dafür ausgelegten Dateien.
    Alle diese Systeme basieren aber auf die Abfrage über einen String. Sich dort zu vertppen ist natürlich groß, aber eine Klasse zu schreiben ud sich dort zu vertippen letzten endes fast genauso groß und aufwendiger. Wenn du dir beim testen jeden Text aufmerksam durchliest, dann bekommst du auch Fehler mit und die Codestelle ist meistens schnell gefunden ;)

    Wenn du nicht mit RESX-Dateien o.ä. arbeiten willst, dann würde ich die Datei vorher komplett einlesen und im Arbeitsspeicher behalten, somit sparst du dir aufwendige Dateizugriffe. Wenn du speziell CSV-Dateien nimmst, dann würde ich ein Dictionary<TKey,TValue> empfehlen. Aber ich würde die normalen Mechanismen verwenden.

    Die Klasse solltest du dir komplett sparren, da sie wie gesagt nur Arbeit macht und ein Fehler ggf. schnell gefunden ist.


    Koopakiller [kuːpakɪllɐ] | Webseite | Code Beispiele | Facebook | Snippets

    Mittwoch, 6. März 2013 14:07
    Moderator
  • Hallo

    zunächst einmal Danke, für die zahlreichen Links. Allerdings kann ich die Resource-Dateien nicht verwenden.

    Zum einen finde ich sie persönlich zu unhandlich. Zum Beispiel muss ich jeden String in jeder Resourcen-Datei seperat anlegen und dabei kann auch schnell der Überblick verloren gehen und dann muss man mühsam die Resourcen wieder auf ein und den selben Stand bringen.

    Zum anderen soll meine Sprach-Datei so einfach gestaltet sein, dass ich sie auch an nicht IT-ler geben kann, die dann mit dem Datei-Format kein Problem haben und mir die enzelnen Texte übersetzen können.

    Daher habe ich mich für die csv-Struktur entschieden. Hier habe ich dann auch für jeden String eine eigene Zeile und habe damit sofort alle Sprachen abgedeckt und ich gebe dabei nur einmal mein Key an.

    Wenn also so etwas wie in Ihrem Link Nr. 4 beschrieben, auch mit einer Resourcen-Datei, die einfacher zu handhaben ist, möglich wäre, dann suche ich genau so etwas. Gibt es denn Resourcen-Dateien in denen mehrere Strings einem Key zugeordnet sind?

    @Koopakiller: Ja, ich lese zu Beginn alle Strings ein und verwalte diese in einem Dictionary.

    Grüße drossmann

    Mittwoch, 6. März 2013 16:20
  • Hallo,

    Ressourcen Dateien gelten jeweils für eine Sprache. Womit beliebig viele Kulturen möglich sind - nebeneinander würde das sehr schnell unübersichtlich. Der ResourceManager sucht entsprechend der Kultur nach den Dateien und lädt sie in eine Hashtable.

    Wenn Dir das XML Format nicht liegt, so kannst Du die Ressourcen auch über ein Programm erzeugen, siehe ResourceWriter Klasse.

    Was das "Stören" angeht: Für Konstanten im Programm wäre das der normale Weg und das können schon einige Zeichenketten werden (auch im .NET Framework gibt es solche Hilfsklassen).

    Bei Steuerelementen kann man die Informationen direkt ablegen - in der Text oder auch Tag-Eigenschaft - und diese mit Präfixen kenntlich machen, z. B. $Label1Text oder %Dies ist der Text für Label 1% (Variationen gibt es da viele).

    Anstatt Nicht-IT'ler an den (CSV) Dateien basteln zu lassen und sich mit auftretenden Fehlern herumschlagen zu müssen wäre es dann sinnvoll, ein Programm dafür zu erstellen, was notwendige Prüfungen vornimmt. Und im Falle von Steuerelementen die notwendige Extraktion vornehmen könnte - zum Vergleich WPF LocBaml.

    Mehr siehe Codierung und Lokalisierung - merke: es sind nicht nur Zeichenketten ;)

    Gruß Elmar

    Donnerstag, 7. März 2013 11:53
    Beantworter