sly's profileSilverlight and Internat...PhotosBlogLists Tools Help

Blog


    8/22/2009

    Binding to Server based Resx Files in Silverlight 3

     

    In Silverlight you can easily bind to compiled resx files, and the translations are baked into your xap as resourse dlls. In the majority of cases this is fine, as translations don’t change very often unless the UI changes which mean re-translation and redeploying anyway.

    Editorial Content

    If you have content, that needs to be changed frequently, you should use RIA Services or WCF that binds some editorial section that is not locked in your regular UI strings. Examples of this would be : Special Offers, promotions etc…. The translator would update your Content Management System and translate a default English text or promote something specific to that market. Eg: NFL tickets for US and Rugby Tickets for France. Then your RIA or WCF would poll this content from your CMS system each time your Silverlight application page loads for that market. This way the core translations are still baked into app but you have flexibility, to update certain parts of the UI dynamically. Code for this is pretty standard RIA services and is out of scope for this article. I may post a sample if people are interested.

    Server based Resx

    Under some circumstances a mixture of core UI and editorial content is not flexible enough. You may not want all your translation compiled into one mega xap or use MEF for dynamic resource loading, but keep them uncompiled on the server side until user requests a different language. In the example project below, I use a English resx with no code generation and stored as static resource. When the page loads it reads the local resx in the xap and creates strongly typed dynamic object of the dictionary using reflection. We wrap this in the LocStrings class that implements inotifypropertychanged interface to allow dynamic loc string binding.

    When the user selects a different culture in the dropdown the we make a request to the server get the resx. We then set the contents to LocStrings and update the thread culture.

    Possible uses include:

    -        Reuse translations from your aspx site

    -        Add new languages dynamically

    ViewBox in Localization

    In reading a SVG localization article I noticed developers sometime need some way to update fontsize based on the character length of a translation in some . Part of the Silverlight Toolkit contains a control called viewbox. A viewbox in WPF or Silverlight is a layout control that scale transforms it contents to fit the dimensions of it container. This should be used sparing and instead you grid that expands to the size on the content and translations using Textwrapping and scrollviewers.


     

    Code: http://cid-289eaf995528b9fd.skydrive.live.com/self.aspx/Public/ServerResx.zip

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

    7/14/2009

    Silverlight 3 Intl Improvements

    As you aware by now Silverlight 3 is now available on http://microsoft.com/silverlight

     

    Below is a list of international features that have seen updated in this release.

     

    1. Comprehensive documentation on localization : http://msdn.microsoft.com/en-us/library/cc838238(VS.95).aspx

    2. Local Font support including Cambria and Segoe UI http://msdn.microsoft.com/en-us/library/dd547542(VS.95).aspx 

    3. ClearType support (Tip: Greatly improved but use native resolution)

    4. Merged Dictionary Support

    5. Element to Element Binding

    6. Bug fixs - Improved support for asian cultures on XP, thai input issue

     

    Im still waiting patiently for the localized runtimes and tools but that is generally very quick after the main launch.

     

    Anyway below is a sample enables updating UI strings in realtime without re-starting your application.

     

    This uses a singleton class to the PublicResxFileCodeGenerator that implements iNotifyProperyChanged

     

    public class LocStrings :INotifyPropertyChanged

        {

            // INotifyPropertyChanged plumbing

            public event PropertyChangedEventHandler PropertyChanged;

            private void NotifyChange(String name)

            {

                if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name));

            }

            //public constructor

            public LocStrings()

               {

               }

            // PublicResXFileCodeGenerator

            private static loc.Strings lStrings = new loc.Strings();

            public loc.Strings LStrings {

                 get {  return lStrings; }

                 set {  NotifyChange("LStrings");}

             }       

        }

     

    private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)

            {

                ComboBox langddl = sender as ComboBox;

                string selectedLang = (langddl.SelectedItem as ComboBoxItem).Content.ToString(); ;

                Thread.CurrentThread.CurrentCulture = new CultureInfo(selectedLang);

                Thread.CurrentThread.CurrentUICulture = new CultureInfo(selectedLang);

                ((LocStrings)this.Resources["LStrings"]).LStrings = new SL3Loc.loc.Strings();

            }

     

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

    Code: http://cid-2b248d261d0e0035.skydrive.live.com/self.aspx/Public/SL3Loc.zip

     

    BTW: SilverlightRTL updated their excellent code to work on SL3 http://blogs.microsoft.co.il/blogs/alex_golesh/archive/2009/07/10/silverlight-3-hebrew-and-arabic-support.aspx

     

    11/16/2008

    LocWebService: Only download resources per UserControl

    1. Introduction
    2. UserControl local resources configuration
    3. WCF Service
    4. Code

     

    1. Introduction

    In this sample I will show how bind text elements that load localization resources from the server side resx file via a WCF service in silverlight 2.0.

    Advantages:

    1. Only download resources per usercontrol
    2. Remove the need for custom resx code generators locally
    3. Local binding in design mode to english or your source language

    Disadvantages:

    1. UserControl are slower to load (wait for WCF response before displaying)

     

    2. UserControl local resources configuration

    I first created two helper class's to assist in design time binding called LocItem and LocCollection

    LocItem implements the INotifyPropertyChanged class and contains two properties ItemName and ItemValue. This will enable us to dynamically update a localizable string at runtime. We then need to a LocItem for every localizable string we add it to our UserControl Resources  per control or page.

    LocCollection is another helper class based from Silverlight Control Toolkit ObjectCollection This is a enumerable collection of our loc strings on a page, that get over the limitation that ResourceDictionary does not implement iEnumerable.

    Both these are instantiated in markup and then bound to your localizable element.

    <UserControl.Resources>
            <Loc:LocItem ItemName="tb1" ItemValue="tb1" x:Key="LocItem1" />

    <Loc:LocCollection x:Key="LStrings" >
                <sys:String>tb1</sys:String>
    </Loc:LocCollection>

    </UserControl.Resources>

    ...
    <TextBlock x:Name="tb1" Text="{Binding ItemValue}" DataContext="{StaticResource LocItem1}" />

     

    3. WCF Service

    When the control initializes we make a WCF request to get all translations in our LocCollection. On the server side we lookup our server side resx file for each requested string and wrap it in a XDocument of LocString . Once the WCF loaded event fires we then update the  ItemValue our individual LocItems to display the localizable strings.

     

    4. Code

    This is a pretty crude sample but you could wrap this functionality in asp.net style base page to make it scale cleaner.

    Download: LocWebService.zip

    10/26/2008

    SL 2.0 localization on-demand sample updated

    Overview 

    Updated To fix bugs on english code to check for culture installed and to fallback to english if culture not available

    This is a more advanced sample showing concepts I showed beta 2 samples and integrated into Silverlight 2.0  RTW project. Im not going over each part as this has already been detailed in earlier posts.

    1. Localization placeholder substitution
    2. Exposing localizable properties in custom control
    3. On-demand xap download (Explained in detail here)

    Requirements

    Visual Studio professional or greater plus the Silverlight Tools for Visual Studio 2008 SP1 and the excellent Dmytro Kryvko’s Extended Strongly Typed Resource Generator 2.3 at http://dmytro.kryvko.googlepages.com/ installer is at http://dmytro.kryvko.googlepages.com/ResXFileCodeGeneratorEx23.zip

    Code: http://cid-2b248d261d0e0035.skydrive.live.com/self.aspx/Public/LocOndemand.zip

    10/17/2008

    Creating a localizable Silverlight 2.0 RTW Application

    About

    The sample below shows how you can bind language resources (resx) using only markup. The final version of Silverlight makes localization alot cleaner.

    Requirements

    Visual Studio professional or greater plus the Silverlight Tools for Visual Studio 2008 SP1 and the excellent Dmytro Kryvko’s Extended Strongly Typed Resource Generator 2.3 at http://dmytro.kryvko.googlepages.com/ installer is at http://dmytro.kryvko.googlepages.com/ResXFileCodeGeneratorEx23.zip

    Instructions

    1. Open Visual Studio
    2. Click File \ New Project...
    3. Select Visual C# \ Silverlight \ Silverlight Application
    4. In the name field type SL2_RTM_Loc
    5. Click ok and ok
    6. In the Project Explorer
    7. Right click on the SL2_RTM_Loc (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. Close Strings.resx in VS
    14. Select Strings.resx in VS and its file properties replace it Custom Tool field from ResXFileCodeGenerator to ResXFileCodeGeneratorEx
    15. Right click on the strings.resx file and Select Run Custom Tool
    16. Open strings.resx in VS
    17. In the Name Field type tb1 and value “tb1 in english”
    18. Repeat with Name Field type tb2 and value “tb2 in english”
    19. Click Save, press F5 and add debugging to web.config
    20. IE opens up with a blank page
    21. Close IE
    22. Open Page.xaml in xaml editor window
    23. In the user control add a new xml namespace xmlns:Loc="clr-namespace:SL2_RTM_Loc.Resources"
    24. Add a locstrings as a  resource to your page eg: <UserControl.Resources><Loc:Strings x:Name="LocStrings" /></UserControl.Resources>
    25. Inside the grid add a Textblock and bind it to your resource Tb1 eg: <TextBlock Text="{Binding tb1, Source={StaticResource LocStrings}}" />
    26. The String should appear in the Design view above
    27. 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>

    28. In Project Explorer right click on Strings.resx and copy and paste it into the resources folder
    29. Rename “Copy of Strings.resx” to “Strings.de.resx” (DE is the two letter language code for German)
    30. Select Strings.de.resx in VS and its file properties remove it Custom Tool field from value ResXFileCodeGeneratorEx and change its Copy to Output Directory field to Copy if newer
    31. Open Strings.de.resx Edit the value to “tb1 auf deutsch” and “tb2 auf deutsch”
    32. Click Save, press F5
    33. Repeat the last three steps to add fr
    34. Notice the file %HOMEPATH%\Documents\Visual Studio 2008\Projects\SL2_RTM_Loc\SL2_RTM_Loc\bin\Debug\de\ appears but is not embedded in your xap yet
    35. To add that culture to your xap you must open the %HOMEPATH%\Documents\Visual Studio 2008\Projects\SL2_RTM_Loc\SL2_RTM_Loc\ SL2_RTM_Loc.csproj in notepad  
    36. Update SupportedCultures to <SupportedCultures>de,fr</SupportedCultures>
    37. Save and close
    38. VS 2008 will ask you to reload project, click reload
    39. Next we need to update the SL browser object reference
    40. Delete the SL2_RTM_LocTestPage.aspx and set SL2_RTM_LocTestPage.html as your start page inside SL2_RTM_Loc.Web project
    41. In SL2_RTM_LocTestPage.html  Add the culture and uiculture params to your silverlight object

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

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

    42. Click Save, press F5
    43. IE should open up with the German strings

    Code: http://cid-2b248d261d0e0035.skydrive.live.com/self.aspx/Public/SL2%7C_RTM%7C_Loc.zip

    Further Reading

    http://msdn.microsoft.com/en-us/library/cc189057(VS.95).aspx

    9/7/2008

    Silverlight Localization Methods: User Controls Vs. Application

    In this article I'm going to review usercontrol and two types of localization methods around them

    1. User Controls Overview
    2. Localization per user controls
    3. Localization on application only
    4. Conclusion

    1. User Control Overview

    "UserControls are the basic unit of reusable Xaml and the code that goes with it." User Controls are sometimes called custom controls. Most Silverlight applications will use and create many usercontrols in an application to simplify the application design in a more object orientated structure. A usercontrol can be used for UI elements (eg: dropdownlist, styled buttons, image viewer etc..) or computational (eg: prime number control etc...) or data retrieval (eg: load xml etc...).

    Once you have created something worth re-using, you can instantiated directly in XAML as a custom type user control. eg: <CoolButtonUCNamespace:coolButton x:Name="button1" ButtonText="Click Here" />.

    Some samples of user controls but note most controls wont have many UI strings to localize eg:

    1. DropDown list would contain 0 UI loc strings (DB Data is content not UI localisation)
    2. Image viewer would contain 2 loc string (Previous Image and Next image)
    3. RTE (Rich Text Editor) would contain ~40 loc strings (Bold, Italic, Insert Image etc..)

    2. Localization per custom controls

    On the Silverlight forums people occasionally ask how to do localization on a per control basis? eg: coolButton.xaml with coolButtonResource.de.resx where each control has its own set of resource files. This will mean you need to manage, localize & build many seperate files.

    To me this method gives some advantages and disadvantages

    Advantages:

    1. Clean code separation between app and control
    2. No dependencies external to the control

    Disadvantages:

    1. Cultures & Localization strings are control dependant
    2. May lead to translation in-consistency
    3. Control culture resources could grow very large (unless ondemand cultures are used)
    4. Longer build times

    Unless your a usercontrol vendor, this method would not be my first choice.

    3. Localization on application only

    The excellent Jordan Hammond created a novel way and wrote sample application by registering custom dependency properties and having all controls in generic.xaml.

    But if you to have seperate controls, downloadable on demand, but I'll try to explain the logic and basics.

    First review the good example of creating a reusable user control http://community.devexpress.com/blogs/theonewith/archive/2008/08/06/custom-silverlight-controls-creating-a-reusable-messagebox-dialog-part-i.aspx 

    Note a custom type user control can register custom dependency properties where you can set all localisable resources in its declaration and bind xaml at runtime

    eg: <CoolButtonUCNamespace:coolButton x:Name="button1" ButtonText="Click Here" /> as  <CoolButtonUCNamespace:coolButton x:Name="button1" ButtonText="{Binding LocButtonText, Source={StaticResource LocStrings}}" /> using the resx xaml binding as shown in the previous article.

    Using this method you can expose all UI string properties in each of your user controls.  This allows you to override the default strings and use a single application resx file per application rather than a rex per control.

    Advantages:

    1. Simpler loc build setup
    2. Better content separation
    3. Remove dependence on control not supporting application culture set
    4. Translator has full control of all localization strings

    Disadvantages:

    1. More work required in user control creation
    2. More verbose xaml

    4. Conclusion

    Thanks Jordan to pointing me to this method. I believe the localization per application is better due to the cleaner content and code separation which makes life far easier for the translator. Please share your thoughts below.

    Updated: See bluetext control on http://wpf-e.spaces.live.com/blog/cns!2B248D261D0E0035!407.entry for code sample

     

    7/12/2008

    Silverlight : on demand culture downloader

    In this article, im going to explain how to create a localized silverlight application that only downloads the culture resources as required and in the process breifly i'll explain
     
    1. On Demand Assembly deployment and the onDemandLoc class
    2. ObservableCollection & INotifyCollectionChanged
    3. Build xaps in batch file 
    4. Source Code
     
    1. On Demand Assembly deployment and the onDemandLoc class
     
    On Demand Assembly deployment is useful to increase startup performance of a RIA sites and allows the developer to only load the parts of application a user need in an "on demand" basis. This is of course especially useful when we need to use our culture resource files as well. Imagine 1000 words to download for 20 languages, when all you require in application in one culture. It is a waste of bandwidth and the user patience.
     
    Below is a small class that allows you to download a class based on the current culture in use. 
     
    It use the webclient to download a xap of the cultures name it extract the culture dll of your namespace and then loads the assemably into memory.

    public class onDemandLoc

    {

    private static ICollection<string> LoadedLang;

    private string CurrentLCID;

    static onDemandLoc() {

    LoadedLang = App.getlang();

    }

    internal void LoadLocDll()

    {

    CurrentLCID = System.Threading.Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName;

    System.Net.WebClient wc = new System.Net.WebClient();

    wc.OpenReadCompleted += new OpenReadCompletedEventHandler(OpenXAP);

    wc.OpenReadAsync(new Uri(CurrentLCID + ".xap", UriKind.Relative));

    }

    internal void OpenXAP(object sender, OpenReadCompletedEventArgs e)

    {

    if ((e.Error == null) && (e.Cancelled == false))

    {

    Assembly a = LoadAssemblyFromXap(App.Current.GetType().Namespace + "." + CurrentLCID + ".resources.dll", e.Result);

    LoadedLang.Add(CurrentLCID);

    }

    }

    internal Assembly LoadAssemblyFromXap(string relativeUriString, Stream xapPackageStream)

    {

    Uri uri = new Uri(relativeUriString, UriKind.Relative);

    StreamResourceInfo xapPackageSri = new StreamResourceInfo(xapPackageStream, null);

    StreamResourceInfo assemblySri = Application.GetResourceStream(xapPackageSri, uri);

    AssemblyPart assemblyPart = new AssemblyPart();

    Assembly a = assemblyPart.Load(assemblySri.Stream);

    return a;

    }

    }

    2. ObservableCollection & INotifyCollectionChanged
     
    Once the assembly is loaded into memory it can be used, but i also add the culture to our list of loaded cultures to avoid re-downloading the same culture twice. I used an ObservableCollection<T> class and used the INotifyCollectionChanged event to trigger the event that the culture is downloaded and ready for use and thus we can safely refresh our page content using the new culture strings. Im not sure this is the best method, but i wanted to make it as re-useable as possible. I would love to hear suggestions of how others do it.

    private static ObservableCollection<string> LoadedLang;

    public App()

    {

    this.Startup += this.Application_Startup;

    this.Exit += this.Application_Exit;

    this.UnhandledException += this.Application_UnhandledException;

    InitializeComponent();

    LoadedLang = GetNewCollection();

    INotifyCollectionChanged collection = LoadedLang as INotifyCollectionChanged;

    collection.CollectionChanged += new NotifyCollectionChangedEventHandler(LocCollectionChangedEvt);

    }

    void LocCollectionChangedEvt(object sender, NotifyCollectionChangedEventArgs e)

    {

    Page page1 = new Page();

    ((Page)this.RootVisual).LayoutRoot.Children.Clear();

    ((Page)this.RootVisual).LayoutRoot.Children.Add(page1);

    }

     

    public static ObservableCollection<string> GetNewCollection()

    {

    return new ObservableCollection<string>();

    }

    public static ICollection<string> getlang()

    {

    return LoadedLang;

    }

    3. Build xaps in batch file
     
    Lastly we need to build out language xaps using the Visual Studio post build event and a small batch file so the user can download, remember if the user culture does not exist it fall back to english. I use some helper vbs file to help create and to zip files. Some people said in the past they had issues with the vbs zip functions i updated them a little and hopefully they are more intl friendly
     
    for %%i in (da de fr ja nl) do (
    if exist "$(TargetDir)%%i\%%i.zip" del "$(TargetDir)%%i\%%i.zip"
    cscript /nologo "$(SolutionDir)$(ProjectName)\createzip.vbs" "$(TargetDir)%%i\%%i.zip"
    echo ^<Deployment xmlns="
    http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ^>^<Deployment.Parts^>^<AssemblyPart Source="$(ProjectName).%%i.resources.dll" /^>^</Deployment.Parts^>^</Deployment^> > "$(TargetDir)%%i\appmanifest.xaml"
    cscript /nologo "$(SolutionDir)$(ProjectName)\addfiletozip.vbs" "$(TargetDir)%%i\%%i.zip" "$(TargetDir)%%i\appmanifest.xaml"
    if exist "$(TargetDir)%%i\$(ProjectName).%%i.resources.dll" del "$(TargetDir)%%i\$(ProjectName).%%i.resources.dll"
    move /Y "$(TargetDir)%%i\$(ProjectName).resources.dll" "$(TargetDir)%%i\$(ProjectName).%%i.resources.dll"
    cscript /nologo "$(SolutionDir)$(ProjectName)\addfiletozip.vbs"   "$(TargetDir)%%i\%%i.zip" "$(TargetDir)%%i\$(ProjectName).%%i.resources.dll"
    move /Y "$(TargetDir)%%i\%%i.zip" "$(SolutionDir)$(ProjectName)Web\ClientBin\%%i.xap"
    del "$(TargetDir)%%i\appmanifest.xaml"
    del "$(TargetDir)%%i\$(ProjectName).%%i.resources.dll"
    )
     
    I added code to allow culture=auto to work and updated the code sample on skydrive.
     
    4. Source Code
     
    Update : I figured out how to add the ondemand to silverlight Streaming
     
    7/5/2008

    Silverlight Localizability and Pseudo-Localization

    In this sample I’ll try to give you an overview of localizability and some tools that can help assist you in the process, particularity pseudo-localization.

    1.       What is Localizability?

    2.       Enter Pseudo-Localization

    3.       No Custom Cultures yet

    4.       Code and sample

    5.       Other news: Bidi

    1.  What is Localizability?

    Localizability is the process to ensure that all UI strings in an application can be translated eg: no hard coded text or text on images. This is under the World-Readiness node of internationalization tree.

    We need to do localizability testing on a product to minimize the number of times we need to get our strings translated. We always aim to do one localization or translation cycle to reduce localization costs.

    I cant give the subject justice but please review .NET Internationalization and Developing International Software for further information.

    A common example of a localizability issues

    ·         Hard coded strings

    ·         Text in images

    ·         Fixed text lengths

    ·         Wrong encoding (eg: ansi rather than utf-8)

    For each issue there is an easy workaround

    1.       Hard code string: Move the hardcoded strings to the global application strings.resx file and reference these resx strings in the UI see http://wpf-e.spaces.live.com/Blog/cns!2B248D261D0E0035!203.entry

    2.       Text in images: Remove the string from the image and place in the resx file and make the image a grid that expands to the size of the string see http://wpf-e.spaces.live.com/Blog/cns!2B248D261D0E0035!232.entry

    3.       Fixed text lengths:  See expandable UI  section in http://wpf-e.spaces.live.com/Blog/cns!2B248D261D0E0035!232.entry  

    4.       Wrong Encoding: This is more a globalization issue rather than a localizability issue but you need to ensure all xaml and resx files are saved at in Unicode (default in visual studio) or UTF8

    What is not a localizability issue is, user content stored or external resources. Eg: An international imputed content is designed to differ per user and any text they enter should be stored in their language, so this would be user error if the user inputted English text in a German UI. Also if user german user subscribed to English RSS feed this probably what they wanted.

    2.  Enter Pseudo-Localization

    Pseudo Localization is a test process designed to make to easy to find hard coded strings, fixed width UI or improper encoding. It does this by converting the English UI elements to a extreme internationalized version of the UI

    Eg: “Hello {0}” becomes “[Ħęľľő {0}! !!! !!!]”

    In the above example the string is

    1.       The text is wrapped in the square brackets to show easily if a string is clipped

    2.       Each character or glyph is replaced with an international version of the character, to show if any encoding issues are present

    3.       The string length is in increased by 40% to show that any width restrictions

    There is a excellent tool, Pseudoizer.exe part of the John Robbins MSDN article .NET Internationalization Utilities to convert resx files to this format.

    pseudo

    3. No Custom cultures yet

    In .net there is the concept of custom cultures and Pseudo Cultures which allow the developer to create non-standard cultures eg:   – ES-US or “Spanish – United States” to better target your users.

    But the object  CultureAndRegionInfoBuilder doesn’t exist yet in Silverlight globalization class so instead we can use some obscure culture to display our pseudo culture eg: en-029 or English – Caribbean

    4. Code and sample

    psudoapp

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

    Code: http://cid-2b248d261d0e0035.skydrive.live.com/self.aspx/Public/Pseudo.zip

    5. Other news: BiDi/RTL

    Mark Rideout has stated there is no out-of-box support in 2.0 for Bidirectional or Right to Left text eg: Hebrew and Arabic . But there are some free 3rd party dlls using nBiDi to provide this functionality http://www.santeon.com/silverlight/  and http://www.codeplex.com/SilverlightRTL

     

    6/27/2008

    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

     

    6/21/2008

    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

    6/14/2008

    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

    5/25/2007

    Using resx files in Silverlight 1.0 (Updated to 1.0 RTW)

    You want to app to work outside the US

    You have created a great silverlight application but unfortunately but unless you have globalablized, it will only ever have limited reach. Therefore you need to localize and translate it. For a site to be able show different text based on language without having to re-create a different xaml for page you need dynamically reference different text based on the user’s language. For such occasions .net uses resx files.

    What are ResX Files?

    *.resx files are a .net standard resource file format - http://msdn2.microsoft.com/en-us/library/ekyft91f.aspx  
    It is an xml standard that has a set structure, as shown below, that are automatically generated from visual studio, from any text or localizable elements in web site or application.
    From this one base file, a localizer can translate the site without messing up the code of the rest of the site or application.

    <data name="string1">
        <value>hello</value>
    </data>

    Silverlight Localization Model

    Unlike Silverlight 2.0, Silverlight 1.0 has no localization resource model, that I am aware of. So instead of creating a custom format for your app, we can re-use the .Net standard resx format. In Silverlight 1.0 there is no built-in method to reference or generate these resources, so we need to re-create the ability the reference these.
    Since these are simple xml files, it is simple to do in either JS or client side .net

    In the example on http://www.geocities.com/sly_i/resx-sample , I have created a small page

    BTW: I got no design skills that im aware of ;-)

    How this Works

    It simply loads a xaml with some basic xaml elements and when the user press’s the mousedown on a button.

    1. I create a download object and load up and read a zipped resx file
    2. Store each loc resource into an array
    3. Then I walk the XAML DOM and look for any textblocks that are name like L_something_text
    4. Replace each item with its corresponding localized/translated string
    I hope you found this useful.

    Slyi

    In my next blog item is wrapping and clipping. I’ll show how to dynamically resize button like objects and canvas based on differing text lengths.
    5/23/2007

    Displaying unicode in silverlight

    The Problem up till now

    With the launch of silverlight 1.0 beta at mix, the Faq and forums stated BiDi (eg arabic) and East Asian (eg: japanese) fonts, are not supported in textblock element by default, only glyphs but will be in the final 1.0 release, this summer.
    I work on some international sites, so i need methods to display intl charactors, if i want to presude my boss to adopt it. 

    From the WPF/E Feb CTP we found you could show japanese text in text block, but only if you had the font available on your webserver. This is not a realistic deployment model, when you need 9mb font file to be downloaded every time.

    A designer would be better hardcoding some gif's with the text instead 

    A Solution Emerges

    In April, the Silverlight beta came the ability to embed fonts. But this is still a 6 mb zipped font file. 
    Then a
    breakthought came when Mark Rideout said, the plugin allowed obfuscated fonts. They are compressed subsets of the intl fonts used in the doc. So instead of 9mb it only 20k :-)

    Then with some tinking of the SDK embedded font example. I could show japanese charactors. http://www.geocities.com/sly_i/jajp/default.htm 

    What i needed to do,

    1. In vista open a wordpad and type or paste in some asian charactors and click print and select Microsooft XPS Document Writer.
    2. A dialog appears and asks for the name and location of the file to be saved, chose c:\test.xps
    3. Open c: drive in the explorer and rename file from test.xps to test.zip
    4. Extract the odttf from C:\test.zip\Documents\1\Resources\Fonts\9D2A1321-7A9B-4533-8D7D-B58C1539A91D.odttf
    5. Open the sdk example http://blogs.msdn.com/silverlight_sdk/attachment/2365400.ashx
    6. Replace the odttf font file with the downloader sample fonts in the zip.
    6. Save all html, js and xaml files as utf-8 encoding
    7. In the textblock use your same japanese charactors and that you used in wordpad
    8. Change the fontFamily to the font name in wordpad eg: myTextBlock.fontFamily = "MS PGothic";

    NB: Please note, some fonts may have embedding licencing issues.

    BIDI Support

    Silverlight fonts, support middle eastern ( eg hebrew or arabic) charactors as long as you save everything as utf-8.
    But Bi-Directional text flow is not supported yet.
    In Javascript the solution is simple, reverse the string text eg: http://www.geocities.com/sly_i/heil/

    function reversetext(HEIL_text){
       return HEIL_text.split('').reverse().join(''); 
    }

     

    Put it all together
     

    Then you can view both bidi and east asian text using textblock elements. A basic example is all languages is at

    http://www.geocities.com/sly_i/languages

     

    I hope this helps you design your silverlight apps to be enabled for international markets.
    My next post will be on guidelines for creating a localizable silverlight app using resx and javascript.

     

     

    Regards,

    Slyi

     

    BTW: Please see Laurence Moroney for more silverlight Intl samples http://blogs.msdn.com/webnext/default.aspx

    1/13/2006

    Should expression be free?

    What is Expression?
     
    Expression is a suite of 3 graphic tools
    1. Graphic designer (silimlar to photoshop)
    2. Interactive designer (similar to flash but more powerful but less portable)
    3. Web Designer (More dreamweaver than frontpage)

    Together someone could at last take on, the professional graphics tools monoply controlled and owned by Adobe.

     

    Who is expression targeted at?

     

    Microsoft in the past has create some entry level graphic apps, Photodraw 2000 (later merged into visio) and Digital image Editor but these both got low penetration. Expression on the other hand is aimed at high end pro designer market with more high end features and this microsoft jumping into the deep end.

    The price of apps generally is big deciding factor in it usage, the Graphic designer (Acrylic) is currently running a free beta and i suspect once the Vista beta 2 is finalised and the XAML API becomes more solid, Interactive Designer (Sparkle) will also release a free beta. This desperately need to happen as currently the only stable XAML animation editor is available via http://www.mobiform.com/ but this is VS 2005 add-in and as such only aimed at developers not designers.

    Graphic designers will be the only people cabable of fully untilising XAML/sparkles potential and finding its limits, or else it will be left dev's, who cant and shouldnt be deciding on UI design. Look to DA and VML as lessons from history where we had very impressive engines but dev's couldnt see it potential eg: http://www.geocities.com/sly_i/datest.htm. If you look at the code, it looks relatively simple but then look at the code cube.x file and you'll understand the barriers that dev's and designers were then confronted. XAML is definatly more simple for designers and dev to get to grips with and at stage i should hope so.

     

    Should it be free?

    I cant see graphics being a core MS focus and potential cash cow like say window, office, games or adverting but its DirectX underpinning if fully explored and untilised will allow these core products to be simply outstanding. Apple included X-Code (think VS 2005/Borland) free with the MacOS X CD, this i personally believe allowed MacOS X to get 15,000 new apps so quickly, by making new product development free and included and relatively simple.

    For Vista , its needs a bold step like this, but not for coding but designing apps by giving it out for free. Or even just slimed down version of sparkle, sparkle lite*, free and included on the vista CD this would surely speed up the development and adoption of XAML/WPF app and maybe expression as a whole. But winfx 1.0  runtime will need to be a download for winxp to ensure it doesnt get sidelined until vista adoption increases.

    * Hopefully something better than xamlpad or http://msdn.microsoft.com/archive/en-us/samples/internet/vml/vmlgenerator/default.asp

    12/13/2005

    Whats its Compatition?

    It has 3 main competitors
    1. Flash
    2. SVG
    3. Older IE technoligies (AJAX, VML, SMIL and DirectAnimation) 
    Flash

    The main competion is Flash, by far the leader in vector amination and more recently streaming video it has a near 90% penation in the browser market  and lately mobile devices but with poor dev interfaces and mainly designer centric.

    Adobe which has recently sewn up the designer market with Photoshop, Flash and dreamweaver to name but a few of it formidable assets in the professional graphic's designer toolbox it will be hard to turn its talented user base into a new tools and languages but if anyone can it is microsoft with it vast resourses of money and talent.

    SVG

    Scalable vector graphics was W3 next flash like standard. It was begining to take off but since adobe bought flash i personally dont think they will push 2 compeititing formats and without IE planning to support it by default, its stuck in no mans land to langish without a patron.

    Older IE Technologies

    There is some amazing browser plugins Microsoft created years ago that standard on nearly all recent versions of IE, about 85-90% of browser currently that are only begining to see the light of day.

    Ajax
    Some of you may heard alot about AJAX and DHTML recently. This is quite old technology that is being re-discovered with google as it main parton used in using in GMail, Google suggest, Googel Maps and earlier Outlook Web Access but name a few examples. People are begining to think of Rich web clients written in standard browser technologies since firefox recently implement xmlhttprequest.

    Some simple ajax effects at
    http://www.dhteumeuleu.com/runscript.php?scr=imgPress-X.html

    VML, SMIL and DA

    IE built in graphic is being re-discovered recently now as firefox has now implemented it own version <canvas>. This now allows a X-browser compatiably of vector animations that is crawlable.

    The main reason these technologies never took off before was a few reasons
    • MS created no designer friendly tools
    • poor graphics cards
    • low bandwidth

    Demo's:
    http://www.lutanho.net/svgvml3d/index.html
    http://webfx.eae.net/dhtml/VMLClock/elementbehaviordemo.html
    http://www.dhteumeuleu.com/runscript.php?scr=innercubeDA3.html
    http://www.geocities.com/sly_i/datest.htm
    http://cybarber.ath.cx/semcheski.htm
    http://me.eae.net/archive/2005/12/29/canvas-in-ie/

    What is WPF/E?

    WPF/E stands for Windows Presentation Foundation Everywhere which is a new vector based standard/language for the web.
     
    Its based on a slimdown version of MS WPF which is xml presentation for creating hardware accelerated software and web user interfaces with powerful features including 2D and 3D drawing,  advanced text rendering, vector graphics, raster graphics, animation, data binding, audio and video, but WPF/E wont have some of the advanved 3D stuff.
     
    WPF/E will work as browser plugin for most major browsers and OS's. It will scriptable for Dynamic XAML via javascript which will enable event driven UI similar to AJAX or http://atlas.asp.net.
     
    It is to be released for sometime in the new year probably in conjuction with release of MS Windows Vista runmored to be releasing Winter 2006.
     
    It was first announced at the PDC 2005 that MS would enable slim down version XAML that could be portable as Flash but still have progamable via visual studio cider or via MS Expression Designer aka sparkle.