

Introduction
Apart from the default language of the application (generally English), your software should support different languages since people prefer using software with a native language interface. For the worldwide distribution of an application, you need to translate the user interface to as many languages as possible. When you do that, you can say the application is Globalized.
The first step to globalize an application is setting the Localizable property of the Windows Form to true. When you create a Forms based Windows application, there is a resource (.resx) file associated with each form. This resource file is specific to a language which contains all locale specific details of that form.
In this article, we will discuss how to generate a different language resource file from the default English resource file.
Background
I have posted an article on Globalization/Internationalization too. Before reading this article, please read: Globalization, Internationalization (I18N), and Localization using C# and .NET 2.0.
Using the Code
The text translation is based on the translation provided by the Google Translator website (http://translate.google.com).
Although the Google Translator API classes are available here, you can refer to the source file attached to this article. These APIs will work perfectly as long as the interface or the format of the Google Translator website will not change.
Here, we have the Translator class which basically uses the Google Translator API to translate the text. Create an instance of the TranslateClient class and call the Translate method with the appropriate parameters.
public static string Translate(Language targetLanguage, string text)
{
TranslateClient client = new TranslateClient("www.google.co.in");
string translatedValue =
client.Translate(text, Language.English, targetLanguage);
Trace.WriteLine(string.Format("Given Text is {0} " +
"and Target Language is {1}. Result - {2}.",
text, targetLanguage.Name, translatedValue));
return translatedValue;
}
Once the given text is translated in the target language, the only work left is creating a .resx file and adding the text into that file. The code given below performs this task:
public static void Write(Language targetLanguage,
string resxFilePath, bool onlyTextStrings)
{
if (string.IsNullOrEmpty(resxFilePath))
{
throw new ArgumentNullException(resxFilePath,
"Resx file path cannot be null or empty");
}
if (targetLanguage == null)
{
throw new ArgumentNullException(targetLanguage,
"Target Language cannot be null");
}
using (ResXResourceReader resourceReader = new ResXResourceReader(resxFilePath))
{
string locale = targetLanguage.Value.ToLower();
#region Create locale specific directory.
locale);
#endregion
string outputFilePath = Path.GetDirectoryName(resxFilePath);
string outputFileName = Path.GetFileNameWithoutExtension(resxFilePath);
outputFileName += "." + locale + ".resx";
outputFilePath = Path.Combine(outputFilePath, outputFileName);
using (ResXResourceWriter resourceWriter = new ResXResourceWriter(outputFilePath))
{
foreach (DictionaryEntry entry in resourceReader)
{
string key = entry.Key as string;
if (!String.IsNullOrEmpty(key))
{
if (onlyTextStrings)
{
if (!key.EndsWith(".Text"))
{
continue;
}
}
string value = entry.Value as string;
if (!String.IsNullOrEmpty(value))
{
string translatedValue = Translator.Translate(targetLanguage,
value);
resourceWriter.AddResource(key, translatedValue);
}
}
}
resourceWriter.Generate();
}
}
}
Since the text translation happens at the Google website, it takes time to fetch the text and get the translated text. I have used the BackgroundWorker class to do this job. The BackgroundWorker initiates the process by Binding the channel and then sending and receiving the text with the specified languages.
The BackgroundWorker class allows you to run an operation on a separate, dedicated thread. Time-consuming operations like downloads and database transactions can cause your user interface (UI) to seem as though it has stopped responding while they are running. When you want a responsive UI and you are faced with long delays associated with such operations, the BackgroundWorker class provides a convenient solution.
private void myStartButton_Click(object sender, EventArgs e)
{
*
*
myBackgroundWorker.RunWorkerAsync(languages);
*
*
}
void myBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
Language[] languages = e.Argument as Language[];
PerformTranslation(languages, worker, e, myOnlyTextCheckBox.Checked);
}
Once you hit the Start Translation button on the UI, the BackgroundWorker starts the text translation. In case you want to abort the background process, call the CancelAsync() method and then check for the CancellationPending flag on the BackgoundWorker instance, and set DoWorkEventArgs - e.Cancel to true.
private void PerformTranslation(Language[] languages,
BackgroundWorker worker, DoWorkEventArgs e, bool onlyTextStrings)
{
int totalProgress = 0;
foreach (string file in mySelectedFiles)
{
foreach (Language targetLanguage in languages)
{
if (worker.CancellationPending)
{
e.Cancel = true;
}
else
{
ResxWriter.Write(targetLanguage, file, onlyTextStrings);
totalProgress++;
worker.ReportProgress(totalProgress);
}
}
}
}
There could be two types of .resx files. When you set the Localizable property to true, the entire information of the form (specific to a locale) is moved to the .resx file, including location, size, etc. This is an auto generated resource file which contains the entries other than the UI text strings. Another option could be a user defined resource file, which contains only strings.
In the Resx Translator application UI, you can select the 'Convert only .Text key' checkbox in order to convert only strings of the auto generated .resx files. Translating entries other than strings can cause some serious errors. In the case of the user defined resource file, you can leave this option.
There are two components in this application - the Translator and the Config UIs. In the Translator UI, you can browse and select the .resx files. In the Config UI, you can select the languages in which you want to translate your English .resx files.
Once the translation starts, the progress bar and the status bar will indicate the whole process. Hope this tool will help you to generate resource files in different languages. ;)
Points of Interest
Keep an eye on the Google Translator API website if this application stops translating the text. Download the latest GoogleTranslatorAPI.dll and then run this application.
History
- 08/02/2010 - Added details of APIs.
- 04/02/2010 - Uploaded source code.
- 04/02/2010 - Initial post.