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!


No Comments

Add a Comment

As it will appear on the website

Not displayed

Your website