June 2013
M T W T F S S
« Aug    
 12
3456789
10111213141516
17181920212223
24252627282930

Categories

.NET Internationalization Programming – Resource Administration (Form, WPF, Silverlight)

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.



ASP.NET Internationalization Programming – Resource Administration

The following are extracts from ASP.NET Internationalization of Software Internationalization Tool World Wide Navi‘s Internationalization Programming Advisory Info.

ASP.NET uses resx resources (About resx, see Resource Administration, .NET chapter) for internationalization in some different ways from C# and other .NET programming languages.

This page describes its unique points with World Wide Navi string externalization samples.

1. Adding headers in ASPX

Add culture (language and region) settings to ASPX header area.

Default.aspx

  <%@ Page  Language="C#" ...%>
=><%@ Page  Culture="auto"
UICulture="auto" Language="C#" ...%>

2. String Externalization (literal replacement)

ASP.NET has 4 syntaxes for string resource handling.

  • Syntax 1 needs ‘<%=..%>’.
  • ‘”‘ are truncated in Syntax 2.
  • Syntax 3 is very similar to syntax 1, but some different.
  • The default text can remain adding meta in Syntax 4.
  • Syntax 3 & 4 can be used for ASP tags only.
Default.aspx

* Syntax 1. (tag text replacement)
 '<%=' + 'Resources.Default.' + RESOURCE_KEY + '%>'
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>This is a sample site!</title>
 => <title><%=Resources.Default.
DefaultWwnaviMsg1%></title>
</head>
<body>

* Syntax 2. (program literal replacement)
'Resources.Default.' + RESOURCE_KEY
<div>
    <% Response.Write("Hello, World!"); %>
 => <% Response.Write(Resources.
Default.DefaultWwnaviMsg2); %>
</div> 

* Syntax 3. (text replacement in ASP tag)
 '<%$' + 'Resources.Default,' + RESOURCE_KEY + '%>'
<asp:Label ID="Label1" runat="server"
Text="This is label 1.">
=><asp:Label ID="Label1" runat="server"
Text="<%$Resources:Default,
DefaultWwnaviMsg3%>">
</asp:Label>

* Syntax 4. (meta insertion in ASP tag)
 'meta:resourcekey="' + RESOURCE_KEY + '"'
<asp:Label ID="Label1" runat="server"
Text="This is label 1.">
=><asp:Label ID="Label2" runat="server"
 Text="This is label 1."
meta:resourcekey="DefaultWwnaviMsg4" >
</asp:Label>

You need to use proper process for each string based on its location.

(You can choose either 3 or 4 in ASP tags.)

3. Creating Resx Files

Put externalized strings into resx (resource) files.You need to create ‘App_GlobalResources’ folder under your project directory and put resx files there named ‘ASPX_FILE_NAME(without extension).resx’(*1).

PROJECT_DIRECTORY
    -  App_GlobalResources
         -  Default.resx
         -  WebForm1.resx
         *1)If you use syntax 4 (meta attribute),
           you heed to add extension
           (Default.aspx.resx).
Default.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="DefaultWwnaviMsg1" xml:space="preserve">
     (RESOURCE_KEY)
    <value>This is a sample site!</value>
     (RESOURCE_STRING)
  </data>
</root>

4. Compiling and localization

Build and run, you will see the resource strings shown in browser.If you want to add other language resources, put ASPX_FILE_NAME.LOCALE_CODE(e.g. ‘ja’).resx in App_GlobalResources.

App_GlobalResources
  -  Default.resx
    ... master resource (e.g. English)
  -  Default.ja.resx
    ... localized resource (e.g. Japanese)