Description:
I have may string constants in my code. Usually, they are messages for the end-user. Now I need to create a localized version of my application, but it seems to be difficult to do this, since user messages are hard-coded. I don't know where and how to define message constants for a specific language. Perhaps, you can suggest the best approach for this task…
Answer:
We think that it's best to use the standard model for localization. First you should separate the localizable resources from your code to ensure the localizability of your application.
Stage 1: Localizability
You can use the same approach as we used in our controls: create a Localizer class with a method for loading strings from the assembly resource. When the strings are stored in the resource and loaded via the ResourceManager class, you can localize them by using the hub and spoke model explained in the MSDN Library.
Here is the code for your Localizer class.
C#using System;
using System.Resources;
namespace MyApp {
public class Localizer {
ResourceManager manager;
static Localizer localizer = new Localizer();
private Localizer() {
manager = new ResourceManager("MyApp.UserMessages", this.GetType().Assembly);
}
public static string GetString(StringId id) {
string ret = localizer.manager.GetString(id.ToString());
if(ret == null)
throw new Exception(string.Format("The localized string for {0} is not found", id));
return ret;
}
}
public enum StringId {
MsgGreeting,
... // other IDs
}
}
Visual BasicImports System.Resources
Public Class Localizer
Private manager As ResourceManager
Shared localizer As Localizer = New Localizer
Private Sub New()
manager = New ResourceManager("MyApp.UserMessages", Me.GetType().Assembly)
End Sub
Public Shared Function GetString(ByVal id As StringId) As String
Dim ret As String = localizer.manager.GetString(id.ToString())
If ret Is Nothing Then
Throw New Exception(String.Format("The localized string for {0} is not found", id))
End If
Return ret
End Function
End Class
Public Enum StringId
MsgGreeting
...
End Enum
The first parameter in the ResourceManager constructor is the resource name in the assembly manifest. If the resource file is located in the root directory of your project, the first parameter is the project default namespace + the resource file name without the extension (MyApp + UserMessages in our example).
As you can see, the strings' IDs are defined by the StringId enumerator.
To add a new resource string:
- Add a new item to the StringId enumerator.
- Add the desired string to your resource file (UserMessages.resx in our example).
Then you can use the following simple code to get the resource string:
C#// usage
string msg = Localizer.GetString(StringId.MsgGreeting);
MessageBox.Show(msg);
Visual Basic' usage
Dim msg As String = Localizer.GetString(StringId.MsgGreeting)
MessageBox.Show(msg)
Stage 2: Localization
Let's assume that you need to translate your strings into a different language. All you need to do is:
- Make a copy of the UserMessages.resx file, add the culture name to the file name and translate the strings.
- Rebuild your application. The satellite assembly will be automatically created in your project's bin folder.
See Also:
Developing World-Ready Applications Overview in the MSDN Library
How to translate components via their Localizer objects
The collection of localized DevExpress assemblies