Controls are the basic blocks of any application, you use controls everywhere and also HTML Metro apps are part of the game, you add a control inside a HTML Metro page just placing a <div> with a special “data-win-control” attribute in it:

here’s an example:

<divdata-win-control="WinJS.UI.SemanticZoom"></div>

if you have pages (even in different applications) that need some special kind of functionality paired with some custom UI, custom controls allows you to reach the “write once, use everywhere” paradigm (unless you like reinventing the wheel of course…)Let’s see how you can create your own custom control and use it inside a HTML Metro application, simulating a simple custom countdown control.

Step1: Design the user interface

While not strictly a requirement I personally like to start from the appeareance of my control, so I fire up Expression Blend and start design it:

image-1

I’ve highlighted the HTML representing my control’s UI and, on right side, associated CSS, question now is: how do we turn it in a WinJS custom control?

Step2: Define public interface

The countdown control will expose:

initialValue property: will be initialized with countdown initial value

start method: begins countdown

countdownexpired and coundownstarted events

Step3: The code sss

Below is the control’s code contained in a separate countdown.js file:

Inside constructor I associate passed element with control's element property and I also add associate control’s instance with a conventionally named winControl property appended to passed element so that it can easily accessible from page’s javascript code.

The buildVisualTree function uses javascript to recreate control’s DOM and appends it to passed element while setOptions is a WinJS helper method that associates passed options to control so that it can be correctly initialized.

Since the control exposes events we finally use a couple of WinJS helper methods to ‘mix’ control’s class with a class defined inside WinJS framework to add all stuff required to handle and raise events (like onXYZ methods or addEventListener/removeEventListener support)

The rest of the code is just countdown code implementation, nothing really new here.

Step4: Using the control

To embed the code the control inside a HTML page we use exactly the same approach used for any WinJS control, add both required javasript and css references and decorate placeholder div with appropriate attributes, here’s the complete HTML page content:

note how both Person and Address are marked as sealed, this is a mandatory requisite if you want expose them to others WinRT languages.
Let’s now add a reference from HTML application to our C# library:

I know it might sound strange to mix Javascript with C# when you can do exactly same things with both languages on Metro but when you have some complex logic
or you want to hide some code as much as possible (you can do exactly the same with C++ code) this may be a viable alternative.

Azure applications, may have a set of parameters associated, this allows you to change your app configuration without having to redeploy the entire package (a long operation in any case). You can control how an application reacts to a parameter modification by subscribing RoleEnvironment.Changing event, if you want to restart the whole role when a parameter change you can simply set Cancel=true inside Changing event:

RoleEnvironment.Changing += (s, e) => { e.Cancel = true; };

in this case, when application’s .cscfg file content change, the role is shut down then restarted so that new parameters can be properly reloaded. If you don’t want to restart the role but handle modifications yourself you can handle Changes parameter passed to RoleEnvironment.Changing event.

How can you test this logic when your app runs inside Azure local compute emulator? here are basic step:

Run you app locally and read what is current development id by opening compute emulator UI and reading what between parenthesis (2103 in following example) following deploymentXX label:

Run Windows Azure Command Prompt and navigate to the folder that contains your configuration file ServiceConfiguration.cscfg and run this command:
csrun /update:[id];ServiceConfiguration.cscfg

And you’ll see your role reacting to configuration change appropriately.

by looking at Blend’s css properties pane you can see that, it has some css rules automatically applied:

you can copy the applied rule and paste it into another stylesheet by right clicking the highlighted row into selecting copy:

Now go to the Styles pane and click the “+” button shown in the picture below to add a new stylesheet:

then right click new file and select paste from context menu to paste the selector.

If you already have the same selector inside target file the properties will be merged (you’ll see Paste properties instead of Paste menu) of course you can also right click the selector inside source file and copy/paste from there but in this case you will copy all selectors not just applied one.

Navigation is one of the core concepts of any Metro application, in this post I’ll show how can you implement it in a HTML based Metro application.

The easiest way is to use the same common approach used by millions of HTML pages: using an hyperlink. Assuming you are in default.html page and wish to navigate to page2.html all you need to do is add something like:

1: <!DOCTYPEhtml>

2: <html>

3: <head>

4: <metacharset="utf-8">

5: <title>DemoNavigation</title>

6:

7: <!-- WinJS references -->

8: <linkhref="//Microsoft.WinJS.0.6/css/ui-dark.css"rel="stylesheet">

9: <scriptsrc="//Microsoft.WinJS.0.6/js/base.js"></script>

10: <script src="//Microsoft.WinJS.0.6/js/ui.js"></script>

