Search code examples
c#localizationwindows-runtimewindows-phone-8.1portable-class-library

Unable to access localized resources in .NET 4.5 PCL from Windows Phone 8.1


I have troubles accessing localized string resources in Portable Class Library targeting .NET 4.5.

I am allowing the user to select the language on first page and have localized experience on further pages. I am trying to achieve that just by getting resource with code

MyTextBloxk.Text = PasswordResetMethod_Page.Title;

PasswordResetMethod_Page is the auto-generated class from the .resx

Everything works fine on the WP 8.1 emulator, but when I try to deploy it to the real device I get

Error : DEP6810 : MdilXapCompile.exe failed with error code 1004. See log file 'C:\Projects\WP81-ResourceBug\ResourceBugRepro.WP81\obj\Debug\MDIL\MDILXapCompileLog.txt' for more details.

Error: Compile filter argument specified non-existent file: C:\Projects\WP81-ResourceBug\ResourceBugRepro.WP81\obj\Debug\MSIL\ar\ResourceLib.resources.dll

Invalid argument

To reproduce:

  1. Clone repo https://github.com/konradbartecki/WP81-ResourceBug
  2. Set WP8.1 as startup project
  3. Deploy to the device

Works fine on the emulator, does not work when deploying to real device


Solution

  • Unfortunately the workaround described on Phil Hoff blog did not work for me too well. I have developed my own workaround. It turns out if you are using .resx files to store string values only, then you can easily convert them to .resw.

    So what I am doing is automatically converting all .resx files from PCL and placing it into native structured folders in my Windows Phone 8.1 project and refreshing them every build using this tool that I wrote.

    https://github.com/konradbartecki/ResxHell

    Then I can easily access my string resources from code like this

    var resourceLoader = new ResourceLoader();
    var localizedText = resourceLoader.GetString("MyCustomReswFile/MyCustom");
    

    For nice binding I ended up creating ValueConventer and small localization helper class, take a look at this gist: Binding from .resw files example

    With the use of that you can do following in your xaml pages:

    //For resource in file Page.Login.resw and string ID "NotUserYet"
    <TextBlock Text="{Binding ConverterParameter=Page.Login/NotUserYet, Converter={StaticResource ResString}, Mode=OneWay, Source={StaticResource ResString}}"/>
    

    or string localizedtext = LocalizationHelper.GetString("MyCustomReswFile", "MyStringId");