Resource Dictionaries

Introduction

Resource dictionaries can be used to define globally accessible values that can be bound to view fields using the standard data binding mechanism. The resource dictionary may return different values depending on global settings (language and platform) that can be changed during runtime. It's a flexible feature that can be used to do things like localization and adapt layout to different screen sizes.

Creating a Resource Dictionary

A resource dictionary can be created by a XUML file having the root element ResourceDictionary:

Localization.xml

<ResourceDictionary Name="Loc" xmlns="MarkLight">
</ResourceDictionary>
          

We have now created a resource dictionary called "Loc". The name you give the resource dictionary will be used when its resources are accessed in XUML. If you omit the name the resources are assigned to a default dictionary. For this example we will use the dictionary for localization. Let's continue by adding a few resources.

Creating Resources

Resources are created by adding elements with the name Resource to the dictionary:


<ResourceDictionary Name="Loc" xmlns="MarkLight">
    <Resource Key="Greeting" Value="???" />
    <Resource Key="Greeting" Language="en" Value="Hello" />
    <Resource Key="Greeting" Language="sv" Value="Hej" />
    <Resource Key="Greeting" Language="hi" Value="Namaste" />
    <Resource Key="Greeting" Language="fa" Value="Salaam" />
</ResourceDictionary>
          

Here we have created five resources with different values but with the same key: "Greeting". If we request the value for the resource with the key "Greeting" which value returned depends on the global resource dictionary settings. For example, if the language is set to "en" (English) the value "Hello" is returned, if it's set to "hi" then "Namaste" is returned, and if language isn't set then the value "???" will be returned.

Binding to Resource Values

You can create resource bindings in XUML using the following notation:

{@DictionaryName.ResourceKey} or {@ResourceKey}

If we omit the dictionary name we access resources in the default dictionary. Here is how to bind the label text to a resource value in our localization dictionary:


<LocalizationExample>
    <Label Text="{@Loc.Greeting}" />
</LocalizationExample>
          

If you run the example you will see "???" printed. Next we'll explain how to set which settings the dictionary should use (language and platform).

Configuring Resource Dictionary

The default language and platform can be set on the view presenter:

configure resource dictionary
If you change the language to "en" and run the example you should see "Hello" printed in the label. You can also set these settings in code:


    public void ChangeLanguageToEnglish()
    {
        ResourceDictionary.SetConfiguration("en");
        ResourceDictionary.NotifyObservers(); // update bindings
    }
          

Resource Groups

Resource groups are elements within the dictionary. Resources within the resource group inherit the parameters set on the group:


<ResourceDictionary Name="Loc" xmlns="MarkLight">
    <ResourceGroup Key="Greeting">
        <Resource Language="en" Value="Hello" />
        <Resource Language="sv" Value="Hej" />
        <Resource Language="hi" Value="Namaste" />
        <Resource Language="fa" Value="Salaam" />
    </ResourceGroup>
</ResourceDictionary>
          

In the example above, all the resources within the group will inherit the key "Greeting". Resource groups can be used to organize your resources and make the dictionary more readable. You can nest as many resource groups as you want and you can choose which parameter to group resources by (e.g. in our localization dictionary we could group resources by language rather than key).

Dynamic Resources

You can work with resources during run-time. E.g. if you want to load a resource dictionary from a database, you can create resources in the dictionary using the method SetResource:


    public void LoadResources()
    {        
        List<Resource> resourcesFromDatabase =  ... // load resources from database
        foreach (var resource in resourcesFromDatabase)
        {       
            // update existing or add new resources to a dictionary
            ResourceDictionary.SetResource("MyDynamicDictionary", resource);
        }

        ResourceDictionary.NotifyObservers(); // update bindings
    }
          

Note that whenever you are done changing a dictionary you need to call NotifyObservers to update all resource bindings.

Variables in Localized Strings

When localizing it's not uncommon to want to inject values within a localized string. In MarkLight you can accomplish this by using resource dictionaries combined with multi bindings using a string formatter as a transformation method:

Localization.xml

<ResourceDictionary Name="Loc" xmlns="MarkLight">
    <Resource Key="Greeting" Language="en" Value="Hello {0} {1}!" />   
</ResourceDictionary>
          

FormatLocalizationExample.cs

<FormatLocalizationExample>
    <Label Text="$View.Format2({@Loc.Greeting}, {FirstName}, {LastName})" />
</FormatLocalizationExample>
          

Format2 is a static transformation method that takes a format string as a parameter followed by two values to be inserted.




















Join the Announcement List

Be notified when new themes, views, tutorials and updates are available