11:

12: <!-- DemoNavigation references -->

13: <link href="default.css" rel="stylesheet">

14: <script src="default.js"></script>

15: </head>

16: <body>

17: <ahref="../page2/page2.html">Click here to navigate to Page 2</a>

18: </body>

19: </html>

default.html

When you run the app and click the hyperlink you move straight to page2.html.
This is approach is quite common, works fine (of course) but has a main drawback: you loose state when you move from default.html to page2.html, so if you need to maintain state, something that’s quite common in client application , you’re on your own.

The problem is the same in web application that’s why technologies like ajax or single page applications are gaining more and more momentum.

Let’s now briefly see how you can embed an HTML fragment into default.html using WinJS’s HtmlControl, here’s the html you need to add to default.html page:

Launching the app you’ll see exactly what expected but with some limitations:

the fragment can’t reference any css nor javascript file, and you are not informed when the fragment is loaded, luckily there’s a way to get some javascript code executed when fragment is loaded into the DOM: WinJS.Pages.define.

Let’s assume we wish to dynamically change the text of the fragment after it has been loaded so let’s add a new pagedefine.js file (just for better understanding and separation) to our solution:

The define method available on Pages object accept the uri that uniquely identifies the page that is going to be loaded and an object exposing a set of properties, among these, ready is the function that will be called when page has been loaded into DOM, then the code just changes element content with current date:

we’re now in a state where we can load a HTML fragment and run some code after it has been loades, before going further I need to point out that HmlControl can only load local html, if you need to load external content iFrame is your friend.

Problem now is: what if I need to load the fragment programmatically? (e.g. on a button click), let’s remove HtmlControl from default.html and let’s inject the fragment with a little help from WinJS:

In default.html I added a button and a “contentHost” div whose role is to be the container for for dynamically loaded content, default.js subscribes button’s click event (using WinJS.Utilities methods) and invokes WinJS.Pages.render method.
WinJS.Pages.render method accepts the uri of the fragment to load, the host element where fragment will be appended and optional data to pass to loaded fragment.
Here’s how I changed fragment’s code to handle passed parameter:

1: /// <reference path="//Microsoft.WinJS.0.6//js/base.js" />

2:

3: (function () {

4: 'use strict';

5: WinJS.UI.Pages.define("../fragments/pageFragment.html",

6: {

7: ready:function(element,options)

8: {

9: var text = document.getElementById("txt");

10: text.innerText = options.data;

11: }

12: });

13: }());

result, after clicking “Load fragment” button, is:

We now know how to dynamically load content into live DOM.

About page navigation: the best way to include it in a Html5 Metro app is to start with the Navigation Application template that creates all the infrastructure required to support navigating between pages while maintaining state, here’s what get’s created once you select the template:

1: <!--default.html-->

2: <!DOCTYPEhtml>

3: <html>

4: <head>

5: <metacharset="utf-8">

6: <title>DemoNavigation2</title>

7: <!-- WinJS references -->

8: <linkhref="//Microsoft.WinJS.0.6/css/ui-dark.css"rel="stylesheet">

9: <scriptsrc="//Microsoft.WinJS.0.6/js/base.js"></script>

10: <script src="//Microsoft.WinJS.0.6/js/ui.js"></script>

11:

12: <!-- DemoNavigation2 references -->

13: <link href="/css/default.css" rel="stylesheet">

14: <script src="/js/default.js"></script>

15: <script src="/js/navigator.js"></script>

16: </head>

17: <body>

18: <divid="contenthost"

19: data-win-control="DemoNavigation2.PageControlNavigator"

20: data-win-options="{home: '/html/homePage.html'}">

21: </div>

22: </body>

23: </html>

As you can see homePage.html (the starting page) contains a PageControlNavigator control that is defined inside navigator.js that basically uses WinJS.Pages.render to append other pages to contenthost div and adds typical navigation features like backstack etc… the control is configured via data-win-options to display homePage.html as initial content.
To add a page that can be navigated, let’s add a new folder named details and inside it a new Page control named details.html (see below):

1: //detail.js

2: (function () {

3: "use strict";

4:

5: // This function is called whenever a user navigates to this page. It

6: // populates the page elements with the app's data.

7: function ready(element, options) {

8: // TODO: Initialize the fragment here.

9: }

10:

11: function updateLayout(element, viewState) {

12: // TODO: Respond to changes in viewState.

13: }

14:

15: WinJS.UI.Pages.define("/html/details/details.html", {

16: ready: ready,

17: updateLayout: updateLayout

18: });

19: })();

