Search code examples
c#xamlwindows-store-appsembedded-resourcedesigner

Windows store app ResourceLoader at design time


I've started creating a Windows Store App for Windows 8.1 and now I encountered a problem concerning localization.

I would like to display a string resource from a .resw file at design time, but every attempt to do so has failed, even though it works at runtime.

When using the x:Uid attribute, I still have to supply the Text property (i.e. for a TextBlock) and I don't like to write the text twice.

I also tried creating a property for the string on the viewmodel:

public string Title
{
    get { return ResourceLoader.GetForCurrentView("Strings").GetString("MainView_Title"); }
}

This is working at runtime, but at design time it is blank.

So the question is, is there a way to display resources from a .resw file in the XAML-designer?

More specifically, does the ResourceManager class allow .resw files to be read at design time?

Thanks for your help, Lucas


Solution

  • Old Method

    So, there are a couple of things you can do.

    The first (and simplest, given that you're using x:Uid already) is to just supply the text into the Text field. The x:Uid-related value will overwrite whatever is in there.

    <TextBlock Text="MyText" x:Uid="MainView_Title"/>
    

    The second method is to use the property like you already have, and then check to see if the app is in Design Time (through a couple of different methods), then return a constant value if it is and the Resource if it is not.

    public string Title
    {
         if(ViewModelBase.IsInDesignTimeStatic) //Mvvm Light's easy accessor
             return "My Text";
         return ResourceLoader.GetForCurrentView("Strings").GetString("MainView_Title");
    }
    

    Hope this helps and happy coding!

    Edit: There appears to be a new way to do this, at least as of Windows 8.1.

    New Method

    • Create a class which references a ResourceLoader (similar to the property described above).
    • Create an indexed property accessor which accepts a string key and return the value from the ResourceLoader.

      public class LocalizedStrings
      {
          public string this[string key]
          {
              get
              {
                  return App.ResourceLoader.GetForViewIndependentUse().GetString(key);
              }
          }
      }
      
    • In your App.xaml, define a StaticResource of this type.

      <Application.Resources>
          <ResourceDictionary>
              <common:LocalizedStrings x:Key="Localized"/>
          </ResourceDictionary>
      </Application.Resources>
      

    Now, when you want to access your property with entry key MainView_Title, use this. It's more verbose, but it should translate both in the designer and in the app itself.

    <TextBlock Text="{Binding Source={StaticResource Localized}, Path=[MainView_Title]}" />
    

    You can shuffle it around to be a bit more readable if you'd like, such as:

    <TextBlock Text="{Binding [MainView_Title], Source={StaticResource Localized}}" />