Thursday, November 1, 2012

Fixing RTL layout for the built in HTML5 store templates

Windows 8 HTML platform has great support for globalization generally and it has particularly very well crafted support for RTL languages. If you open the WinJS CSS, and JS files you will find code everywhere caring for the requirements of RTL languages. That is why it is very disappointing to see that all this effort undermined by the built-in VS templates. Once you create an app with one of these templates and switch to RTL, hell breaks loose and the well crafted layout is gone, items overlap, margins disappear, and the whole metro style is no more.

The following screenshot shows the extent of deformation in the built in Grid template once transformed into RTL layout

broken_layout_grid_template_rtl

Luckily all the issues are only in the template and can be fixed with some CSS modifications. I have compiled these modifications into a single CSS file that can be easily included in the project to fix the layout issues. The CSS changes is minimally invasive and shouldn’t interfere with your CSS. The CSS rules are all qualified with -ms-lang pseudo selector to ensure the rules only affect RTL layout. The WinJS CSS rules made it easy to extract the list of RTL languages which are (ar, dv, fa, he, ku-Arab, pa-Arab, prs, ps, sd-Arab, syr, ug, ur, qps-plocm)

You can download the file here. I have testes these updates only with the Grid template, I will work on Split and Navigation template soon. Please let me know about any issues in the fixes.

Friday, April 20, 2012

Windows 8 Quick Tip: Debugging Managed Code Referenced by HTML 5 Applications

You can write libraries in Managed C# or VB, or native C++ that can be used from Windows 8 HTML5 applications as long as they are exported as WinMD libraries and conforms to WinMD rules. This is very useful especially if you want to use features in the managed world like Linq or consume SOAP services with the strongly typed WSDL proxy generator.

While I was trying to debug the managed code referenced by the HTML applications, no breakpoints were hit. After some poking around I discovered a setting that can enable debugging managed code in HTML applications.

In the HTML project properties navigate to the “Debugging” section and select “Managed Only” or “Mixed”. Please note that this will disable JavaScript debugging, so you have to choose between debugging managed libraries or Scripts at a time. The following screenshot shows this setting.

managed_debugging

Friday, April 6, 2012

PRI Files Deep Dive - Building Global Windows 8 Metro XAML Apps Part 3

In Part 1 we explored localizing strings, and in Part 2 explored localizing images, styles and custom layouts. In this post we will dig deeper into PRI files. All resource metadata is compiled into binary PRI files using a tool called makepri.exe. PRI files store all string resources and files metadata to a tree structure that can be navigated using Windows.ApplicationModel.Resources.Core.ResourceManager. This is unmanaged WinRT class different from the managed System.Resources.ResourceManager. It is not recommended to use the managed ResourceManager unless you are building a portable class library that is not targeting WinRT only.

Dumping PRI Files

You can use makepri.exe tool to dump the PRI binary into XML following these steps
- Open “Developer Command Prompt”
- Navigate to the bin directory.
- You should see a resources.pri file
- Type “makepri dump”
- The tool will generate a “resource.pri.xml” file.
The following snippet shows a very basic PRI dump.
   1: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
   2: <PriInfo>
   3:     <ResourceMap name="8f615d67-84d4-474a-8d44-04f3482dc045" version="1.0" primary="true">
   4:         <Qualifiers/>
   5:         <ResourceMapSubtree name="Files">
   6:             <NamedResource name="App.xaml" uri="ms-resource://8f615d67-84d4-474a-8d44-04f3482dc045/Files/App.xaml">
   7:                 <Candidate type="Path">
   8:                     <Value>App.xaml</Value>
   9:                 </Candidate>
  10:             </NamedResource>
  11:             <ResourceMapSubtree name="Assets">
  12:                 <NamedResource name="SplashScreen.png" uri="ms-resource://8f615d67-84d4-474a-8d44-04f3482dc045/Files/Assets/SplashScreen.png">
  13:                     <Candidate type="Path">
  14:                         <Value>Assets\SplashScreen.png</Value>
  15:                     </Candidate>
  16:                 </NamedResource>
  17:             </ResourceMapSubtree>
  18:             <ResourceMapSubtree name="Common">
  19:                 <NamedResource name="StandardStyles.xaml" uri="ms-resource://8f615d67-84d4-474a-8d44-04f3482dc045/Files/Common/StandardStyles.xaml">
  20:                     <Candidate type="Path">
  21:                         <Value>Common\StandardStyles.xaml</Value>
  22:                     </Candidate>
  23:                 </NamedResource>
  24:             </ResourceMapSubtree>
  25:         </ResourceMapSubtree>
  26:     </ResourceMap>
  27: </PriInfo>

