Improvements to Localization in Visual Studio 2005

Designing and developing applications for the global economy can often be difficult, but the .NET Framework made globalization and localization much more simple. In Visual Studio 2005 resources are handled a little bit differently, providing you – the application developer – a class you can easily use throughout your application to access resources as their native Type.

One major advancement I’ve had a chance to use is the ComponentResourceManager. This class helps overcome many of the performance problems of the ResourceManager. Before in Visual Studio 7.0 (2002) and newer when you set the Localizable property to true for a Form, every property attributed with LocalizableAttribute(true) was added to the Form‘s ResX file and a call to ResourceManager.GetObject – along with a cast to the appropriate Type – was added to InitializeComponent.

The major drawback was that properties that you may or may not localize were using a lot of space in your primary assembly – the assembly that contains your embedded IL modules. The extra calls – while necessary to fully support localizability – cost a lot in terms of performance since the embedded .resources file must be parsed, cached, and objects must be cast, often times to value types (which requires unboxing, an expensive operation).

In Visual Studio 2005 performance and cost in terms of file size is improved thanks to the ComponentResourceManager, a derivative of the ResourceManager. The designer needs only to instantiate this class once using the type of the container you’re localizing – like a Form – and makes only a single call to ApplyResources for each component that requires localization. This method differs from many calls to GetObject because the ResX file needs to only store the resources to be localized, since ApplyResources enumerates all the resources for a particular control, and caches them for a particular culture.

The ComponentResourceManager class, however, is not new to the BCL. In fact it has been around since the .NET Framework 1.0 RTM. Visual Studio 2005 is the first to use it from the form designer.

To use the ComponentResourceManager in your class, you can use an existing Form of create a new Form. For brevity, I’ll assume you’re upgrading an existing Form. First change declaration of the ResourceManager to ComponentResourceManager and instantiate a new instance ComponentResourceManager in InitializeComponent.

private System.ComponentModel.ComponentResourceManager resources;
private void InitializeComponent()
this.resources = new System.ComponentModel.ComponentResourceManager(this.GetType());
// ...

Now for each component you want to localize add a call to ApplyResources passing the name of the component as well as the instance of the component itself.

this.resources.ApplyResources("textBox1", this.textBox1);
this.textBox1.Name = "textBox1";
this.resources.ApplyResources("button1", this.button1);
this.button1.Name = "button1";

When ApplyResources is called the .resources embedded resource matching the fully-qualified class name is loaded and parsed, enumerating all the property values. Each key in the .resources file that beings with objectName is matched against a property of the named object and assigned for you. Numerous calls to GetObject are no longer required and your application is still fully localizable.