Silverlight Quick Tip: Resources in RESX files – Image Resources for Localization - DevCorner

Silverlight Quick Tip: Resources in RESX files – Image Resources for Localization

This post was actually born in the middle of previous post :)

I had to find the way to use images as a RESX resources – this actually was second question of the person who asked me about forcing the rebinding.

Before starting, some theory about RESX usage in Silverlight.

Silverlight support usage of RESX files and localization via “SupportedCultures” attribute in CSPROJ file. The attribute itself even exists in project created with Silverlight 3  Tools, but for some reason there is no interface to change the cultures (or at least I didn’t found them). So the only way (for me) to change this attribute is via text editing the CSPROJ file.

<SupportedCultures>
    de,he,ru
</SupportedCultures>

After this attribute set, if we will use RESX files with standard .NET localization naming convention (<RESOURCE_NAME>.resx for culture neutral resources and <RESOURCE_NAME>.<LANGUAGE>.resx for language depended resorces) Visual Studio will compile resources and will create satellite assemblies for supported cultures.

I’ve added new “Resource” file to my project, and \added string values for HE, RU and DE languages. The 4th resource file is Neutral Culture (in my case EN) resources

image

imageimage

Here is first quick tip:

  • Change Access Modifier of your resources to “Public”, otherwise Silverlight will not be able to use it. image

Second tip:

  • Change access modifier of constructor in auto generated Resource class from internal to public (in my case the generated file was Strings.Designer.cs):
    internal Strings() -> public Strings()

The usage of those resources is very easy – simple StaticResource declaration in XAML and usage:

<Canvas.Resources>
  <local:Strings x:Key="res"/>
</Canvas.Resources>
<StackPanel x:Name="LayoutRoot" Orientation="Vertical">
  <TextBlock x:Name="txtSTR1" Text="{Binding tb1, Source={StaticResource res}}" FontSize="15" Foreground="Black"/>
</StackPanel>

This way the text displayed in TextBlock will depend on Thread.CurrentThread.CurrentUICulture value or on “uiculture” parameter for Silverlight plug-in:

<param name="uiculture" value="de" />

To see how to force re-binding when Thread.CurrentThread.CurrentUICulture value changes at the runtime – see this post.

Now to the main issue – when trying to add any non-textual resource to the resource file visual studio will generate wrong code in the Designer file:

image

For Image(of any kind)/Icon/Existing File (of image type) it will generate following code:

public static System.Drawing.Bitmap img1
{
  get
  {
    object obj = ResourceManager.GetObject("img1", resourceCulture);
    return ((System.Drawing.Bitmap)(obj));
  }
}

The “System.Drawing.Bitmap” does not exists in Silverlight, thus the application will not compile. From other hand, if Visual Studio will not identify the resource (unknown resource type) it will generate following code:

public static byte[] img1 {
    get {
        object obj = ResourceManager.GetObject("img1", resourceCulture);
        return ((byte[])(obj));
    }
}

This is much better :)

Third tip:

  • Before you adding the image resource to Silverlight resources rename them
  • Alternatively you left the file name as it was and edit RESX file in text editor as follows:
<data name="img1" type="System.Resources.ResXFileRef, System.Windows.Forms">
  <value>Resources\MVP_small.png;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>

Now the usage of this resource is very simple – all we need is a converter to convert byte[] to BitmapImage (in case of images). Here the converter:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
  byte[] arr = (byte[])value;

  MemoryStream str = new MemoryStream(arr);
  BitmapImage img = new BitmapImage();
  img.SetSource(str);
  return img;
}

And usage (ByteArrConverter defined in Resources):

<Image x:Name="img" Width="100" Height="100" Source="{Binding img1, Source={StaticResource res}, 
       Converter={StaticResource ByteArrConverter}}" Margin="5"/>

Now image will be displayed on page, and it will will depend on Thread.CurrentThread.CurrentUICulture value or on “uiculture” parameter for Silverlight plug-in:

image

image

Live demo here

Sources here

 

Enjoy,

Alex

Published Tuesday, July 14, 2009 1:08 PM by Alex Golesh

Comments

# re: Silverlight Quick Tip: Resources in RESX files – Image Resources for Localization

THANKS!!!!!!!!!!!!

Friday, July 24, 2009 1:52 PM by FReger

# re: Silverlight Quick Tip: Resources in RESX files – Image Resources for Localization

Handy method btw you can edit the your supportedcultures eg:

1. In Solution Explorer

2. Right Click on your silverlight project folder

3. Select unload project

4. Right click on your project

5. Select Edit {Myproject} eg: "Edit SL3Loc.csproj"

6. Edit the supported cultures element and save

7. Right click on your project and select reload project

Saturday, August 22, 2009 12:43 PM by slyi

# re: Silverlight Quick Tip: Resources in RESX files – Image Resources for Localization

BTW changing your contrustor to public is not recommended as the it break each time you edit the resx file. Instead use a class to make your resourse public. eg msdn.microsoft.com/.../dd882554(VS.95).aspx

Saturday, August 22, 2009 12:50 PM by slyi

# Silverlight Quick Tip: How to get localized resources from RESX file in code behind

It looks like I’m using too much resources and localizing too much applications lately :) This time I

Wednesday, October 21, 2009 2:06 PM by DevCorner

# Silverlight Quick Tip: How to get localized resources from RESX file in code behind

It looks like I’m using too much resources and localizing too much applications lately :) This time I

Wednesday, October 21, 2009 2:26 PM by Community Blogs

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above: