Thursday, March 15, 2012

Building Single Page Apps with ASP.NET MVC4 - Part 3 - Basic Mobile Application

This blog is part of a series about building Single Page Applications using ASP.NET MVC 4 beta. When writing this post I assumed you have read the first and second posts. The code snippets are just the incremental changes that are needed since the second post

  1. Single Page Applications - Part 1 - Basic Desktop application
  2. Single Page Applications - Part 2 - Advanced Desktop Application
  3. Single Page Applications - Part 3 - Basic Mobile Application
  4. Single Page Applications - Part 4 - Sorting, Filtering and Manipulation data with upshot.js
  5. Single Page Applications - Part 5 - With MVC4 RC

The mobile viewmodel

In this post I'm adding a mobile component to the DeliveryTracker application I have been describing in my previous posts. I want to have an overview page per delivery, an overview page per customer and a detail view for the currently selected delivery. In order to do that, I'll create a new MobileDeliveriesViewModel in the DeliveriesViewModel.js file. This new class inherits from the existing DeliveriesViewModel class to inherit the existing features but adds some of its own:

  • self.currentDelivery is an observable (knockout.js) variable to keep track of the currently selected delivery which we need in order to navigate from the overview pages to the detail page
  • self.nav keeps the navigation history (nav.js) for our single page. It gives the impression to the user of navigating between different pages as usual. But it enables back button and allows creation of bookmarks within the single page application.
    • The name of the view will be stored in the view parameter. The default page will be the deliveries view.
    • A deliveryId paramater will be included in the querystring and intialized to null
    • On navigation we extract the deliveryId from the querystring and use it to filter the datasource
  • self.showsomething functions to invoke the navigation functionality. The showDelivery function receives the delivery object that was clicked so it can extract the deliveryId from it and attach it to the querystring so the delivery view can read it.
function MobileDeliveriesViewModel() {
  //inherit from DeliveriesViewModel
  var self = this;
  DeliveriesViewModel.call(self);

  // Data
  self.currentDelivery = ko.observable();

  self.nav = new NavHistory({
      params: { view: 'deliveries', deliveryId: null },
      onNavigate: function (navEntry) {
          var requestedDeliveryId = navEntry.params.deliveryId;            
          self.dataSource.findById(requestedDeliveryId, self.currentDelivery);
      }
  });

  //Operations
  self.showDeliveries = function () 
       { self.nav.navigate({ view: 'deliveries' }) };
  self.showCustomers = function () 
       { self.nav.navigate({ view: 'customers' }) };

  self.showDelivery = function (delivery) {
      self.nav.navigate({ view: 'delivery', 
                    deliveryId: delivery.DeliveryId() })
  };

  self.nav.initialize({ linkToUrl: true });
}

Note that the onNavigate function uses the findById method on the upshot datasource that doesn't exist in the original beta release of ASP.NET MVC 4. Add the following javascript code to the upshot.knockout.extensions.js file. The highlighted line below is already present in the file so don't add it again.