The root of resource trees is the ResourceMap. The ResourceMap begins with a definition of Qulaifiers list. Qualifiers include Languages, Contrasts, and Scales as explained in Part 2 of this series. For example the following project structure generates the following qualifier list.


qaulifiers



   1: <Qualifiers>
   2:  <Language>FR-FR, EN-US</Language>
   3:  <Contrast>WHITE</Contrast>
   4:  <Scale>100</Scale>
   5: </Qualifiers>

Resource Subtrees


Resource are grouped into ResourceMapSubTree elements. Knowing the resource map tree structure is essential for navigating the map using ResourceManager. As shown in Part 1 and Part 2 of this series, you can use ResourceLoader or ms-appx Uri to load a resource with simple API. But in case you need to load a resource based on custom ResourceContext, which is really useful in situations like Unit Testing or custom configurations independent of the system settings.
Typically there are two main ResourceMapSubtree in a ResourceMap, one is named “Files” for images, xaml, and media files. The other is named “Resources” for string resources. The following screenshot shows the ResourceMapSubtree hierarchy for the SplashScreen.png file in the previous example.


resourcesubtree


All string resources are merged into a single Subtree as long as they are defined with same file name. The following project structure will generate only two Subtrees, one named Resources, the other named Custom.


stringresourcetreeproj


Unit Testing Resources


Testing resources requires simulations of different settings like Languages, Contrasts, and Scales. Using the ResourceManager with custom ResourceContext enables customizing qualifiers. The ResourceMap.GetValue method returns the best match ResourceCandidate. The ResourceCandidate has Score property that can be used if the resource is an exact match. The following snippet demonstrates this technique.



   1: var ctx = new ResourceContext();
   2: ctx.QualifierValues["Contrast"] = "black";
   3: ctx.QualifierValues["Scale"] = "100";
   4: var c1 = ResourceManager.Current.MainResourceMap.GetValue("ms-resource:///Files/Assets/SplashScreen.png", ctx);
   5: var candidate = ResourceManager.Current.MainResourceMap.GetValue("ms-appx:///Resources/HelloWorld", ctx);
   6: foreach (var c in candidate.Qualifiers)
   7: {
   8:   Assert.AreEqual(c.Score, 1.0);
   9: }

Note that the GetValue method can receive a Uri with the path of the resource instead of navigating to the exact subtree. The Uri can be either qualified with ms-appx or ms-resource scheme.


Resource in Referenced Class Libraries


Resources in referenced libraries will be merged in the same PRI file, and in the main ResourceMap, and to load the resource you must include the Library name in the resource Uri as in the following snippet



   1: var c = ResourceManager.Current.MainResourceMap
   2:                .GetValue("ms-resource:///ClassLibrary1/Resources/HelloWorld");

Summary


In this post we explored the internals of PRI files, and how to inspect their structure. Also explored how to unit test resource based on custom contexts. In the following post we will explore localization for Culture specific values like Dates, and Currencies.

Wednesday, April 4, 2012

Building Global Windows 8 Metro XAML Apps Part 2 Localizing Files and Custom Layouts

In the previous post we explored string localization for WinRT XAML applications. In this post the focus will be on localizing files like Images, Styles, and Custom Layouts.

Image Localization in XAML

If you are referencing the image from XAML, localizing an image is as simple as creating folders for the locals you need to support and put localized versions of the image file into the local folder. The local folder must be named with ISO Culture Names. The following image shows an example for project hierarchy for localized images of country flags.

project-hierarchy-images

And referencing the image in XAML is the normal relative URL without the culture code as shown in the following example.

ImageTag

Image Localization in Code

