Reacting to a Language Change
Excerpt by Ken Getz
Although it won't happen every day, your application may need to react to the situation in which a user changes the currently active language in Windows, while your application is running. Although it's possible to handle the event that occurs in this situation, it's important to note that the technique you'll see here allows you to programmatically update text-it won't automatically refresh user interface elements to which you have bound localized text using the x:Uid property. (There may be a simple way to make this work, but the Microsoft documentation certainly doesn't mention it!) Your job, then, involves reacting to an event that your application handles in reaction to the user language changing. In the event handler, your code must update all the user interface elements that contain localized text.
As mentioned earlier, Windows provides two means of accessing resources programmatically. You can use the ResourceLoader class, as you have done previously; or you can use the ResourceManager class, which provides more functionality at the "cost" of being more difficult to use. You can certainly use the ResourceManager class to do everything you've done so far (for which you previously used the ResourceLoader class). In order to retrieve a reference to the resource manager for the currently running application, use the ResourceManager.Current property. You will also need to interact with the ResourceContext class, which encapsulates all the factors that might affect resource selection (such as the selected language, for example). The collection of factors that affect resource selection is an instance of the ResourceQualifiers class, and a ResourceContext's QualifierValues property retrieves a ResourceQualifiers collection containing information about the context's resource qualifiers. The QualifierValues property of a ResourceContext object returns a collection of type IObservableMap<K,V>, where K represents the type of the key, and V represents the type of values in the collection. This class raises its MapChanged event when any of its members changes, and this occurs when the language changes. (Remember, the qualifiers represent all the characteristics that help the ResourceManager instance figure out which string to load when you supply a resource name, and the current language is certainly one of those qualifiers!) Given all this information, your code must trap the MapChanged event of the QualifierValues property of the ResourceContext object provided by the DefaultContext property of the current ResourceManager. In other words, you must handle this event:
That's quite a mouthful! And, of course, there's a wrinkle. There's always a wrinkle. The MapChanged event occurs on a thread other than the user interface thread, and updating the user interface from a separate thread isn't allowed. This certainly complicates updating the text on the page! You must ensure that the code that updates the page is called from the page's thread. In order to ensure the correct thread switch, your code should call the current page's Dispatcher.RunAsync method, which guarantees a thread switch to the correct thread. Of course, when using the RunAsync method, you must include the await keyword in the call; when you use the await keyword in the method call, you must modify the procedure declaration to include the async keyword (so the compiler knows to handle this procedure specially). In addition, you can specify the priority for the asynchronous call to the code that updates the page's text: The sample uses the CoreDispatcherPriority.Normal parameter in the call to the RunAsync method. After adding the event handling code, you should call a procedure that you create to update the text on the current page. Remember that your code runs, allowing you to manually update text on the screen, but no updates occur automatically-"bound" resources won't update.
This post is an excerpt from the online courseware for ourWindows 8 Using XAML: Views, Resources, and Toastscourse written by expert Ken Getz.
This course excerpt was originally posted July 11, 2013 from the online courseware Windows 8 Using XAML, Part 09: Views, Binding, and Templates by Ken Getz