sly 的个人资料Silverlight and Internat...照片日志列表 工具 帮助

日志


2008/6/27

Silverlight Marketization (Market Customization)

In this article I’ll explain how to use maketization (short for market customization) in Silverlight to reduce your loc costs and to enhance your application for particular market.

1.       What is marketization?

2.       What should be marketised?

3.       Silverlight Example

4.       Expandable UI

5.       Sample and source code

1. What is Marketization?

Marketization is under the Internationalization tree, it the ability to target a website or application to a particular market rather than simply a language. A language (eg: En = english) can shared in many countries and some countries speak more than one language each having a particalar market or culture (eg: fr-ca = french canada).

Of those familiar with developing sites for international markets, most are familiar with localization (translation of product UI) , but few use the implement the globalization process in full. If you do, you can greatly reduce your external translation costs and provide a more targeted user experience to all your users.

intltree

If you are not familiar with the .net localization process I strongly recommend you review .NET Internationalization and Developing International Software, both excellent books on the subject who explain the rest of these subjects better than I ever can.

It reduces loc costs by normalizing your international resources, strings, urls and settings so you only need to translate at the language level rather than down the many market level. Translations dont need to targeted at a paticalar market but they may have some small spelling differences (eg: colour & color) so the text should be translated in formal way and avoid local phares and terms. In .net we have a culture parent language fallback system to enable this eg:

fallback 

 

 

2. What should be marketized?

Website and product UI text translations and strings should all be in one localization strings resx file while the market resx file should contain

a)      Market Links/URLs

b)      Enabling market specific features settings

c)       Tracking and advertizing codes

d)      Branding

Generally the market resx will have a small fraction (1/10 - 1/3) of the elements that are in the strings file and it helps to be quite ruthless in the setting that are in your marketiztion settings resource file as it needs to configure for many more markets .

 piramid

 

3. Silverlight Example

In this example below we can display national sports of many countries and languages. You need to create 2 resource files and make them bind the UI text to strings resource file and market resx file to control the visibility of elements of the application per country. I wrapped the text in expandable grids that gracefully fit to meet the size of a translation.

A market picker ListBox is binded to the market list to dynamically refresh both the UI language and the culture of the application.

sportapp

4. Expandable UI

Please remember translation string lengths differ greatly per language and you don’t want to have fixed widths or the text can be clipped or overlapping other UI. It is always recommended for any international user controls to use stackpanels, wrappanels and autosizing grids for international text, as some languages are up 40% longer on average. Long text should allowed wrap (TextWrapping="Wrap") , and add scroll bars (ScrollViewer) as necessary. If UI absolutely cant be expanded then ellipses (...) converter function could be used to restrict the text size but this should be avoided if possible.

5.  Sample and Source Code

Updated code to 2.0 RTW.

Live Sample:  http://silverlight.services.live.com/invoke/6655/Marketization/iframe.html

Source code: http://cid-2b248d261d0e0035.skydrive.live.com/self.aspx/Public/marketization.zip

 

2008/6/21

Multi Langauge Silverlight 2.0 Application

In my previous example i showed you how you can create a localizable Silverlight 2.0 application for just two languages. In this article i’ll expand on this and explain how to

 

1.      Multi-language xap’s

2.      Change a user control language at runtime

3.      Using converters for placeholder substitution / replacement

4.      Demo and Code

 

 

1. Multi-language xap’s

 

If you have played with the SupportedLanguages in SL 2.0 Beta 2, you would quickly notice that if you try to implement multiple culture resx files only the first language ever loads. There is a issue in Beta 2 is that the resource assemblies dlls can’t have the same name, even if they in different folders.

NB: This will be fixed in RTW 2.0.

eg:

fr\silverlightapplication1.resources.dll

de\silverlightapplication1.resources.dll

 

For a workaround to those impatient folks out there, to overcome the single language resource loading issue. Here is a simple script you can create, to set this correctly at compile time, using the appmanifest.xml and VS post-build events.

NB: Remove any values from <SupportedCultures></SupportedCultures> in the *.csproj file

 

        i.          Update your Properties\AppManifest.xml to include your new language assembly dlls and click save eg:

<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Deployment.Parts>

   <AssemblyPart Source="SilverlightApplication1.de.resources.dll" />

   <AssemblyPart Source="SilverlightApplication1.fr.resources.dll" />

   <AssemblyPart Source="SilverlightApplication1.ja.resources.dll" />

</Deployment.Parts>

         </Deployment>

 

       ii.          Add a vb script to your project folder that enables you to add files to zip archive called AddFilestoZip.vbs with the following code, you could also use winzip or any other zip command software, as xap are simply a renamed zip file

 

Set objShell = CreateObject("Shell.Application")

Set objFolder = objShell.NameSpace(Wscript.arguments(0))

objFolder.CopyHere Wscript.arguments(1), &H10&

WScript.Sleep 500

 

      iii.          In Visual Studio project explorer right click on your Silverlight Application and select properties, click on the events tab and insert the following code into the Post-Build Events: Notice the culture list in bold in the batch for loop.

 

move "$(TargetDir)$(ProjectName).xap" "$(TargetDir)$(ProjectName).zip"

for %%i in (de fr ja) do (

move "$(TargetDir)%%i\$(ProjectName).resources.dll" "$(TargetDir)$(ProjectName).%%i.resources.dll"

cscript /nologo "$(SolutionDir)$(ProjectName)\addfiletozip.vbs" "$(TargetDir)$(ProjectName).zip" "$(TargetDir)$(ProjectName).%%i.resources.dll"

)

move "$(TargetDir)$(ProjectName).zip" "$(TargetDir)$(ProjectName).xap"

 

 

     iv.          Save and compile and you can see the strings load from the resource assembly for multiple cultures

 

 

