Working with Resx Files

,

To create a resx file, right-click a project node in the Solution Explorer and select Add and then New Item, or alternatively press Ctrl+Shift+A (see Figure 19.1).

Image

FIGURE 19.1 Creating a new resx file.

After the first default resource file has been created, enabling support for alternative languages is achieved by adding a new resource file for each additional language (see Figure 19.2) and by employing the following naming convention:

<Name of the default language resource file>.<Culture Name>.resx

Image

FIGURE 19.2 By using different culture codes when naming resx files, Visual Studio generates satellite assemblies for specific cultures.

Names differ only by culture name, where the culture name has the following format:

<Lowercase two letter language code>-<Uppercase two letter region code>

If you are not specifying a region, use the following format:

<Lowercase two letter language code>


Note

The culture code present in the name of a resx file must match a SupportedCultures string within the project file. Otherwise, no satellite assembly is generated. This also applies when the region is defined with a wider scope without a locale in the SupportedCultures project element.


When editing a resx file, the resx editor allows the access modifier of the generated class to be set to internal or public (see Figure 19.3). Because the generated class will be the target of XAML data-binding expressions, it must be set to public because internal visibility prevents the data-binding infrastructure from resolving the class properties.

Image

FIGURE 19.3 Setting the access modifier to public enables properties to be used in XAML binding expressions.

Although setting the access modifier to Public produces public properties, it unfortunately does not produce a public constructor. The resx file’s generated designer class is left with an internal constructor, which prevents it from being used directly as a resource in a XAML file. Furthermore, modifying the generated designer class is not a practical solution, because any changes to it are lost if the resx file is modified, causing the resx custom tool to run.


Caution

Unfortunately, the generated output of the PublicResXFileCodeGenerator (the tool that converts the resx file XML to a class) does not generate an extensibility point that is compatible with the XAML resource infrastructure. That is, it is not possible to include the generated output directly as an application resource via XAML. The generated class that it produces is not partial, and subclassing it breaks the ability to data bind to the static resource properties in the base class.


A solution is to use an intermediary class, whose task is to create an instance of the generated class and expose it as a public static property, thereby making it compatible with the data-binding infrastructure. This class, called BindableResources, is shown in Listing 19.1 and is available in the downloadable sample code.

LISTING 19.1. BindableResources Class


public class BindableResources
{
    static readonly BindableChangeNotifier<MainResources> resources
        = new BindableChangeNotifier<MainResources>(new MainResources());

    public static BindableChangeNotifier<MainResources> Resources
    {
        get
        {
            return resources;
        }
    }

    public static void RaiseNotifyPropertyChanged()
    {
        resources.RaisePropertyChanged();
    }
}


As new resx files are added to a project, they should also be added to the BindableResources class and exposed as static properties. For convenience, the default resources class, MainResources, is named Resources.

Although the approach presented here may at first appear complicated, it provides for change notification, allowing the data-binding infrastructure to be coerced into rereading the static properties of the localizable resources when the application culture changes.


Note

The Windows Phone 8 SDK now includes a LocalizedStrings class in the Windows Phone App project template, which resembles the BindableResources class that I originally demonstrated in the first edition of this book. What is still lacking from the SDK, however, is the dynamic update capability provided by the custom BindableChangeNotifier class, which is discussed later in the chapter.


The BindableResources class uses the BindableChangeNotifier to expose the localizable resources. When the culture is changed, the BindableResources class signals to each BindableChangeNotifier instance that the PropertyChanged event should be raised. After the event is raised, all data-bindings associated with the resources are refreshed.

The BindableResources class can be defined as a resource in an applicationwide resource file or directly in your app’s App.xaml file, as shown in the following excerpt:

<Application ...>
    <Application.Resources>
        <local:BindableResources x:Key="BindableResources" />
    </Application.Resources>
</Application>

This allows an instance of the BindableResources proxy to be resolved in binding expressions, like so:

<TextBlock Text="{Binding Resources.Instance.ApplicationTitle,
        Source={StaticResource BindableResources}}" />

Here the Source property of the Text property’s binding expression points to the BindableResources instance. The path accesses the ApplicationTitle resource string via the Instance property of the BindableChangeNotifier, which happens to be an instance of the resx generated designer class.


Note

Validation of binding expressions is performed at runtime. Unlike WPF, Windows Phone does not support the x:Static markup extension, which would otherwise provide the means to validate the binding expression at compile time.


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.56.18