Using a relative URI to reference package content is not permitted in Metro XAML apps. If you tried to reference a file in code with relative Uri, you will receive “The given System.Uri cannot be converted into a Windows.Foundation.Uri.” error. Instead you have to use an absolute URI using the ms-appx scheme. The simple form of ms-appx url is ms-appx///path. So in the example we used the flag image should be referred to as ms-appx:///images/flag.png. This is a shorthand for ms-appx://[package name]/path. The following example shows how to load the flag image from code.

ImageinCOde

Contrast and Scale Conventions

The resource loader does not only support conventions for local resources, but also conventions for high contrast to enhance accessibility, and different DPI conventions to support high resolution screens.
The supported modes are:
High Contrast : contrast-black and contrast-white
Pixel Density: scale-80(start screen only), scale-100 (normal DPI), scale-140 (HD DPI), scale-180 (ultra HD)
The following screenshot showing an example project hierarchy supporting different contrast and scale scenarios

project-hierarchy-contrast

The Windows 8 Simulator has good support for simulation different DPI scenarios. You can change the resolution of the simulator to 1920*1080 which corresponds to scale 140, 2560*1440 which corresponds to scale 180, or other resolutions that will reflect scale 100. High contrast can be modified from control panel accessibility.

Custom Layouts and Styles

The conventions listed for local, contrast and scale file names are not limited to images or resw files, but to any file regardless of the extensions. Which is really useful with XAML resource dictionaries, giving designers great flexibilities not only to localize strings and images, but create totally different layouts specific to a local, contrast, or scale.

All resources in Metro project are analyzed using a tool called makepri.exe, the tool generates a binary metadata file that can be dumped into XML with “makepri dump”. Inspecting PRI dumps is useful in debugging resource related issues, and  parsing resource maps. In the next post we will dig deeper into PRI files and their structure.

Wednesday, March 21, 2012

Building Global Windows 8 Metro XAML Apps Part 1–Localizing Strings


WinRT provides good support for building global aware applications especially when compared to classic Windows API , but has some limitations compared to WPF features. In this series of posts we will explore the provided features with some workarounds to the issues in the current release.

ResW Files


WinRT uses ResW files to store localized strings, which are XML files used to store key value . ResW is the same as ResX schema. But unlike ResX built-in tooling in Visual Studio for WPF and Silverlight no strongly typed classes will be generated for ResW files. ResW files are compiled to binary .pri files using  makpri.exe, the same tool can be used to dump the data to XML. Dumping pri files provides useful information about how and what resources are stored.

The resource files can be loaded manually using ResourceLoader or ResourceManager, but the runtime will load the files automatically if the file is named Resources.resw and placed in a folder named with National Language Tag. The following screenshot shows an example of this structure.

project-hierarchy

The folder name is divided into two chunks, the first is the culture identifier for example en to English, es to Spanish, the second is the country qualifier, for example en-US for or en-UK. Determining the right resource to load depends on a heuristic process depending on the user Language Preference list.



Language Preferences


Traditionally .NET applications used the CurrentCutlure to determine the resource to load. This allowed only two options, either the culture specific resource or the fallback resource. With Windows 8 comes the concept of Language preferences which can include multiple language. The resource engine will try loading resources for the preferred language and if it can’t find any it will try the preferred language culture then the second preferred language and so on and if no match from the preferred languages is found, the engine will default to the fallback language. You can get the language preferences of the current user with Windows.System.UserProfile.GlobalizationPreferences.Languages property.

You can programmatically override the preferred language using Windows.Globalization.ApplicationPreferences.PreferredLanguage property. The PreferredLanguage setting is persisted, an will live across applications sessions. To clear it to use the system default language preferences instead, set it to an empty string.

Loading Strings in XAML


The resource engine can bind strings automatically to XAML elements if the following steps are followed:

1- Add x:Uid attribute to your XAML element, for example <TextBlock x:Uid="HelloWorld" /> 2- In the Resources.resw file add a value with its key uses the convention [Uid].[Property] for example HelloWorld.Text or HelloWorld.FontSize to set the Text and FontSize properties of the control with x:Uid HelloWorld.

