Corrado's Blog 2.0

Online thoughts of a technology funatic

UWP: Read German text from a file

I had some hard times figuring out how to properly read a file that contains typical German characters (e.g umlauts) so I want to share my solution in case are in the same situation.

The magic trick is to register a new provider named “windows-1254” using Encoding.RegisterProvider

Beware of generated XAML in UWP

I admit, this is s strange blog post title but that’s what this post is going to talk about.

I’m working on a UWP app that has different min and target runtimes:


After doing some UI work with Visual Studio & Blend I’ve discovered that the app was crashing on machines without Anniversary edition installed. At the end of a debuggin session I’ve found the reason: The XAML template generated by the tools contains incompatible elements (resources mainly, but also new properties) that are not present on previous builds.

To give you an example, this is an extract from a ComboBox default template, generated by Blend when you use the Template->Edit copy feature:


<Setter Property="Foreground"

Value="{ThemeResource SystemControlForegroundBaseHighBrush}" />

14393 (Anniversary)

<Setter Property="Foreground"

Value="{ThemeResource ComboBoxForeground}" />

The reason of this is because the tools generate the template from the Target version SDK and not the Min version SDK that might even not be present.

The team said that they’re going to give you some warnings in the future when situations like this happen, but in the meantime, at least when you’re doing design work, be sure to selected, the min target version SDK otherwise you might end up in troubles.

Dynamic localization of Windows Store apps

Localizing a Windows Store app is a fairly easy task thanks to the x:UId attribute introduced with WinRT.
If you need to create a Multilanguage application just add to your Visual Studio solution a folder named Strings and below it add a folder for each language you want to support using the two letter ISO language as name.
In this picture I have a solution that support Italian and American English


Inside each folder I’ve added a resource file and note that there’s a Resource.resw file just below Strings folder, it represent the default fallback resource language file that will be used in case your app will be executed on a system whose language is different than America English or Italian.

Inside each Resource.resw add the property of the control to localize, in our case we want to localize the Text property of a TextBlock, so the file content for each will be:

en-US folder


it-IT folder


Now to localize the Text property of our TextBlock all we need to to is use this XAML:

1 <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 2 <TextBlock x:Uid="WelcomeMessage" 3 VerticalAlignment="Center" 4 Foreground="BlueViolet" 5 Text="..." 6 HorizontalAlignment="Center" 7 FontSize="48" /> 8 </Grid>

Here’s what you’ll see when the code is executed on an Italian pc:


Very easy isn’t it? Smile

This approach let you do more than just localize Text, if you want to dig more into it you can read this article

Ok, but imagine you have this mandatory requests:

  • 1-Application language can be unrelated to machine language (French app running on an Italian machine)

2-Language switching should not require an application reboot

3-You must use a MVVM friendly solution

Ok, things can get a little more intricate here  and since I haven’t found a standard solution I solved this way:

Step 1: Since we’ll deal with text only let’s rename resources inside .resw files from WelcomeMessage.Text to just WelcomeMessage (see below)


Step 2: Let’s create a ViewModel (yes, MVVM always requires a ViewModel…) and let’s add the necessary code to load the strings dynamically:

1 public class MyViewModel : INotifyPropertyChanged 2 { 3 private ResourceContext resoureContext; 4 5 public MyViewModel(string language) 6 { 7 this.UpdateCulture(language); 8 } 9 10 public void UpdateCulture(string language) 11 { 12 this.resoureContext = ResourceContext.GetForCurrentView(); 13 this.resoureContext.Languages = new List<string> { language }; 14 } 15 16 public string GetResource(string stringResource) 17 { 18 try 19 { 20 var resourceStringMap = ResourceManager.Current.MainResourceMap.GetSubtree("Resources"); 21 return resourceStringMap.GetValue(stringResource, this.resoureContext).ValueAsString; 22 } 23 catch (Exception ex) 24 { 25 return $"?{stringResource}?"; 26 } 27 } 28 29 ... 30 }

The magic here is inside UpdateCulture and GetResource methods, if we name the TextBlock in previous XAML snippet MyTextBlock we can dynamically change its text using this code:

1 public sealed partial class MainPage : Page 2 { 3 public MainPage() 4 { 5 this.InitializeComponent(); 6 this.MyTextBlock.Text = new MyViewModel("it-IT").GetResource("WelcomeMessage"); 7 8 } 9 }

But since we’re using MVVM we want to use databinding for that instead of code and we need a smart solution otherwise localization can become tedious, solution is not very far: just use an indexer:

Just add this line of code to the ViewModel

1 public string this[string key] => this.ApplicationController.GetResource(key);

And let’s inform binding that our indexer property need to be refreshed so that all texts will be reloaded when user changes the UI language at runtime modifying the UpdateCulture method this way:

1 public void UpdateCulture(string language) 2 { 3 this.resoureContext = ResourceContext.GetForCurrentView(); 4 this.resoureContext.Languages = new List<string> { language }; 5 this.OnPropertyChanged("Item[]"); 6 }

Note the trick of using “Item[]” as property name to signal that the class indexer has changed.

So let’s bind TextBlock’s Text property to viewmodel indexer using this syntax, and you’re done.

1 <TextBlock x:Name="MyTextBlock" 2 VerticalAlignment="Center" 3 Foreground="BlueViolet" 4 Text="{Binding [WelcomeMessage]}" 5 HorizontalAlignment="Center" 6 FontSize="48" />

You can find a complete example here.

Have fun!