Adding a new page control results in three files: the html, the css and the javascript code behind that, as you see below, it includes the necessary define invocation so that, inside ready handler, we can run page’s initialization code.
The only thing missing is triggering navigation from homePage.html to details.html, let’s assume this would happen, again, via a button:

1: <!--homePage.html-->

2: <!DOCTYPEhtml>

3: <html>

4: <head>

5: <metacharset="utf-8">

6: <title>homePage</title>

7:

8: <!-- WinJS references -->

9: <linkhref="//Microsoft.WinJS.0.6/css/ui-dark.css"rel="stylesheet">

10: <scriptsrc="//Microsoft.WinJS.0.6/js/base.js"></script>

11: <script src="//Microsoft.WinJS.0.6/js/ui.js"></script>

12:

13: <link href="/css/default.css" rel="stylesheet">

14: <link href="/css/homePage.css" rel="stylesheet">

15: <script src="/js/homePage.js"></script>

16: </head>

17: <body>

18: <!-- The content that will be loaded and displayed. -->

19: <divclass="fragment homepage">

20: <headeraria-label="Header content"role="banner">

21: <buttonclass="win-backbutton"aria-label="Back"disabled></button>

22: <h1class="titlearea win-type-ellipsis">

23: <spanclass="pagetitle">Welcome to DemoNavigation2!</span>

24: </h1>

25: </header>

26: <sectionaria-label="Main content"role="main">

27: <buttonid="btnLoad">Details</button>

28: </section>

29: </div>

30: </body>

31: </html>

1: //homePage.js

2: (function () {

3: "use strict";

4: // This function is called whenever a user navigates to this page. It

as you see, application navigation is handled globally through WinJS.Navigation object that exposes methods like navigate (together with back, canGoBack, canGoForward…) that navigates (thus, loads page into default.html’s DOM) to details.html, this way, since default.html isn’t discarded, state is preserved and experience is similar to any other client application development.

Quite cumbersome to understand at the beginning, but easy to implement thanks to Visual Studio 11 templates

In Javascript is extremely easy to write spaghetti code, when you write something like:

var foo = 12;function log(value){ console.log(value);}

both foo variable and log function become part of the global namespace, you can imagine what could happen when you add a new Javascript file that also includes a foo function.

In .NET to better organize the code we have Namespaces that can be used to group types together and prevent naming collision, while Javascript misses this concept natively it can be simulated through objects and that’s what Microsoft did inside WinJS Library.
Here’s how we can expose a ‘Logger’ object inside ‘MyLibrary’ namespace defined inside myLibrary.js file.

Nice, but now I’m using sort of static classes exposed from a namespace, what if I want something like real .NET classes?
You’re probably aware that using some patterns you can simulate classes in in a classless language like Javascript but ,again, thanks WinJS we can quickly have classes in Javascript too, here’s how:

the code add a new class MultiLogger to MyLibrary namespace using WinJS.Class.define method that accepts 3 parameters: a function representing class constructor (or null for an empty one) an object exposing instance properties (note that EcmaScript 5 allows definition of both get and set function associated to a property) and an optional object exposing static methods.

How can we use the MultiLogger class? exactly as if it was a .NET class:

When you create a background agent for Windows Phone 7 there are a couple of important details you must be aware of:

The total scheduled time for the agent to execute is 25 seconds, if you exceed it the agent will be killed by the scheduler.

The max amount of memory available is 6 MB, if the agent allocates more the agent will be, again, killed.

With Visual Studio debugger attached these limits are disabled.

An agent is killed silently and after two killing operations the scheduler will automatically disable it and your user probably will start wondering why your wonderful tile doesn’t work as expected.

The common problem I face when dealing with agents is that 6 MB of memory are a very strict constraint especially when you realize that the agent alone consumes more than 3 MB (in real cases I got more than 5 MB allocated at startup) So what can you do do live in a such restrict space? along with optimizations (in some cases I ended up duplicating code in order to avoid to load some dependencies) my suggestion is: never trust the debugger, with it attached the allocated memory increases so you might end up with wrong measurements. What I normally do is to write inside application tile what is the real amount of occupied memory so that I can quickly estimate how long I can go.

As advanced user I often need to reach areas like Control Panel, Event Viewer or the good old friend Command Prompt and you might imagine how happy I was to discover that using Win+X you have access to a “developer menu” in lower left corner that give you access to OS’ hardcore areas

You can also show the menu by pointing the mouse in lower left corner, wait for Start menu to appear then right clicking on it (but Win+X is a lot more faster…)

BTW: I took the shot using Win+PrintScreen that now automatically saves the screenshot under User’s MyPicture