x:Uid’s is not required to be unique. If two elements have the same Uid, both will receive the property settings. The property type is not limited to strings. Any type with built in converter can be used, for example Color properties can be set to Green or #00FF00 for example. Custom converters are not supported using Uid. If you need custom value converters for localized resource strings, you can use Binding to a class that loads the resources manually.

Attached properties can also be set in resw files but requires the fully qualified namespace for the class defining the property, for example the syntax for setting the Grid.Column property for an element would be MyElement.[using:Windows.UI.Xaml.Controls]Grid.Column

Loading Strings Manually


The ResourceLoader class simplifies the task of retrieving a string in two steps. First you instantiate a ResourceLoader then invoke GetString method. Instantiating ResourceLoader without any parameters loads the resources located in Resources.resw class. Passing a name loads the resource in the specified file as shown in the following example
   1: var loader = new ResourceLoader();
   2: loader.GetString("HelloWorld");
   3: var customLoader = new ResourceLoader("Custom");
   4: var str = customLoader.GetString("MyString");

ResourceManager class located in Windows.ApplicationModel.Resources.Core namespace exposes more powerful API to deal with resources, but requires more intimate knowledge of the internal structure of PRI files and resource maps. This is a native class part of WinRT API and different from System.Resources.ResourceManager. To get a string using ResourceManager first navigate to the subtree containing the resource, invoke GetValue or TryGetValue method. GetValue returns a ResourceCandidate that can be converted to a string or to a file depending on resource type. The following snippet shows using ResourceManager to load a string in action


   1: var manager = Windows.ApplicationModel.Resources.Core.ResourceManager.Current;
   2: var subtree = manager.MainResourceMap.GetSubtree("Custom");
   3: var resource = subtree.GetValue("MyString");
   4: var resourceValue = resource.ToString();

Responding to System Preferences Changes


ResourceManager exposes an event that can be used to detect the system preference changes. The following snippet shows how to use this event and get the current language preferences.


   1: var manager = Windows.ApplicationModel.Resources.Core.ResourceManager.Current;
   2: manager.DefaultContext.QualifierValues.MapChanged +=  (s, m) => {
   3:     string currentLangValue;
   4:     ResourceManager.Current.DefaultContext.QualifierValues.TryGetValue("Language", out currentLangValue);
   5:     var langs = Windows.System.UserProfile.GlobalizationPreferences.Languages;
   6: };

In the next post we will dig deeper into PRI files and their internal structure, and see how to load localized files and custom layouts.

Wednesday, March 7, 2012

Using SeaDragon Ajax to Display DeepZoom Content in Windows8 Apps

Download sample project

MultiScaleImage was introduced in Silverlight 2 and offered great power to manipulate high resolution images on the web. Unfortunately MultiScaleImage control is not yet available to Windows 8 developers as of Consumer Preview. DeepZoom or SeaDragon research project cuts images into smaller pyramid of lower resolution tiles, and smartly brings down only the tile suitable for the current display. So a viewer can be built in virtually any technology. Microsoft provides a JavaScript viewer for DeepZoom content. The JavaScript implementation has limited features and does not support image collections and sparse images, but works very well with single images.

Using SeaDragon Ajax in Windows 8 HTML5 apps is straightforward except for few hacks to work around the security restrictions and environment difference from the browser environment.

First you need to get the source from http://gallery.expression.microsoft.com/SeadragonAjax and note that you can not reference the hosted script because access to external scripts is prohibited while in local context http://msdn.microsoft.com/en-us/library/windows/apps/hh465373.aspx.

I used the dev version of the library to face the first glitch. The seadragon-dev.js uses document.write to emit the script files required by the library. WinRT apps running in local context requires dynamic content to be secure using the window.toStaticHTML or else you will receive “JavaScript runtime error: Unable to add dynamic content. A script attempted to inject dynamic content, or elements previously modified dynamically, that might be unsafe.”.

But using the window.toStaticHTML will remove all script tags in dynamic content, which renders the code useless. Since we trust the source of the content we can use MSApp.execUnsafeLocalFunction to wrap the dynamic content creation and temporarily disable the security restrictions as shown in the following snippet.

   1:  MSApp.execUnsafeLocalFunction(function () {
   2:      document.write(html.join(''));
   3:  });




