In my last post (https://gauravmantri.com/2012/01/16/building-first-windows-8-metro-application/), I talked about my experience building my first Windows 8 Metro application. Now I am going to talk about how I built the application. In this post, we will just cover setting up the project and what you get out of the box when you create a new project. In subsequent posts, we will dig deep into the code. I will be using Visual Studio 11 Express for Windows Developer Preview for these blog posts.
Before we begin
The information I have presented below is based on my understanding of building Metro applications using HTML/JS. It is quite possible that my understanding may be incorrect. If that is so, please let me know about that and I will make necessary corrections.
Create Project
So, let’s fire up Visual Studio and create a new project:
As you can see from the screenshot above, you get a number of predefined project templates. Depending on the template you choose, Visual Studio will automatically create necessary files. For our purpose, we will choose Blank Application template. Let’s name the project as “WorldClock” and click OK to get going!
Solution Explorer View
Once the project is created, you will see the following items in your Solution Explorer view:
Let’s take a moment and see what all things are included:
default.html: This would be the landing page of our application.
“winjs” folder: This is where all the Microsoft stuff goes in. This folder contains two subfolders – Css (which contains system defined stylesheets … more on it in a little while) and js (which contains system defined JavaScript files … more on it again in a little while).
“js” folder: This is where you would normally put your JavaScript files. By default when you create a new html file, Visual Studio automatically creates a js file for that as well as a css file for that. In this case Visual Studio automatically created default.js and default.css files for default.html.
“images” folder: This is where you would normally put images used by your application.
“css” folder: This is where you would normally put your CSS files.
About winjs/Css folder
As you can see from the screenshot above, this folder contains two CSS files: ui-dark.css and ui-light.css. These are system defined CSS files and comes with predefined styles for various components/elements of your application. To understand the difference between the two, let’s modify default.html by adding a simple <div></div> element and run the application. This is what our code currently looks like:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>WorldClock</title> <!-- WinJS references --> <link rel="stylesheet" href="/winjs/css/ui-dark.css" /> <script src="/winjs/js/base.js"></script> <script src="/winjs/js/wwaapp.js"></script> <!-- WorldClock references --> <link rel="stylesheet" href="/css/default.css" /> <script src="/js/default.js"></script> </head> <body> <div class="win-title"> Hello World! <br /><br /> I'm using /winjs/css/ui-dark.css </div> </body> </html>
When we run this application, this is what we see.
Now let’s change the code so that it uses ui-light.css and see what happens. This is what our code would look like:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>WorldClock</title> <!-- WinJS references --> <link rel="stylesheet" href="/winjs/css/ui-light.css" /> <script src="/winjs/js/base.js"></script> <script src="/winjs/js/wwaapp.js"></script> <!-- WorldClock references --> <link rel="stylesheet" href="/css/default.css" /> <script src="/js/default.js"></script> </head> <body> <div class="win-title"> Hello World! <br /><br /> I'm using /winjs/css/ui-light.css </div> </body> </html>
When we run this application, this is what we see.
See the difference!!! With ui-dark.css it’s black background and white foreground while with ui-light.css it’s opposite of that. Depending on the theme of your application, you can choose either of these and provide a “Metro” feel to your application without writing a single line of code. You’re free to write your own styles of course!
A word of caution: Don’t try to edit styles directly in these files. If you wish to change something, you can define the same style (with same class name) in your CSS file and make changes there and the style defined in your CSS file will override the base style.
For example, I used a style called “win-title” and this is what it looks like in the ui-light.css file:
.win-title { font: 42pt/48pt "Segoe UI Light"; }
In my default.css file, I can create a style with same class name and change the style attributes there:
.win-title { font: 20pt/24pt "Segoe UI Light"; }
and the application would look something like this:
About winjs/js folder
winjs/js folder contains what I would call “system” JavaScript files. These files are essentially JavaScript based wrappers over WinRT. You can read more about these here: http://msdn.microsoft.com/en-us/library/windows/apps/br211669.aspx.
Quick note about navigation
Even though we just have one file in our project just yet, I want to take a moment and talk about navigation. Since we’re building HTML based application and there will be multiple pages (files) involved and we will be navigating between different pages. Broadly speaking, there are two navigation models: multi-page and single-page navigation. In multi-page navigation model, your users are taken from one page to another page of your application however in single-page navigation model, even though you have multiple pages in your application your user stay on just one page and the content from other pages is loaded in the main page only. There are three ways by which you can implement navigation in your application:
<a href=””></a> based navigation
This is your standard HTML based navigation mechanism where you navigate from one page to another by specifying the page link as the valule for href attribute. It falls under multi-page navigation model. For example:
<a href="ms-wwa:///addClock.html">Add Clock</a>
Iframe based navigation
As the name suggests, you end up accomplishing navigating between the pages by loading your pages in iframes. It falls under single-page navigation model. For example:
<a href="ms-wwa:///addClock.html" target="contentIframe">Add Clock</a> <iframe name="contentIframe" width="320" height="240"></iframe>
Fragment based navigation
Fragment based navigation is a new concept introduced. It again falls under single-page navigation model. A fragment is an HTML page contents of which gets loaded in the main page. The difference between an iframe based navigation and fragment based navigation is that the page loaded in an iframe has its own DOM and is separate than the DOM of the main page whereas when a fragment gets loaded its contents become part of the main page DOM. The advantage is that you get access to all the scripts and styles of the main page and (based on the documentation here) it loads faster. For building Metro application, Microsoft recommends using this approach. We’ll also use the same approach for our application.
You can read more about the navigation here: http://msdn.microsoft.com/en-us/library/windows/apps/hh452761.aspx. There are also some quickstart applications which will help you gain better understanding of the concepts.
Wrapping Up
Before we end this post, let’s make some changes in the project and add some files. We’ll need these files for our next steps.
1. Let’s add references to WinJS library in default.html. Your default.html should now look like:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>World Clock</title> <!-- WinJS references --> <link rel="stylesheet" href="/winjs/css/ui-dark.css" /> <script src="/winjs/js/base.js"></script> <script src="/winjs/js/ui.js"></script> <script src="/winjs/js/binding.js"></script> <script src="/winjs/js/controls.js"></script> <script src="/winjs/js/animations.js"></script> <script src="/winjs/js/uicollections.js"></script> <script src="/winjs/js/wwaapp.js"></script> <!-- WorldClock references --> <link rel="stylesheet" href="/css/default.css" /> <script src="/js/default.js"></script> </head> <body> <div id="contentHost"></div> </body> </html>
2. Let’s add following JavaScript files in “js” folder. For now we’ll not put any code in these files.
clock.js – This file will contain a custom object which would represent a clock.
converters.js – This file will contain some functions to create data binding converters which we will use to display data.
helper.js – This file will contain some helper functions.
3. Let’s create a folder called “html” and add an HTML fragment called “savedClocks.html”. This is where we will display the time from around the world. When you create this file, a JavaScript file called “savedClocks.js” and a CSS file called “savedClocks.css” is created for you. Let’s move the “savedClocks.js” in “js” folder and “savedClocks.css” in “css” folder and fix the references. So your “savedClocks.html” would look something like this:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Saved Clocks</title> <!-- WinJS references --> <link rel="stylesheet" href="/winjs/css/ui-dark.css" /> <script type="ms-deferred/javascript" src="/winjs/js/base.js"></script> <script type="ms-deferred/javascript" src="/winjs/js/ui.js"></script> <script type="ms-deferred/javascript" src="/winjs/js/binding.js"></script> <script type="ms-deferred/javascript" src="/winjs/js/controls.js"></script> <script type="ms-deferred/javascript" src="/winjs/js/animations.js"></script> <script type="ms-deferred/javascript" src="/winjs/js/uicollections.js"></script> <script type="ms-deferred/javascript" src="/winjs/js/wwaapp.js"></script> <link rel="stylesheet" href="/css/savedClocks.css" /> <script type="ms-deferred/javascript" src="/js/savedClocks.js"></script> </head> <body> <div class="savedClocks fragment"> <header role="banner" aria-label="Header content"> <button disabled class="win-backbutton" aria-label="Back"></button> <div class="titleArea"> <h1 class="pageTitle win-title">My Clocks</h1> </div> </header> <section role="main" aria-label="Main content"> <p>Content goes here.</p> </section> </div> </body> </html>
One interesting thing I would like to mention here is “ms-deferred/javascript” in <script> tag. If you look at any of the <script> tag in default.html, you will notice that it is missing there. When you add type=”ms-deferred/javascript” to your <script> tag what happens is that the fragment loader skips loading the JavaScript file if it is already loaded thus avoiding loading a single JavaScript file multiple times and hence improving the performance of your application. According to Microsoft, you should always include type=”ms-deferred/javascript” to all your script elements in your fragment html.
Summary
So what we have done till now is understood some of the concepts and laid the ground work for our next step. In the next part, we will create a basic clock which will display current time and will advance by a second. Some of the concepts we will use in the next blog will be related to data binding, converters, and navigation etc. Stay tuned!!!
Here is the source code of what we have done so far: Source Code