MahApps.Metro in Verbindung mit der PRISM-Bibliothek (Teil 6: Lokalisierung)

Jede moderne Anwendung wird heute in mehreren Sprachen (multilingual) ausgeliefert. In diesem Beitrag wird beschrieben wie man bei der Lokalisierung einer Anwendung vorgehen kann und welche nützlichen Tools es gibt, die einen bei der Implementierung unterstützen können. In meinen bisherigen Projekten habe ich die folgenden Erweiterungen verwendet:

  • WPFLocalizationExtension – Erweiterung um WPF-Anwendungen direkt im XAML-Code zu lokalisieren
  • ResXManager – VisualStudio-Erweiterung zu Verwaltung bzw. Pflege der Ressourcendateien (*.resx)

Der Artikel beschreibt nun die Verwendung und den Einsatz dieser Komponenten in der Beispielanwendung.

Installation der WPFLocalizationExtension

Im ersten Schritt installieren wird die WPFLocalizationExtension installiert. Dies kann einfach über den NuGet-Paketmanager (https://www.nuget.org/packages/WpfLocalizeExtension ) erledigt werden:

PrismMahAppsSample_22

Anlegen der Ressourcendateien

Die WPFLocalizationExtension unterstützt resx-Dateien für die Ablage der der lokalisierten Werte. Diese Dateien können einfach über die VisualStudio angelegt werden, müssen aber einem bestimmten Namensschema entsprechen. Dieses Namensschema sieht wie folgt aus: Name.CultureCode.resx

PrismMahAppsSample_23

Nachdem die entsprechenden Ressourcendateien (im Beispiel für Deutsch und Englisch) angelegt wurden müssen diese in den Properties-Ordner verschoben werden. Innerhalb des Solution-Explorers sieht das dann wie folgt aus:

PrismMahAppsSample_24

Im Screenshot sind jetzt insgesamt drei Ressourcendateien zu sehen:

  • Resources.resx – sprachneutral (gehört standardmäßig zu jedem Projekt)
  • Resources.de-DE.resx – Ressourcendatei für die deutsche Lokalisierung
  • Resources.en-US.resx – Ressourcendatei für die englische Lokalisierung

Jetzt muss der XAML-Code für die Verwendung der lokalisierten Werte vorbereitet werden. Dafür werden zunächst die entsprechenden Namespaces eingefügt:

Wie im Beispiel zu sehen muss man folgendes angeben:

  • DesignCulture – die Sprache, die im Designer angezeigt werden soll
  • DefaultAssembly – die Assembly, in welcher die resx-Dateien abgelegt sind, z.B. PrismMahAppsSample.Shell
  • DefaultDictionary – der Name der resx-Dateien (ohne das Language-Flag). In diesem Beispiel also Resources

Um auf die lokalisierten Werte innerhalb des XAML-Codes zugreifen zu können reicht jetzt die folgende Anweisung (wobei Test für den Key des lokalisierten Textes steht):

Damit wäre man mit der Lokalisierung auch schon fertig.

ResXManager

Wie schon geschrieben werden die lokalisierten Texte in den resx-Dateien abgelegt. Im Normalfall muss jetzt über VisualStudio jede resx-Datei einzeln gepflegt werden oder man installiert sich die VisualStudio-Erweiterung ResXManager. Mit dieser Erweiterung ist es möglich alle resx-Dateien innerhalb eines Projekts in einem übersichtlichen Grid zu editieren (das ist echt komfortabel und nimmt einem jede Menge Arbeit ab). Man sieht z.B. auch auf einen Blick alle nicht lokalisierten Strings und kann das Grid sogar in eine Excel-Datei exportieren (um die Lokalisierungen außerhalb von VisualStudio editieren zu können).

PrismMahAppsSample_25

ILocalizerService

Jetzt kann es ja auch vorkommen, dass man den Texte nicht nur direkt im XAML-Code lokalisieren möchte sondern auch im entsprechenden ViewModel. Das kommt immer dann vor wenn man z.B. dynamische Meldungen in MessageBoxen oder der StatusBar ausgeben möchte. Dafür kann man sich einen einfachen Lokalisierungsservice erstellen und diesen im DI-Container registrieren. Zunächst habe ich dafür mal ein Interface definiert, das wie folgt aussieht:

Dieses Interface definiert die folgenden Methoden und Eigenschaften:

  • SetLocale – Methode zum Setzen der Sprache (auch währende der Laufzeit des Programms)
  • GetLocalizedString – Methode zum Lesen eines lokalisierten Strings auf Basis eines gegebenen Keys aus den resx-Dateien
  • SupportedLanguages – Liste mit den unterstützten Sprachen

Die Implementierung des Service ist im Beispiel wie folgt umgesetzt:

Jetzt muss der Service nur noch registriert werden:

Somit steht der Service applikationsweit zu Verfügung und kann innerhalb der ViewModels genutzt werden. Die Aufrufen sehen dann wie folgt aus:

Ich denke hiermit hat man für WPF-Anwendungen eine flexible Lösung um sowohl innerhalb des XAML-Codes als auch in den entsprechenden ViewModels auf lokalisierte Texte zugreifen zu können.

Github-Repository

Der aktuellste Quellcode (inkl. dem LocalizerService) ist in folgendem Github-Repository verfügbar: https://github.com/steve600/PrismMahAppsSample

Fork me on GitHub