(function (ko, upshot, undefined) {
    upshot.RemoteDataSource.prototype.findById = function (id, updateTarget) {
        function search() {
            var self = this;
            var foundEntity = 
                $.grep(ko.utils.unwrapObservable(self.getEntities()), 
                function (entity) {
                   return self.getEntityId(entity) === updateTarget._id;
                })[0];
            updateTarget(foundEntity);
        }

        if (!('_id' in updateTarget)) {
            // TODO: What is the provision to 'unbind' here?
            this.bind("refreshSuccess", search);
        }
        updateTarget._id = id;
        search.call(this);
    };

Also note that in the parent DeliveriesViewModel class, bufferChanges is put back to false in order to have immediate upshot synchronization with the service back-end

function DeliveriesViewModel() {
    // Private
    var self = this;
    var dataSourceOptions = {
        providerParameters: { url: "/api/DataService",
            operationName: "GetDeliveriesForToday"
        },
        entityType: "Delivery:#DeliveryTracker.Models",
        bufferChanges: false,
        mapping: Delivery
    };

    // Snip the rest of the code
    // ...
    // ...
}

The mobile layout

ASP.NET MVC can support mobile browsers by letting you create specific mobile pages using the ".mobile.cshtml" extension. In order to test these pages I installed this User-Agent Switcher for Chrome.

In the \Views\Shared folder, create two new files:

  • _SpaScripts.cshtml: partial view that groups the different javascript includes
  • _Layout.mobile.cshtml: layout page for mobile browsers

The _SpaScripts.cshtml: is quite simply

<script src="~/Scripts/jquery-1.6.4.min.js"
        type="text/javascript"></script>
<script src="~/Scripts/modernizr-2.0.6-development-only.js"
        type="text/javascript"></script>
<script src="~/Scripts/knockout-2.0.0.js"
        type="text/javascript"></script>
<script src="~/Scripts/arrayUtils.js"
        type="text/javascript"></script>
<script src="~/Scripts/upshot.min.js"
        type="text/javascript"></script>
<script src="~/Scripts/upshot.compat.knockout.js"
        type="text/javascript"></script>
<script src="~/Scripts/upshot.knockout.extensions.js"
        type="text/javascript"></script>
<script src="~/Scripts/native.history.js"
        type="text/javascript"></script>
<script src="~/Scripts/nav.js"
        type="text/javascript"></script>

The _Layout.mobile.cshtml: includes the _SpaScripts partial view and the navigation bar. The two list items in the navigation bar use data-binding to attach their functionality in a declarative way.

  • Their click events are linked to their respective show functions in the MobileDeliveriesViewModel
  • Their CSS style is adapted so they appear as active when their view is showing. You can find the Site.Mobile.css file in the code download at the end of this post.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
    <link href="~/Content/Site.Mobile.css" rel="Stylesheet" type="text/css" />       
    <script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")">
    </script>
    <meta name="viewport" content="width=device-width" />

    @Html.Partial("_SpaScripts")

    <script src="~/Scripts/App/DeliveriesViewModel.js"
            type="text/javascript"></script>

  </head>
  <body>
    <nav class="bar">
        <ul>
          <li data-bind="click: showDeliveries, 
              css: { active: nav.params().view == 'deliveries' }">Deliveries</li>
          <li data-bind="click: showCustomers, 
              css: { active: nav.params().view == 'customers' }">Customers</li>
        </ul>
    </nav>

    @RenderBody()
  </body>
</html>

The mobile views

Now add a Index.mobile.cshtml to the \Views\Home folder. It's quite simple. When the DOM is ready a javascript function initializes the upshot library and initializes the knockout bindings to the MobileDeliveriesViewModel. The actual views are defined as partial views that are shown whenever their views are active.

Notice that the _DeliveryDetails view in Steven Sandersons example used the with: data-bind parameter. I couldn't get it to work so I encapsulated it within a parent div that checks the active view

@{
    ViewBag.Title = "Deliveries";
}

<script type="text/javascript">
    $(function () {
        upshot.metadata(@(Html.Metadata
                 <DeliveryTracker.Controllers.DataServiceController>()));
        ko.applyBindings( new MobileDeliveriesViewModel( ));
    });
</script>

<div data-bind="if: nav.params().view == 'deliveries'">
    @Html.Partial("_DeliveriesList")
</div>

<div data-bind="if: nav.params().view == 'customers'">
    @Html.Partial("_CustomersList")
</div>

<div data-bind="if: nav.params().view == 'delivery'">
    <div data-bind="with: currentDelivery">
        @Html.Partial("_DeliveryDetails")
</div>

The final items left to do are defining the partial views themselves. The only new functionality here is the $root pseudo-variable used by knockouts for-each data-binding which is used to bind the showDelivery method of the MobileDeliveriesViewModel to each item in the list

_CustomersList.cshtml

<div class="content">
    <label><input type="checkbox" data-bind="checked: excludeDelivered" />
              Only show undelivered items</label>

    <div data-bind="foreach: deliveriesForCustomer">
        <h4 data-bind="text: key.Name"></h4>
        <ol class="deliveries" data-bind="foreach: values">
            <li data-bind="text: Description, 
                           css: { updated: IsUpdated, delivered: IsDelivered }, 
                           click: $root.showDelivery"></li>
        </ol>
    </div>
</div>

_DeliveriesList.cshtml

<div class="content">
    <label><input data-bind="checked: excludeDelivered" type="checkbox" />
              Only show undelivered items</label>

    <ol class="deliveries" data-bind="foreach: deliveries">

        <li data-bind="css: { updated: IsUpdated, delivered: IsDelivered },
                                        click: $root.showDelivery">
            <span data-bind="text: Description"></span>
            <span class="details" data-bind="text: Customer().Name"></span>
        </li>

    </ol>
</div>

_DeliveryDetails.cshtml

<div class="title bar">
    <button data-bind="click: History.back">&lt; Back</button>
    <h1 data-bind="text: Description"></h1>
</div>

<div class="content">
    <p>Delivery #<strong data-bind="text: DeliveryId"></strong></p>

    <div class="callout" data-bind="with: Customer">
        <h1>Customer</h1>

        <label>Name</label>
        <strong data-bind="text: Name"></strong>
        
        <label>Address</label>
        <strong data-bind="text: Address"></strong>
    </div>
    
    <label class="checkbox" data-bind="css: { delivered: IsDelivered }">
        <input type="checkbox" data-bind="checked: IsDelivered" /> Delivered
    </label>
</div>

Following navigation map shows the mobile application in action

  • The 'deliveries' screen with the list of deliveries. Clicking a delivery navigates to the 'delivery' screen
  • The 'customers' screen with the list of deliveries grouped by customer. Clicking a delivery navigates to the 'delivery' screen. In the URL you can see the 'view=customer' parameter.
  • The 'delivery' screen containing the delivery details per item. In the URL you can see the 'view' and the 'deliveryId' parameters. Clicking 'Back' navigates back to the previous page.
  • All of these views exist on the same webpage but by changing the URL, the back button and bookmarking functions as you would expect

Download the source code

You can download the source code (Visual Studio 2010 solution) from my Skydrive.

Wednesday, March 7, 2012

Building Single Page Apps with ASP.NET MVC4 - Part 2 - Advanced Desktop Application

This is the second article in a series about building single page applications using ASP.NET MVC4. I assume that you have read the first part.
  1. Single Page Applications - Part 1 - Basic Desktop application
  2. Single Page Applications - Part 2 - Advanced Desktop Application
  3. Single Page Applications - Part 3 - Basic Mobile Application
  4. Single Page Applications - Part 4 - Sorting, Filtering and Manipulation data with upshot.js
  5. Single Page Applications - Part 5 - With MVC4 RC

In part 1 I recreate the first part of a demo by Steven Sanderson that shows a list of deliveries on screen, allows a user to mark an item as delivered and have the results immediately sent back to the server. In this second part the application will also show the deliveries grouped by customer and uses "Save All" and "Revert All" buttons so that the user can decide when to update the back-end.

Group by Customer

In order to group deliveries by customer, you'll need to a bit of javascript code that can go over the observable 'deliveries' array and group them together based on the referenced customer. This grouped data needs to be observable too. Steven has released the following bit of javascript called arrayUtils.js in order to achieve this:



/// <reference path="knockout.debug.js" />

(function () {
    function firstWhere(array, condition) {
        for (var i = 0; i < array.length; i++)
            if (condition(array[i]))
                return array[i];
    }

    ko.observableArray.fn.groupBy = function (keySelector) {
        if (typeof keySelector === "string") {
            var key = keySelector;
            keySelector = function (x) 
                          { return ko.utils.unwrapObservable(x[key]) };
        }
        var observableArray = this;

        return ko.computed(function () {
            var groups = [], array = observableArray();
            for (var i = 0; i < array.length; i++) {
                var item = array[i],
                existingGroup = firstWhere(groups, function (g) 
                                { return g.key === keySelector(item) });
                if (existingGroup)
                    existingGroup.values.push(item);
                else
                    groups.push({ key: keySelector(item), values: [item] });
            }
            return groups;
        })
    }
})();
You can now add a new datasource to the DeliveriesViewModel.js like this:
    self.deliveries = self.dataSource.getEntities();
    self.deliveriesForCustomer = self.deliveries.groupBy("Customer");
To show this new information on screen, add following code to index.cshtml. The groupBy operator has put every customer object on the "key" parameter and all his deliveries on the "values" parameter.
    <h3>Customers</h3>
    <ul data-bind="foreach: deliveriesForCustomer">
        <li>
            <div>Name: <strong data-bind="text: key.Name"></strong></div>
            <ul data-bind="foreach: values">
                <li data-bind="text: Description, 
                                css: { highlight: IsDelivered }">                
                </li>
            </ul>
        </li>    
    </ul>

If you would run the application now you will notice that knockout.js is keeping the values is the deliveries list and the customers list in sync.

Save, Revert, Exclude if delivered

Upshot can be configured to NOT synchronize the changes to the backend, meaning the user will have to click a "Save" button when he wants to submit. There is also the possibility to undo the accumulated changes or to put a filter on the datasource. In order to enable above functionality, make the following changes to the DeliveriesViewModel.js
  • Set bufferChanges to true so that the upshot datasource will keep the changes in memory and not sync them with the back-end
  • Create a self.localDataSource that we can use for client-side operations like filtering the data
  • Create a self.excludeDelivered variable to keep track of the value of the checkbox saying the user wants to exclude already delivered items from the list
  • Create the self.saveAll and self.revertAll function to commit or revert the changes on the upshot datasource
  • Subscribe a function to the self.excludeDelivered observable that gets called everytime the value changes. Inside this function a new filter rule is created which is then applied to the local data source
/// <reference path="_references.js" />

function DeliveriesViewModel() {
    // Private
    var self = this;
    var dataSourceOptions = {
        providerParameters: { url: "/api/DataService",
                    operationName: "GetDeliveriesForToday" },
        entityType: "Delivery:#DeliveryTracker.Models",
        bufferChanges: true,
        mapping : Delivery
    };

    // Public Properties
    self.dataSource = new upshot.RemoteDataSource(dataSourceOptions).refresh();
    self.localDataSource = upshot.LocalDataSource({ source: self.dataSource,
                                               autoRefresh: true });

    self.deliveries = self.localDataSource.getEntities();
    self.deliveriesForCustomer = self.deliveries.groupBy("Customer");
    self.excludeDelivered = ko.observable(false);

    // Operations
    self.saveAll = function () { self.dataSource.commitChanges() }
    self.revertAll = function () { self.dataSource.revertChanges() }

    // Delegates
    self.excludeDelivered.subscribe(function (shouldExcludeDelivered) {
        var filterRule = shouldExcludeDelivered 
            ? { property: "IsDelivered", operation: "==", value: false }
            : null;
        self.localDataSource.setFilter(filterRule);
        self.localDataSource.refresh();
    });
}

Include the new arrayUtils.js in the Index.cshtml file

<script src="~/Scripts/arrayUtils.js"
        type="text/javascript"></script>
<script src="~/Scripts/App/DeliveriesViewModel.js"
        type="text/javascript"></script>
To take advantage of the functionalities you can bind the view to the functions that have been put in place in the DeliveriesViewModel
  • Added two buttons of which knockout binds the click event to the appropriate functions in the DeliveriesViewModel
  • The "Exclude Delivered items" checkbox bound to the 'excludeDelivered' property in the viewmodel
  • The 'delivered' CSS class is bound to the existing 'IsDelivered' property which was foreseen on the view model. The 'updated' CSS class however is bound to the 'IsUpdated' property that comes built-in with the observable datasource
<div>
    <h3>Deliveries</h3>

    <button data-bind="click: saveAll">Save All</button>
    <button data-bind="click: revertAll">Revert All</button>

    <label>
        <input data-bind="checked: excludeDelivered" type="checkbox" />
         Exclude delivered items</label>

    <ol data-bind="foreach: deliveries">
        <li data-bind="css: { delivered: IsDelivered, 
                                        updated: IsUpdated}">
            <strong data-bind="text: Description"></strong>
            is for <em data-bind="text: Customer().Name"></em>
            <label><input data-bind="checked: IsDelivered" 
                  type="checkbox"/>Delivered</label>
        </li>
    </ol>

    <h3>Customers</h3>
    <ul data-bind="foreach: deliveriesForCustomer">
        <li>
            <div>Name: <strong data-bind="text: key.Name"></strong>
            </div>
            <ul data-bind="foreach: values">
                <li data-bind="text: Description, 
                    css: { delivered: IsDelivered,
                             updated: IsUpdated}">                
                </li>
            </ul>
        </li>    
    </ul>
</div>
I've defined these new styles in Site.css
.delivered
{
    text-decoration: line-through;
    color: #008000;
}

.updated
{
    background-color: #FFFF00;
}

If you now mark items as delivered, they will get the 'delivered' AND 'updated' styles in both lists. These are nicely kept in sync by upshot. When the user clicks the "SaveAll" button, all changes will be submitted to the server and the 'updated' style will disappear. The "RevertAll" button undoes all the changes. Selecting "Exclude Delivered Items" will remove the delivered items from the shared datasource so they won't show up in either list.

Download the source code

You can download the code (Visual Studio 2010 project file) from my SkyDrive

Monday, February 20, 2012

Building Single Page Apps with ASP.NET MVC4 - Part 1 - Basic Desktop Application

This blog entry is mainly based on the presentation given by Steven Sanderson on TechDays 2012 called “Building Single Page Apps for desktop, mobile and tablet with ASP.NET MVC 4”. Steven’s talk consisted of a large demo that immediately got me interested and made me want to try it out.
There was one big disappointment however. With the latest beta version of ASP.NET MVC 4 and information from the official pages, it was not possible to recreate Steven’s demo. In the following post, I’ll show what I had to do to get things to work. This is the first post of a series
  1. Single Page Applications - Part 1 - Basic Desktop application
  2. Single Page Applications - Part 2 - Advanced Desktop Application
  3. Single Page Applications - Part 3 - Basic Mobile Application
  4. Single Page Applications - Part 4 - Sorting, Filtering and Manipulation data with upshot.js
  5. Single Page Applications - Part 5 - With MVC4 RC

New Project Template

The ASP.NET MVC 4 beta adds a new project template in Visual Studio 2010 called “The “Single Page Application" (SPA). When creating a new project and starting it up, you’ll get some guidance about completing a first demo application for adding ToDoItems using a new TasksController. I will not do this but instead I will follow the same sequence as Steve did in his presentation and create a new SPA application called “DeliveryTracker”

Server side Domain Model

Since this demo application is a tool to track deliveries we will be using the following datamodel. The Customer class shows how to define a one-to-many relationship.
namespace DeliveryTracker.Models
{
    public class Customer
    {
        public int CustomerId { get; set; }

        public string Name { get; set; }
        public string Address { get; set; }
    }

    public class Delivery
    {
        public int DeliveryId { get; set; }
        public virtual int CustomerId { get; set; }
        public virtual Customer Customer { get; set; }

        public string Description { get; set; }
        public bool IsDelivered { get; set; }
    }
}
In order to store delivery information in the database, we are using the Entity Framework Code First approach
namespace DeliveryTracker.Models
{
    public class AppDbContext : DbContext
    {
        public DbSet<Customer> Customers { get; set; }
        public DbSet<Delivery> Deliveries { get; set; }
    }
}

Web API Data Service

The data for the application is loaded from a DbDataController which was introduced with the new Web API feature. In the solution explorer, right-click the controller folder and add a new controller called “DataServiceController” based on the “Empty Controller” template. The purpose here is to show what is happening behind the scenes and not rely on scaffolding too much. Replace the parent Controller class by DbDataController using the AppDbContext as generic parameter.
namespace DeliveryTracker.Controllers
{
    public class DataServiceController : DbDataController<AppDbContext>
    {

        public IQueryable<Delivery> GetDeliveriesForToday() 
        {
            return DbContext.Deliveries.Include("Customer")
                            .OrderBy(x => x.DeliveryId);
        }

        public void InsertDelivery(Delivery delivery) 
                  { InsertEntity(delivery); }
        public void UpdateDelivery(Delivery delivery) 
                  { UpdateEntity(delivery); }
        public void DeleteDelivery(Delivery delivery) 
                  { DeleteEntity(delivery); }
    }
}
The GetDeliveriesForToday will be used by the page to load the data. The IQueryable type allows sorting, paging, filtering and passing in custom parameters. The other methods are necessary for inserting, updating and deleting entities. If you build and run now, you could run OData queries against the service on http://localhost/api/DataService/GetDeliveriesForToday

Client Side ViewModel -  upshot.js & knockout.js

In order to use this data, the page will use the upshot.js javascript library that knows how to talk to a DbDataController. It will want to map your server side C# model in to a client-side javascript model. Steven has hidden this step behind his mysterious and undocumented Html.UpshotContext class.

Add a new “App” subfolder inside the “Scripts” folder and create a new script there called “DeliveryViewModel.js”. In the constructor of the DeliveriesViewModel, we are using upshot to make a connection to the GetDeliveriesForToday method in the DbDataController class. The results from the query are stored in the self.deliveries property.

Notice that the properties of the Customer and Delivery classes are knockout observables. Knockout keeps the data on your views and viewmodel synchronized. Upshot synchronizes with the data service. The bufferChanges option is set to false, meaning that any data that is changed on the web page will also be submitted to the server and saved directly in the database.
/// <reference path="_references.js" />

function DeliveriesViewModel() {
    // Private
    var self = this;
    var dataSourceOptions = {
        providerParameters: { 
          url: "/api/DataService", 
          operationName: "GetDeliveriesForToday"
        },
        entityType: "Delivery:#DeliveryTracker.Models",
        bufferChanges: false,
        mapping : Delivery
    };

    // Public Properties
    self.dataSource = new upshot.RemoteDataSource(dataSourceOptions)
                                .refresh();
    self.deliveries = self.dataSource.getEntities();   
}

function Customer (data) {
    var self = this;

    self.CustomerId = ko.observable(data.CustomerId);
    self.Name = ko.observable(data.Name);
    self.Address = ko.observable(data.Address);
    upshot.addEntityProperties(self, "Customer:#DeliveryTracker.Models");
}

function Delivery (data) {
    var self = this;

    self.DeliveryId = ko.observable(data.DeliveryId);
    self.CustomerId = ko.observable(data.CustomerId);
    self.Customer = ko.observable(data.Customer);
    self.Description = ko.observable(data.Description);
    self.IsDelivered = ko.observable(data.IsDelivered);
    upshot.addEntityProperties(self, "Delivery:#DeliveryTracker.Models");
}

Index View

In order to trigger the upshot call to the service when the index.cshtml page is loaded, add this code below the title section. All the rest of the code is not needed and can be removed. The Html.MetaData function provides the structure of the types to upshot. Knockout applies the bindings to the DeliveriesViewModel
<script src="~/Scripts/upshot.js" 
          type="text/javascript"></script>
<script src="~/Scripts/knockout-2.0.0.js" 
          type="text/javascript"></script>
<script src="~/Scripts/nav.js" 
          type="text/javascript"></script>
<script src="~/Scripts/native.history.js" 
          type="text/javascript"></script>
<script src="~/Scripts/upshot.compat.knockout.js"
          type="text/javascript"></script>
<script src="~/Scripts/upshot.knockout.extensions.js" 
          type="text/javascript"></script>
<script src="~/Scripts/App/DeliveriesViewModel.js" 
          type="text/javascript"></script>

<script type="text/javascript">
    $(function () {
        upshot.metadata(@(Html.Metadata
            <DeliveryTracker.Controllers.DataServiceController>()));

        ko.applyBindings( new DeliveriesViewModel( ));
    });
</script>
We can now use the data that is loaded and bound to the DeliveriesViewModel in the HTML. Add this code below the javascript call
<section>
<div>
    <h3>Deliveries</h3>
    <ol data-bind="foreach: deliveries">
        <li data-bind="css: { highlight: IsDelivered}">
            <strong data-bind="text: Description"></strong>
            is for <em data-bind="text: Customer().Name"></em>
            <label>
               <input data-bind="checked: IsDelivered" 
                           type="checkbox"/>
               Delivered</label>
        </li>
    </ol>
</div>
</section>

Routing

If you run this code, you will noticed that loading data from the database and displaying it on page works fine but submitting changes to the services fails. Investigating with Fiddler shows that the service responds to the submit request with the error “The service does not support the POST verb”

What Steven Sanderson also failed to mention is that you need to correct the 'MapHttpRoute' route in the routing table in global.asax.cs like this:
            routes.MapHttpRoute(
                "DataService", // Route name
                "api/DataService/{action}", // URL with parameters
                new { controller = "DataService" } // Parameter defaults
            );
So with the code above you can list the deliveries in the database and update the "IsDelivered" properties in real-time from a single page. All communication consists of AJAX calls handled by the upshot framework.

Download the source code

You can download the code (Visual Studio 2010 project) from my Skydrive