Home > Localization > Localization in WPF

Localization in WPF


There are lots of good articles on localizing WPF applications out there, so here it is more a matter of commenting and choosing different approaches than of creating new value. But before I start, I’d like to discuss the jobs of localization a bit, and explain my choices in how to handle them.

Providing a Localized User Interface

The most obvious effect of localization is to provide labels, descriptions and pictures which contain texts in the current user’s language. So, the two bits of information one needs in order to provide this are the user’s language and the source of the texts. In .Net, localized resources are contained in resource DLLs, which are provided together with the main program executable, and are accessed through the ResourceManager class internally, already taking into account the language of the current thread.

Visual Studio supports two ways of editing localized resources: the one is directly through the My Project / Resources editor, the second is indirectly as part of the Windows Forms designer. Unfortunately, there is no such support for WPF. There is a command line tool named LocBAML which is supposed to extract all localizable strings from compiled XAML and to allow to create the localized resource DLLs from it, but this is not very integrated into the development process and requires changes to the XAML itself using UI ids (which are a good thing to have but a nightmare to maintain). So, most examples I found ignore this approach and instead make for a way to make the usual localized resources from the Resource editor available to WPF.

The obvious solution is a MarkupExtension that accepts the name of the resource as a parameter and returns its value. Some of the published components allow to change the language at runtime; I didn’t think this necessary, so my implementation just sets the value, which means you have to close and reopen forms in order to make a language change visible. However, it has the neat little feature of being able to find the ResourceManager of the main program’s assembly by itself, so you don’t have to configure anything in order to be able to use it. Find it explained here.

Formatting and Parsing Values According to Localized Formats

Formatting and parsing values that are displayed to or edited by the user needs to take into account local variations in formatting conventions. 12.456,70 and 12,456.70 are actually the same number, but if you’d ask an American and a German they’d probably disagree on what number that is.

Recognizing these formats has been a job for localization components ever since computers have been invented, so it’s quite well supported in .Net. However, for reasons unknown WPF’s default language for all these purposes is US English, regardless of the system’s settings, let alone the culture of the current thread. In order to change the language for formatting, you have to set the Language attribute. There are some ways to do it; one way one frequently sees is to override its default value to be the system’s culture on application startup, but I find this a little bit harsh, and I think you can’t undo it if you want to change the language at runtime. So I prefer to set the Language attribute on top of the page or window, so that it is inherited by all the controls. In order to get at the language more conveniently, I implemented MarkupExtensions that return the current language or the current UI language, respectively.

There are cases where this behaviour isn’t enough. As I learned recently, even setting the Language property to the CurrentCulture doesn’t make WPF acknowledge changes in date and number formats users might have made in the Regional Settings of their computer. In order to work around this, one would have to use a custom Binding extension, which might be a good idea anyway, since it provides a way to hook all sorts of useful little helpers to bindings without changing the XAML code too much. But actually, I don’t like this solution and hope there will be a fix soon…

A special case of localized formatting is providing translations for Enum values. .Net can parse Enum values from their string equivalents, but unfortunately those string equivalents are hardcoded with the definition of the Enum. Therefore, WPFGlue contains a LocalizedList, which fills two jobs: It works as a Converter, converting the Enum values into localized strings and vice versa, and it can be used as ItemsSource for a ComboBox or other Selector in order to let the user pick from the available values. Its intended way of usage is defining an instance of it in a ResourceDictionary, using an initialization string which maps the invariant string representations to localized counterparts. As an extra, it can produce and parse strings that are combinations of multiple Enum values.

You can find descriptions and examples for these components here.

Switching the Keyboard to Different Languages

Handling different languages with different keyboard layouts within the same document has only recently become a common feature in text processing applications. However, since I frequently have to work with data in different languages, I wouldn’t like to miss this feature.

In WPF, the class responsible for managing different keyboard languages is called InputLanguageManager. It exposes an attached property, InputLanguage, that accepts a culture identifier and switches the keyboard to the defined layout for this language, if one is installed. Unfortunately, this only works when the control receives focus. So, if you are typing something in a TextBox and change the InputLanguage while you are typing, e.g. through a keyboard shortcut, this change doesn’t become active unless the keyboard focus leaves the TextBox and returns again.

Also, in principle you can define different languages for paragraphs in a RichTextBox by setting the InputLanguageManager.InputLanguage on the Paragraph elements in the RichTextBoxes FlowDocument, but the keyboard doesn’t automatically change to the appropriate layout when the selection enters a section in a different language. This feature is extremely useful, so I decided to create a Sticky Property which allows to change the keyboard language effective immediately, and a Sticky Behaviour that sets the current input language according to what is set in this attached property on the FrameworkContentElements inside a RichTextBox’s FlowDocument. This property is explained here. Recently I found a post on Connect which suggests that there might be a native solution for this problem in WPF 4.

Links

Christian Moser describes a good example for localization by MarkupExtension here.

Advertisements
Categories: Localization Tags: ,
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: