Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A .NET Component for Localizing String and Message Boxes

0.00/5 (No votes)
4 Mar 2010 3  
Managing strings contained in a project-scoped resource file can be a real pain. This component makes it easier to colocate the strings with their corresponding classes, even if they are business objects.

Introduction

Localization has become an important feature of many modern applications. In .NET, resource files and the Windows Forms Designer make localization of UI components straightforward, however, there are certain shortcomings. The code included in this article addresses some of the deficiencies, namely localization of string values and message boxes.

Background

Developers hate tedium. If following proper globalization practices is onerous, the developer simply will not adhere to the practice. They will instead embed their strings in the code and (if you're lucky) put a "TODO: Localize" at the top of a file and move on.

Declaring strings (or other resources) in source code is a very bad practice. Hunting down resources in source code is no fun and expressly prohibits software from being localized after it is originally built. Externalizing resources is key to being able to localize applications and is the technique used in this article.

Platform

The included code requires Visual Studio 2008 and targets .NET v2.0.

Usage

The LocalizableContent is a component that can be dragged and dropped from the Visual Studio Toolbox onto any Component, e.g. a UserControl a Form, or even a custom business object. It contains collections of messages and message boxes whose content is externalized to resource files.

Once an instance has been dropped to the component tray, localizable messages or message boxes can be added by using the context menu.

Newly added content automatically becomes selected in the Properties and Document Outline panes. Once selected, various editable properties can be modified.

Note that LocalizableMessageBox.Text or LocalizableMessage.Value can be a format string. If a format string, the arguments are provided when calling LocalizableMessageBox.Show, otherwise, Show can be called with no additional parameters (besides the owning handle).

Gotchas

Just like all components, unless the Localizable property of the class that contains the LocalizableContent is set to true, resources will be embedded in the Designer.cs file as opposed to the .resx file!

Originally, the LocalizableMessageBox and LocalizableMessage supported a preview feature. This feature is currently unavailable. Adding [DesignTimeVisible(false)] to the components preclude such functionality. I found that since component trays can become cluttered, it is more desirable to group the content under a single component tray item (hence the creation of LocalizableContent), so the preview functionality is currently suppressed as you cannot get the context menu that supports it.

Points of Interest

MessageBoxType was required. System.Windows.Forms.MessageBoxIcon does not display properly in a property grid (presumably it has duplicate underlying literal values). Adding my own enumeration, while at first undesirable, does have the advantage of reducing the number of options the developer has to choose from. I never liked selecting from MessageBoxIcon; I find the documentation confusing and don't see the need for more than 3 types, Info, Warning, and Error. This seems better than having to decide if you should use Stop/Error/Hand, or Warning/Exclamation.

The classes in LocalizationUtilities.Design have some interesting aspects. It has code to make GenerateMember default to false (LocalizableContent exposes no useful programmatic functionality). Additionally, there is code to adhere to a preferred naming convention (prefix fields with a '_').

Commentary

Some may object to a business class being edited like a UI element. In the included code, MyBusinessObject represents a business object, yet its localizable content can be edited in the designer. Deriving from Component grants this privilege. I do not take objection to this -- it seems fairly lightweight and provides various opt-out capabilities, for example, applying the ToolboxItem attribute suppresses display in the Visual Studio Toolbox.

History

  • Feb 2010: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here