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!

                             

No Comments

Add a Comment

As it will appear on the website

Not displayed

Your website