November 21, 2024

Writing a multilingual UWP app with Prism and WTS

In this article we are going to design a multilingual application for Universal Windows Platform that is able to change the display language on the fly. This is very useful particularly in kiosk applications, like the ones deployed in the museums. 

We are going to use the Mindgaze.Languages library which has been designed to work both on desktop and web. This library has been started as an included project for the application I created for Piatra Craiului Museum. I think this library can be useful and hence I decided to move it out and publish it on gitlab.

Prerequisites:

  1. Make sure you have a UWP app generated with Windows Template Studio with Prism Framework
  2. Make sure you target the newest version of the SDK as below
  3. Install the Mindgaze.Languages library in your project

Let’s now get to business and see how this app will be created.

Configure the Mindgaze.Languages library

Go to the App.xaml and add the xml namespace definition to the declaration

xmlns:mindgaze="using:Mindgaze.Languages"

Add a resource dictionary if one doesn’t exist already. Add this resource to it:

<mindgaze:MultiLanguageWorkshop x:Name="MultiLanguageWorkshop"></mindgaze:MultiLanguageWorkshop>

Now go to App.xaml.cs and add the following


private MultiLanguageWorkshop languageWorkshop;

private MultiLanguageWorkshop LanguageWorkshop
{
    get
    {
        if (languageWorkshop == null)
        {
            languageWorkshop = (MultiLanguageWorkshop)Resources["MultiLanguageWorkshop"];

            AsyncHelpers.RunSync(async () =>
            {
                await languageWorkshop.LoadLanguages(
                    Path.Combine("Strings", "Strings.json"),
                    Path.Combine("Strings", "Strings.config.json"));
            });
        }

        return languageWorkshop;
    }
}

This will allow us to lazy load the application language resources stored in Strings.json and the configuration in Strings.config.json

Now register the MultiLanguageWorkshop in Prism dependency injection system:


Container.RegisterInstance(LanguageWorkshop);

Create a new ViewModel class which will be used as a base class for all views which require multilanguage:


public class ViewModelBaseWithLang : ViewModelBase
{
    public ViewModelBaseWithLang(MultiLanguageWorkshop lang)
    {
            this.Lang = lang;
    }

    public MultiLanguageWorkshop Lang { get; }
}

Binding to multilingual data

Now that we configured the library correctly, let’s bind some textbox in MainPage with data from the resource. First we need to modify the MainViewModel:


public class MainViewModel : ViewModelBaseWithLang
{
    public MainViewModel(MultiLanguageWorkshop multiLanguageWorkshop) : base(multiLanguageWorkshop)
    {
    }
}

The next step is to perform the binding in the MainPage.xaml

If we run the application it should look like this:

How to change the language

Cool, we can now see the text is loaded properly. How about changing the language? For this, we’ll add two buttons because we support 2 languages: English and Romanian.

Add this method in code behind:


private void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
      ViewModel.ChangeLanguage((sender as Button).Content as string);
}

And finally don’t forget about this one in the ViewModel:


public void ChangeLanguage(String language)
{
     Lang.CurrentLanguage = language;
}

Now our sample will look like this after we click the Romanian button:

Conclusion

In my opinion, the Mindgaze.Languages library can be used as a powerful alternative to MS resource files. It can be easily used to change the display language on the fly, which is very useful if you implement a kiosk app.

Other features:

  • Validation of JSON resources on load. This means that if a language translation is missing, an exception will be thrown
  • External resources are supported via associations
  • Easily include other resources with the help of relative file loading (will be exemplified in a future article)
  • Have big multiline translations? Is it tedious to keep it in a single line JSON value, so it can be kept in a separate text file and loaded with the Load directive (will be exemplified in a future article)

Having said this, I hope it’ll instill some curiosity in you to try this library and share your opinions on that!

Github source code

Thanks for reading, I hope you found this article useful and interesting. If you have any suggestions don’t hesitate to contact me. If you found my content useful please consider a small donation. Any support is greatly appreciated! Cheers  😉

afivan

Enthusiast adventurer, software developer with a high sense of creativity, discipline and achievement. I like to travel, I like music and outdoor sports. Because I have a broken ligament, I prefer safer activities like running or biking. In a couple of years, my ambition is to become a good technical lead with entrepreneurial mindset. From a personal point of view, I’d like to establish my own family, so I’ll have lots of things to do, there’s never time to get bored 😂

View all posts by afivan →