An easy approach to UI internationalization and culture change Written on November 25, 2008, by akafazov.

MyCultureChanger

I am having the task to do internationalization on a software piece written in .NET. The app has to support multiple languages in the UI and the ability to change the UI language at runtime. So the task could be broken up in two parts:

The first part seems quite easy, as Visual Studio already has built-in all of the infrastructure required: designer support for UI internationalization, .resx files with all resources in XML format, which are compiled to dlls for deployment. Although easy to do, this involves quite a bit of work with the designer, as all controls’ properties has to be set individually for every UI culture.

This is usually accomplished with the System.Resources.ResourceManager class and the GetObject method. The code looks something like this:

buttonEnvironment.Font =

((System.Drawing.Font)(resources.GetObject(class="str">"buttonEnvironment.Font")));

The line above sets the Font property of the buttonEnvironment control, given that this property is available in the resource files. Overall, this approach has several drawbacks:

Considering those points, I went for a custom solution, which includes all the benefits of the above method and doesn’t have any of the above problems. All this is done within a couple lines of code and can work with or separately from the existing internationalization methodology. This means, if you have already started translating your UI in the old-fashioned way, you can still take advantage of the new approach.

Here is the code:

        System.ComponentModel.ComponentResourceManager resources = class="kwrd">null;

        class="kwrd">public Form1()
        {
            InitializeComponent();
            class="kwrd">this.resources =
                class="kwrd">new ComponentResourceManager(class="kwrd">typeof(Form1));
        }

        class="kwrd">private class="kwrd">void radioButton_Language_CheckedChanged(class="kwrd">object sender, EventArgs e)
        {
            class="kwrd">if (radioButton_Bulgarian.Checked)
            {
                System.Threading.Thread.CurrentThread.CurrentUICulture =
                    class="kwrd">new System.Globalization.CultureInfo(class="str">"bg");
            }
            class="kwrd">else class="kwrd">if (radioButton_German.Checked)
            {
                System.Threading.Thread.CurrentThread.CurrentUICulture =
                    class="kwrd">new System.Globalization.CultureInfo(class="str">"de");
            }
            class="kwrd">else class="kwrd">if (radioButton_English.Checked)
            {
                System.Threading.Thread.CurrentThread.CurrentUICulture =
                    class="kwrd">new System.Globalization.CultureInfo(class="str">"en");
            }

            ApplyAllResources(class="kwrd">this);
        }

        class="kwrd">private class="kwrd">void ApplyAllResources(Control c)
        {
            class="rem">// do not paint control while changing it's properties
            c.SuspendLayout();

            class="rem">// apply all properties for the current UI culture from the assemble resources
            resources.ApplyResources(c, c.Name);

            class="rem">// apply all resources for child controls recursively
            class="kwrd">foreach (Control subControl class="kwrd">in c.Controls)
            {
                ApplyAllResources(subControl);
            }

            class="rem">// resume painting
            c.ResumeLayout();
        }

We take advantage of the System.ComponentModel.ComponentResourceManager class and the ApplyResources method, which accepts the control and it’s name as parameters. It then goes forward to set all properties for this control, if available in the .resx files. So if you decide that you want to initialize a new property from the resources, just add it there, and the code doesn’t need to be touched. The function ApplyAllResources goes trough all child controls recursively, so all hundreds of lines of code is now reduced to a couple of lines. Simple and beautiful :)

You can download a sample C# project here.

Read more from the Programming category. If you would like to leave a comment, click here: Comment. or stay up to date with this post via RSS, or you can Trackback from your site.
Social Bookmark : Technorati, Digg, de.licio.us, Yahoo, Blinkbits, Blogmarks, Google, Magnolia.

Leave a Comment

If you would like to make a comment, please fill out the form below.

Name (required)

Email (required)

Website

Comments

© Copyright Blog of Angel Kafazov - Powered by Wordpress - Designed by Speckyboy. Enjoy with a Whopper Meal & Large Coke.