13 January 2009

Silverlight and localization

Lucky me! I got a new project: the new company's website. Such sites need to have two features:

  1. an impressive presentation layer
  2. a few languages versions
For the first one, Silverlight is the dream technology. For the second one, however, it's a nightmare. I wanted to be able to change the language easily to say "see, Boss, the French version looks good too". I spent one entire day trying to make it work and it kinda works... kinda.

There are a few catches. First, there is no easy way to do that as in asp.net (there should be!). Microsoft published an article on localizing Silverlight applications and it's no fun to read. But, we're big boys, let's add our resources files by ourselves, rename them and stuff.

Second catch is coming: the constructor in the resourse.designer.cs file is protected instead of public. Two workarounds here:
  1. change it yourself everytime you modify the resource
  2. get a tool for that: Dmytro Kryvko’s Extended Strongly Typed Resource Generator 2.3
So far, everything is to be worked around. But... I wanted too much. I wanted localization and user controls. I could declare two namespaces, one for the resources and one for the controls, I could decalre the resource as a static resource, but binding... no. I got an AG_E_PARSER_BAD_TYPE error on a perfectly correct xaml file. After the entire day of investigating, I gave up on binding my controls to the resources in xaml - I bind them at runtime and rebind each time the language is changed. Ugly, but works.

I don't know... you might have more luck than me. If you wanna localize, start with reading "Silverlight and International Thoughts". There's a fully detailed instruction on creating a localized application in 43 steps.

As much as I like Silverlight, localization is a nightmare and that disappoints me a lot, as it's something that's been done in asp.net already - I feel like reinventing the mouse wheel here!

8 comments:

  1. Sorry to hear, you had problems with this as well. I'm currently in the process of building an enterprise application with Silverlight 2 as a UI and I've cracked the localization issue a slightly different way. You can read about it here:
    http://jvdveen.blogspot.com/2009/01/adventures-while-building-silverlight_12.html

    If you have any questions, please let me know. I'm always happy to help.

    Greets,
    Jonathan van de Veen

    ReplyDelete
  2. I found that if use loc namespace that inherits from your parent namespace, VS can sometimes give vailadtion errors. Try a different namespace altogether from your local project in your custom tool namespace property in strings.resx

    See sample on http://wpf-e.spaces.live.com/Blog/cns!2B248D261D0E0035!407.entry

    ReplyDelete
  3. Thanks slyi, your tip helped.

    But, on my custom control that has a string "Text" property, I get a
    AG_E_PARSER_BAD_PROPERTY_VALUE when I try biding it (it might be my bad).

    On a textblock, however, the first binding works. But I want to be able to switch languages at runtime:

    private void btnFR_Click(object sender, RoutedEventArgs e)
    {
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr");
    ...

    And that code didn't change the textblocks text to a different language version.

    ReplyDelete
  4. To change the culture you can use that in your event handler:
    System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("fr-fr");
    System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("fr-fr");
    Page page1 = new Page();
    LayoutRoot.Children.Clear();
    LayoutRoot.Children.Add(page1);

    ReplyDelete
  5. You mean regenerate my whole app? Isn't reassigning all the strings more efficient?

    The longer I dig this subject, the happier I am with my solution. ;)

    ReplyDelete
  6. I found this site using [url=http://google.com]google.com[/url] And i want to thank you for your work. You have done really very good site. Great work, great site! Thank you!

    Sorry for offtopic

    ReplyDelete
  7. to avoid AG_E_PARSER_BAD_PROPERTY_VALUE, you have to set the resx to public and manualy change the constructor from internal to public

    ReplyDelete
  8. You're right, but I had to do it each time I modified the ressources, which was unpleasing.

    That post must be pretty outdated now that SL 3 and 4 Beta are out, but thatnks for contributing anyway.

    ReplyDelete