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);




            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:


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="">


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

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












        <!- ... -->



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 *