The following are extracts from .NET Internationalization of Software Internationalization Tool World Wide Navi‘s Internationalization Programming Advisory Info.
We described WPF & Silverlight localization with our localization tool Sisulizer that enables Binary File Localization wihout XAML edit.
1. Create ResourceManager
Create a instance of ResourceManager in the initial method (‘Main’ or ‘InitializeComponent’).The following are sample codes of World Wide Navi.
WwnaviResource.cs
namespace Wwnavi {
using System;
public class Resource {
public static void Init(){
// Set the user interface
to display in the same culture as that set in Control Panel.
System.Threading.Thread.CurrentThread.
CurrentUICulture =
System.Threading.Thread.
CurrentThread.CurrentCulture;
// (*This is a important
code to reflect the regional and language
settings of Control Panel.)
// Assembly
wwnaviRs(*1) = new System.Resources.
ResourceManager(
"WindowsFormsApplication.(
Properties.)wwnavi_string",
(*'Properties' needed only in
C# projects of 2005 or later)
System.Reflection.Assembly.
GetExecutingAssembly());
// File Based
// wwnaviRs = System.Resources.
ResourceManager.
// CreateFileBasedResourceManager(
// "WindowsFormsApplication.
wwnavi_string",
// "./",null);
}
public static String GetString(String id){
if (wwnaviRs == null) Init(); *3)
return wwnaviRs.GetString(id);
}
public static System.Resources.ResourceManager
GetResourceManager(){
return wwnaviRs;
}
private static System.Resources.
ResourceManager wwnaviRs = null;
};
}
*1)wwnaviRs … RsourceManager instance
This sample creates ‘Assembly’ RsourceManager
which reads embedded resource or satellite DLLs.
The second commented out codes is ‘FileBased’ RsourceManager
which always reads .resources files
static void Main()
{
Wwnavi.Resource.Init(); *2)
...
}
*2)Calling the ResourceManager creation process of the *1) above.
*ResourceManager creation is better to be done in the initial method, but not necessary.
The codes *3) is calling ‘Init’ if the ResourceManager has not been created before returning reousrce data, this is for kinds of projects with no initial methods such as class libraries .etc.
In the case of Form application, ‘Init’ need to be called at the beginning of Main function, before InitializeComponent() called.
[STAThread]
static void Main()
{
// You need to set System.
Threading.Thread.CurrentThread.
CurrentUICulture first.
Wwnavi.Resource.Init();
In Visual Basic, the beginning of Sub New().
For WPF and Silverlight, refer to Here.
2. Embed string getting codes
Get the string from the resx file with the method ‘ResourceManager.GetString’.
MessageBox.Show(Wwnavi.Resource.
GetString("wwnavi.Msg.Id1")...
WwnaviResource.cs
...
public static String GetString(String id){
...
return wwnaviRs.GetString(id);
}
3. Write strings in resx file
Write stirngs with message id in the following element of the resx file.This file name needs to be corresponding to ResourceManager creation method(see the 1-*1 above, “WindowsFormsApplication.(Properties.)wwnavi_string”),so needs to be ‘wwnavi_string.resx’ in this case.
*For Visual Studio addin implementation, you need to use the name “resources”.
(e.g. ResourceManager “MyAddin.resources”, resx file “resources.resx”)
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
...
</xsd:schema>
...
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="wwnavi.Msg.Id1" xml:space="preserve">
*1)
<value>Hello, how are you? This is a sample.</value>
</data>
</root>
*1)You need to write the string in the element ‘data’.
“wwnavi.Msg.Id1″ is corresponding to the message id of ‘GetString’.
4. Compile and locate the resource file
If you are creating .NET application in Visual Studio (C# project, VC++ CLR project …etc.), you can use ‘automatic internationalized process’.The steps are below.
1. Set component properties. Set the following properties in form designer view. Form.Localizable = true Form.Language = Default (Label.AutoSize = true) 2. Add the resx file into the project. Add the resx file (e.g. 'wwnavi_string.resx' above) into your project. If you are using VC++ projects, add it under the project directory, if C# project of 2005 or later, add it into the directory 'Properties' with drag and drop. (World Wide Navi does these steps automatically.) project- Form1.h (or .cs) <- *set Localizable true Form1.resx <- *created by Visual Studio wwnavi_string.resx or Properties/ wwnavi_string.resx (C# only) 3. Rebuild the solution. Rebuild your solution and generate the executable. In these steps, the resources (Visual Studio resource 'Form1.resx' and your resource 'wwnavi_string.resx') are embedded in the executable as default one, so no DLLs are created. Debug/Release- WindowsFormApplication.exe <- *containing the resource of Form1.resx and wwnavi_string.resx 4. Add other language resources. If you add other language resources into your project, Visual Studio creates satellite DLLs automatically. For example, when you copy the Form1.resx and wwnavi_string.resx into Japanese translated resources (named '*.ja.resx') and add them into your project and rebuild, the Japansese resource DLL gets created automatically. project- Form1.h (or .cs) <- *set Localizable true Form1.resx <- *created by Visual Studio Form1.ja.resx <- *copied and translated by you *3) wwnavi_string.resx wwnavi_string.ja.resx <- *copied and translated by you Properties/wwnavi_string.resx (C# only) /wwnavi_string.ja.resx (C# only) *3)Form1.ja.resx can also be created automatically by Visual Studio, setting Form.Language 'ja' in form designer view. Debug/Release- WindowsFormApplication.exe <- *containing the resource of Form1.resx and wwnavi_string.resx ja/WindowsFormApplication.resources.dll <- *containing the resource of Form1.ja.resx and wwnavi_string.ja.resx === CAUTION === These steps are available only when you use a 'Assembly' ResourceManager. If you create a 'FileBased' manager, you have to copy the .resources file to your running directory manually and need to always attach them to your executable.
Cases of WPF And Silverlight
WPF standalone application and Silverlight have different ways to set UI locale.
Case Of WPF Standalone Application:
By Default, the function Main is automatically generated and UICulture cannot be set, so you have to write your own Main class and turn off automatic Main generation.
1. Set 'Build Action' 'Page' in App.xaml properties. 2.Create the following class for Main function and call Wwnavi.Resource.Init() (setting CurrentUICulture). using System; using System.Collections.Generic; namespace Wwnavi{ class TempMain{ [STAThread] static public void Main(string[] args) { Wwnavi.Resource.Init(); // Setting CurrentUICulture YOUR_APP_NAME.App app = new YOUR_APP_NAME.App(); // YOUR_APP_NAME is your application name (e.g. WpfApplication1) app.InitializeComponent(); app.Run(); } } } 3.Finally, build and check if it's successful. *Each language dll can be easily created by Sisulizer without XAML editing. YOUR_PROJECT_PATH/bin/Debug/WpfApplication1.exe ja/WpfApplication1.resources.dll (*Japanese dll created by Sisulizer) For details about Sisulizer, refer to World Wide Navi Help.
Case Of Silverlight:
The normal way in Siliverlight is to detect the user locale (language) in loading pages (HTML, ASP, PHP, etc.) and give them to Silverlight as parameters and load suitable xap files (Siliverlight objects).
The following is a sample of World Wide Navi using Visual Studio test ASP modified.
SilverlightApplication1TestPage.aspx
...
<%--
//// These are Silverlight i18n/l10n part. ////
--%>
<script runat="server">
// Get the current locale.
// Get user language info
from HTTP requests.
string sLang = System.Web.HttpContext.
Current.Request.UserLanguages[0];
string sPath = System.Web.HttpContext.
Current.Request.UserLanguages[0];
string root = System.Web.HttpContext.
Current.Server.MapPath("/ClientBin/");
</script>
<%
// Set Silverlight file (xap) path.
// Create a xap file path suitable
for the user language.
// ClientBin/SilverlightApplication1.xap
... Default xap
// ClientBin/ja
/SilverlightApplication1.xap ... Japanese xap
// ClientBin/ko
/SilverlightApplication1.xap ... Korean xap
// *Each language xap can be easily created by
Sisulizer without XAML editing.
// For details about Sisulizer, refer to
World Wide Navi Help.
if (!System.IO.Directory.Exists(root + sPath))
{
if (sPath.Length > 2)
sPath = sPath.Substring(0, 2);
}
if (!System.IO.Directory.
Exists(root + sPath))
{
sPath = "";
}
if (sPath != "") sPath = sPath + "/";
%>
...
<object data="data:application/x-silverlight-2,"
type="application/x-silverlight-2"
width="100%" height="100%">
<%--
Switch xap files to load on the current locale.
These are directly localized files by Sisulizer WITHOUT XAML sources.
--%>
<param name="source"
value="ClientBin/
<%=sPath %>SilverlightApplication1.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="3.0.40624.0" />
<param name="autoUpgrade" value="true" />
<%--
Set the current locale to the Silverlight code.
--%>
<param name="uiculture"
value="<%=sLang %>" />
<param name="culture"
value="<%=sLang %>" />
// These two parameters are
taken to Silverlight object cultures.
*For debugging, right-click this ASP and execute [Show In Browser] menu instead of using debug menu in Visual Studio.

Recent Comments