WPF-E Moved to WordPress

February 1, 2011 Leave a comment

Just moved to WordPress hope to have new content soon.

Categories: Uncategorized

Silverlight 4 add Bidi support

November 18, 2009 100 comments
This is short post to show today that the silverlight 4 beta now supports Bidi http://www.silverlight.net/learn/videos/all/bidi-right-to-left/ 
This was a major internatioal feature request and tim has done a great introduction video. I played with this and seems pretty solid.
 
Unfortunately we still dont have any support for indic complex scripts as yet. I hope to do bidi sample over the weekend.
Categories: Uncategorized

Binding to Server based Resx Files in Silverlight 3

August 22, 2009 Leave a comment

 

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

Categories: Uncategorized

Silverlight 3 Intl Improvements

July 14, 2009 Leave a comment

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

 

Categories: Uncategorized

LocWebService: Only download resources per UserControl

November 16, 2008 Leave a comment
  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

Categories: Uncategorized

SL 2.0 localization on-demand sample updated

October 26, 2008 1 comment

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

Categories: Uncategorized

Creating a localizable Silverlight 2.0 RTW Application

October 17, 2008 3 comments

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

Categories: Uncategorized

Silverlight Localization Methods: User Controls Vs. Application

September 7, 2008 Leave a comment

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

 

Silverlight : on demand culture downloader

July 12, 2008 4 comments
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
 
Categories: Uncategorized

Silverlight Localizability and Pseudo-Localization

July 5, 2008 Leave a comment

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.

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

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

 

Categories: Uncategorized