Localize Your .NET Windows Forms Apps
It's a small world. For the price of a nice pair of shoes, you can get on a plane, have dinner, watch a movie, sleep a few hours, and wake up on another continent. Your software can travel even more easily. When it gets there, will it be ready to go to work?
You never know when your software might be used by people who speak different languages. In a multinational company, branch offices need to share database applications. By localizing your product, you can enormously increase its potential market. In addition, letting people work in the language in which they're most comfortable increases productivity, reduces errors, and shows respect for their culture.
The trick to translating GUI elements is that you have to base translations on the initial caption, not on whatever's currently on the screen. Thus you have to save the original captions that are on the screen when it loads.
But how do you make it so? The .NET documentation recommends that you use resource files. Behind each form, there's a .res file that can be used to store the strings that appear on the form, where you can put corresponding translations into other languages. The following excerpt from the .NET documentation describes how you use them:
"You can localize your application's resources for specific cultures. This allows you to build localized (translated) versions of your applications. An application loads the appropriate localized resources based on the value of the CultureInfo.CurrentUI-Culture property. This value is set either explicitly in the application's code or by the common language runtime based on the locale for the current user on the local computer."
In a nutshell, Microsoft recommends that you create satellite assemblies of resource files, one per culture. Setting or changing the CurrentUICulture setting changes the satellite assembly, and your translations appear.
Unfortunately, that's not always the best way to do it. Res files make more sense in ASP.NET. But in the case of Windows Forms applications, if you use res files, you have to make any required changes to them, which means that:
- You're responsible for the translations; if your users don't like your choice of terms, it's a technical support issue;
- Different countries that speak the same language use different words for the same thing; computadora, ordenador and PC are three Spanish translations for "computer";
- Users have to wait for a new res file in order to get their screens fixed.
I appreciate Microsoft's efforts; especially since localization has been one of my favorite topics for many years (I speak five languages, and worked my way through grad school as a simultaneous interpreter.) However, the res file approach doesn't really put responsibility for the maintenance of the translated captions in the hands of the users, where it belongs.
This article will demonstrate a simpler mechanism for creating localized apps. I'll show you how to build a class that stores all translatable captions from screen and menu objects in a collection within each screen. When the user changes the screen language using a "Language" combobox on a screen, the SelectedIndexChanged event code looks up and replaces the original captions with their translations. Finally, I'll show you how to provide a Translation Table Manager to let users provide translations for all captions harvested from the screens in the application. The examples in this article are in Visual Basic .NET, but the downloadable source code is available in C# as well.
Table 1 shows the three tables I'll use in this implementation.
You can use the Server Explorer to create the Translations database, and then create the three tables described above. If you have SQL Server Developer Edition, you can also use either the Enterprise Manager or the Query Analyzer. You can also use an Access MDB file or FoxPro tables. The application works with all three data sources.
The Languages table contains the list of supported languages. The Original table contains all of the strings found on all of your application's screens. The Translated table contains one entry for each translation of each of the strings in the Original table for each supported language. If an entry hasn't yet been translated, it doesn't have an entry in the Translated table.
By: Les Pinter
Les Pinter is a Visual Basic MVP specializing in database application development, software localization, and migration of applications to .NET. His latest book, VFP to VB .NET (Sams), came out in May, and will be published in Spanish in January by McGraw-Hill Interamericana in Mexico City.
Les is a member of the INETA Speakers Bureau, and gives talks on .NET in English, French, Spanish, Russian, and Portuguese. He lives with his Taiwanese wife Ying-Ying in San Mateo, California.
Putting translation into the hands of your users places the responsibility for accurate translation where it belongs. You can either centralize the translations, or let each user customize them.