Silverlight Resource Markup Extension

In case you want to use resources in your Silverlight applications, you have a couple of options. My favorite, however, is using a markup extension and RESX resource files. With this approach, you can have code such as:

<Button Click="OnClick" Content="{my:Resource ResourceName=Resources, ResourceKey=ButtonTitle}"/>

This is very similar to how you’d do it in ASP.NET web forms, and you can even share the resource files. Let’s see the ResourceExtension class, which, by implementing IMarkupExtension<T>, becomes a markup extension, meaning that by convention we can leave out the Extension suffix:

public sealed class ResourceExtension : IMarkupExtension<String>

{

    public String ResourceName { get; set; }

    public String ResourceKey { get; set; }

 

    private Type FindResourceType(params Assembly [] assemblies)

    {

        foreach (var assembly in assemblies.Distinct())

        {

            var resourceType = assembly.GetTypes().SingleOrDefault(x => (x.BaseType == typeof(Object)) && (x.Name == this.ResourceName));

 

            if (resourceType != null)

            {

                return resourceType;

            }

        }

 

        return null;

    }

 

    public String ProvideValue(IServiceProvider serviceProvider)

    {

        var executingAssembly = Assembly.GetExecutingAssembly();

        var callingAssembly = Assembly.GetCallingAssembly();

        var applicationAssembly = Application.Current.GetType().Assembly;

 

        var resourceType = this.FindResourceType(applicationAssembly, callingAssembly, executingAssembly);

 

        if (resourceType != null)

        {

            var resourceManager = new ResourceManager(resourceType);

            return resourceManager.GetString(this.ResourceKey);

        }

        else

        {

            throw new InvalidOperationException(String.Format("Cannot find resource {0} with key {1}.", this.ResourceName, this.ResourceKey));

        }

    }

}

ResourceExtension will try to find the class identified in the ResourceName property in a couple of assemblies and if it finds it, will try to return the resource key from the ResourceKey property; otherwise, it throws an exception, because, obviously, something is wrong.

The resource files need to be compiled as embedded resources:

image

Now, before you can use this, you need to do a couple of things:

  1. Add the NeutralResourcesAssemblyAttribute to your assembly to indicate which language the default resource file refers to (in AssemblyInfo.cs):
    [assembly: NeutralResourcesLanguage("en-US")]

  2. Set the culture of the current thread upon application startup (App.xaml.cs):
    private void Application_Startup(object sender, StartupEventArgs e)

    {

        Thread.CurrentThread.CurrentCulture = new CultureInfo("pt-PT");

        Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

     

        this.RootVisual = new MainPage();

    }

  3. Add the list of supported languages to the project file (.csproj):
    <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

      <PropertyGroup>

        <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>

        <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>

        <ProductVersion>8.0.50727</ProductVersion>

        <SchemaVersion>2.0</SchemaVersion>

        <ProjectGuid>{4AB634F1-D00D-4461-83F4-3ADA1DF2D47B}</ProjectGuid>

        <ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>

        <OutputType>Library</OutputType>

        <AppDesignerFolder>Properties</AppDesignerFolder>

        <SupportedCultures>en-US;pt-PT</SupportedCultures>

        <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>

        <TargetFrameworkVersion>v5.0</TargetFrameworkVersion>

        <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>

        <SilverlightApplication>true</SilverlightApplication>

        <!- ... -->

      </PropertyGroup>

    </Project>

And this is it! Enjoy!

Published by

Ricardo Peres

Team Leader at Dixons Carphone. Microsoft MVP.

Leave a Reply

Your email address will not be published. Required fields are marked *