|
Make the Best of .NET Resource Files
Drill down on some under-documented techniques for using resource files in your apps, and learn to customize these files for different customers.
by Francesco Balena and Giuseppe Dimauro
November 15, 2004
Technology Toolbox: VB.NET, C#
Relatively few .NET developers are familiar with resource files. After all, why should you bother storing a string in a resource file when you can simply type it in code or, at worst, load it from a text file or a database field?
The truth is, there are plenty of reasons for using resource files. First, they let you localize the application for different locales easily. Second, they let you customize the application (to an extent, at least) for different customers. And third, resource files enable you to change the user interface and some other features of an application without redeploying the actual executable.
Last month, we showed you how to store resources in the assembly's manifest—a technique that enables you to store files and images right in the executable so that the end user can't delete them accidentally. Manifest resources, however, don't offer all the benefits that separate resource files do.
Use Localizable Forms
Windows developers typically use resource files to create multilanguage applications. The problem with resource files is that they don't lend themselves well to the Rapid Application Development (RAD) approach. For example, prior to Visual Basic .NET, you could use only one language for the user interface. You could support additional languages only if you authored a resource file yourself, compiled it by running a command-line tool, and wrote the code that extracts each string or image. Fortunately, the Visual Studio .NET form designer solves this problem in a simple, elegant, and effective way.
Take, for example, a simple form that contains three strings and one image that should be localized (see Figure 1). In general, the localization process can involve more than simply changing the visible strings in the user interface or strings used from code. For example, you might need to move a control to a different location or make it invisible under some localized versions. At any rate, you should test your form thoroughly before you make it localizable because any change you make to its user interface afterward will require more coding and efforts.
The first step in localizing a form is to set its Localizable property to True. This property tells the designer's code generator that the values of the form and the controls' properties are to be loaded from a resource file instead of hard-coded in the source code.
Next, set the form's Language property to the alternative locale you want to support. This property is available only at design time, and you can assign any of the locales that .NET supports to it. The form designer continues to display the same user interface as before, but now you can change all the properties of the form and its controls (including their position, size, visibility, and so on). All the values that you set from now on are associated with the alternative locale just selected (see Figure 2 for how the form might look to an Italian end user). Of course, you can repeat this procedure with any language you want to support.
Visual Studio .NET's code generator performs this magic in conjunction with resource files. In fact, all the properties you use for the nondefault locales are stored in resource-only satellite DLLs named appname.resources.dll and in subdirectories under the application's main folder. (Each directory is named after one of the locales that your program manages—for example, it-IT for Italian resources.)
The code Visual Studio .NET generates inside a localizable form uses a ResourceManager object to read all the values assigned to the properties of the form and its controls. The ResourceManager object is aware of the current UI thread's locale and looks for a DLL stored in the relevant subdirectory. The ResourceManager uses the value stored in the main application if it doesn't find that DLL or doesn't find a given value in the DLL.
Back to top
|