PiotrK PiotrK - 3 months ago 21
C# Question

MVVM light and runtime localization change

What is the correct way to implement feature of runtime localization change in MVVM Light WPF app? I am using Resource based localization (.resx files) and I want to have option of changing locale in almost any moment.

I though at first about doing global property in

App.xaml.cs
with
LocalizationChanged
event wired up in every View, but this violate at least two rules of MVVM: not having code in code-behind and coupling View class together, because they will be depended on App class (it will be harder to unit test them)

Another idea was to create global interface
ILocalizableModel
which will be implemented by
LocalizableModel
class (injected at runtime via mvvm light magic), which then provide interface to register
LocalizationChanged
event and way to set new localization (and maybe some other functionality like enumerate available localizations). The event will fire in ViewModel classes and request them to update all properties. This has another problem: some View data (like lists) cannot be updated without recreating them. And handling strongly View-specific code in ViewModel also seems like a bit twisted idea.

Another idea is to use Observator pattern or auto property wired in Model.

But what is the "correct", MVVM way to do so?

Answer

I spent many weeks researching this and reached the conclusion that a resx file is not the best solution for WPF/MVVM. The best solution I found was to use a custom markup extension which allows you to declare your XAML like this:

<TextBlock Text="{Translate 'Hello World!'}" />

This provides a number of benefits:

  1. You can still write XAML in your native tongue, the original strings form the keys used to index your localization tables.
  2. You can write a simple utility to parse all XAML and extract the key strings into a single table which you can then provide to your translators (plus it's easy to paste into Google Translate while you wait for the proper translations).
  3. You can change the current language on-the-fly and all bindings will update immediately.