The next glitch was the unavailability of the alert function for WinJS apps, and the library use it to display errors. As a workaround I defined a global alert function that displays a MessageDialog and logs the message to JavaScript console as shown in the following snippet.


   1:  <script type="text/javascript">
   2:      var alert = function(message) {
   3:          console.log(message);
   4:          var dialog = new Windows.UI.Popups.MessageDialog(message);
   5:          dialog.showAsync();
   6:      }
   7:  </script>



The next glitch was an error “JavaScript runtime error: Automation server can't create object”. This error is caused by the library checking for window.ActiveXObject and if defined it tries to use it to create XMLHTTP object. The workaround I used is setting window.ActiveXObject to null prior to creating the viewer. After that the viewer worked flawlessly. Just make sure to include the img directory available with the source to show the icons correctly.

Saturday, March 3, 2012

Consuming SOAP Web Services in Windows 8 HTML5 Applications

Windows 8 brings a great opportunity to use HTML and JavaScript to build rich desktop applications. I am coming from the managed world and used to some productivity features. One of these features is the Add Service Reference dialog and proxy generators for Web Services.

Interacting with SOAP web services involves a lot of overhead in creating envelop and formatting the message. This complexity is usually hidden behind proxies generated through the rich WSDL meta-information.

Unfortunately JavaScript has poor tooling support for interacting with SOAP services implemented with WCF or any other technology. The best approach when interacting with backend in JavaScript is to use REST based services that follows the simple HTTP protocol rules and returns JSON or XML formatted messages. But this option is not always available to developers.

Fortunately for Windows 8 developers the ability to implement WinRT components in managed languages and expose them to WinJS based applications. In this post the technique to expose a proxy for SOAP web services to HTML5 applications.

First add a new class library project to your HTML5 solution
add_project

Make sure that the output of this class library is WinMD file
winmd

Now use the Add Service Reference dialog to generate the proxy for the Web Service. The important trick here is to make sure that the proxy class are marked as Internal. WinRT exposed classes must follow some rules including being Sealed classes and expose WinRT compatible types. The proxy generated by the Add Service Reference dialog does not follow these rules, therefore the proxy should be internal or you will receive compiler error.
service-reference

You will notice that all the generated methods are Async operations. This is to follow Windows 8 rules of responsive UI. The new C# and VB language features facilitate the usage of async operation. Async methods requires the return type to be either void or System.Task<T>. But System.Task is not a supported WinRT type and if you exposed an async method that returns data as a public method you will get a compiler error

“Error    3    Method has a parameter of type 'System.Threading.Tasks.Task' in its signature.  Instead of using a managed Task type, consider using Windows.Foundation.IAsyncAction, Windows.Foundation.IAsyncOperation, or one of the other Windows Runtime async interfaces.  The standard .NET awaiter pattern also applies when consuming Windows Runtime async interfaces.  Please see System.Runtime.InteropServices.WindowsRuntime.AsyncInfoFactory for more information on converting managed task objects to Windows Runtime async interfaces.   “

To work around this limitation wrap your async operation in a private or internal method and declare a public method that returns Windows.Foundation.IAsyncOperation<T> that wraps the async operation. The following code shows this technique in consuming the public Web Service for 2010 Soccer World Cup located at http://footballpool.dataaccess.eu/data/info.wso?WSDL

   1:  public static Windows.Foundation.IAsyncOperation<TeamsData> GetData()
   2:  {
   3:      return getTeams().AsAsyncOperation();
   4:  }
   5:   
   6:  internal static async Task<TeamsData> getTeams()
   7:  {
   8:      return await Task.Run(async () =>
   9:      {
  10:          var client = new InfoSoapTypeClient();
  11:          var result = await client.TeamsAsync();
  12:   
  13:          var items = from i in result.Body.TeamsResult select i.sName;
  14:          return new TeamsData { Names = items.ToArray() };
  15:      });
  16:  }



Now in your HTML5 application you can add a reference to the managed project and use JavaScript futures to invoke the async operation as shown in the following code


   1:  var proxy = Backend.ServiceProxy;
   2:  proxy.getData().then(function (result) {
   3:      //do something
   4:  });



You can download the sample code here