2. Change a user control language at runtime

 

Surfers sometime want the update their user languages preferences inside the application at runtime rather having to restart the whole application. With asp.net or silverlight this is very easy, see sample below

 

            // Update the app Culture and UICulture

            System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("ja-jp");

            System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("ja-jp");

            Page page1 = new Page();  // Page is your user control xaml/class

            LayoutRoot.Children.Clear(); // remove old control

            LayoutRoot.Children.Add(page1); // re-add new control

 

3. Using a binding converter for placeholder substitution / replacement

 

 

In localization you often need to merge UI strings with DB data or other UI strings and because of the complexities of international grammar strings need to be in differing orders

 

Eg:

"The e-mail was sent successfully to {0}'s e-mail address."

"El e-mail fue enviado satisfactoriamente a la dirección e-mail de {0}"

 

To do this in asp.net or silverlight you can use String.Format, but with silverlight data binding we do this using a binding Converter to assist us.

 

In xaml you can use the following to replace String1

<TextBlock x:Name="String1" Text="{Binding String1, Converter={StaticResource StrReplace}, ConverterParameter='String2', Source={StaticResource LocStrings}}" />

public class PlaceholderSubstitution : IValueConverter {

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture){

return

String.Format((string)value, SilverlightApplication1.Resources.Resource1.ResourceManager.GetString(parameter.ToString(), System.Threading.Thread.CurrentThread.CurrentCulture));
}

 

public

object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{ throw new NotImplementedException("PlaceholderSubstitution does not use ConvertBack."); }

}

 

4. Demo and Code

 

Demo: http://silverlight.services.live.com/invoke/6655/LocSample/iframe.html

 

Soure code: http://cid-2b248d261d0e0035.skydrive.live.com/self.aspx/Public/SL-Multi-Loc.zip

2008/6/14

Creating a localizable Silverlight 2.0 Application

About
The sample below shows how you can bind language resources (resx) with praticllay no code, only markup.
 
Requirements
Visual Studio professional or greater plus the SL 2.0 SDK
 
Instuctions
 

1.       Open Visual Studio

2.       Click File \ New Project...

3.       Select Visual C# \ Silverlight \ Silverlight Application

4.       In the name field type SL_Loc_Sample

5.       Click ok and ok

6.       In the Project Explorer

7.       Right click on the SL_Loc_Sample (c# Icon) Project

8.       Click Add \ New Folder

9.       Name it Resources

10.   Right click on Resources folder and click add New Item...

11.   Select Resources File

12.   Name it Strings.resx and click ok

13.   Open the new created Strings.resx

14.   In the Access Modifier: dropdown select Public

15.   In the Name Field type tb1 and value “tb1 in english”

16.   Repeat with Name Field type tb2 and value “tb2 in english”

17.   In the file Strings.Designer.cs change “internal Strings() {“ to “public Strings() {” Note:  Every time you change the strings.resx you update this reference i hope this gets fixed in the RTM verion

18.   Click Save, press F5 and add debugging to web.config

19.   IE opens up with a blank page

20.   Close IE

21.   Open Page.xaml in xaml editor window

22.   In the user control add a new xml namespace xmlns:Loc="clr-namespace:SL_Loc_Sample.Resources"

23.   Add a locstrings as a  resource to your page eg: <UserControl.Resources><Loc:Strings x:Name="LocStrings" /></UserControl.Resources>

24.   Inside the grid add a Textblock and bind it to your resource Tb1 eg: <TextBlock Text="{Binding tb1, Source={StaticResource LocStrings}}" />

25.   The String should appear in the Design view above

26.   Wrap the textblock inside a vertical stackpanel  and add a second Textkblock

        <StackPanel Orientation="Vertical">

           <TextBlock Text="{Binding tb1, Source={StaticResource LocStrings}}" />

           <TextBlock Text="{Binding tb2, Source={StaticResource LocStrings}}" />

        </StackPanel>  

27.   In Project Explorer right click on Strings.resx and copy and paste it into the resources folder

28.   Rename “Copy of Strings.resx” to “Strings.de.resx” (DE is the two letter language code for German)

29.   Open Strings.de.resx Edit the value to “tb1 auf deutsch” and “tb2 auf deutsch”

30.   Click Save, press F5

31.   Notice the file %HOMEPATH%\Documents\Visual Studio 2008\Projects\SL_Loc_Sample\bin\debug\de\SL_Loc_Sample.resources.dll appears but is not embedded in your xap yet

32.   To add that market to your xap you must open the .csproj in notepad  (ugly workaround until SL2.0 tools RTW)

33.   Update SupportedCultures to <SupportedCultures>de</SupportedCultures>

34.   Save and close

35.   VS 2008 will ask you to reload project, click reload

36.   Next we need to update the SL browser object reference

37.   Id recommend you delete the SL_Loc_SampleTestPage.aspx and set SL_Loc_SampleTestPage.html as your start page

38. In SL_Loc_SampleTestPage.html  Add the culture and uiculture params to your object

<object data="data:application/x-silverlight," type="application/x-silverlight-2-b2" width="100%" height="100%">

            <param name="source"v value="ClientBin/SL_Loc_Sample.xap"/>

            <param name="onerror" value="onSilverlightError" />

            <param name="background" value="white" />

            <param name="culture" value="de" />

            <param name="uiculture" value="de" />

      </object>

39.   Click Save, press F5

40.  IE should open up with the German strings

  SLLoc

 

Code:

http://cid-289eaf995528b9fd.skydrive.live.com/self.aspx/Public/SL%7C_Loc%7C_Sample.zip

 

Links:

http://silverlight.net/forums/p/17678/58967.aspx

http://blogs.msdn.com/webdevtools/archive/2008/06/10/localizing-a-silverlight-application.aspx