Colin Eberhardt's Technology Adventures

Introducing the jQuery Mobile Metro Theme

April 30th, 2012

This blog post introduces the new jQuery Mobile Metro theme and demonstrates how to create a web UI that detects the device it is being viewed on, to render a Metro UI on WP7 and iOS on other devices:


Colin Eberhardt is a Scott Logic technical Evangelist and a Technical Architect for Visiblox, suppliers of high-performance WPF and Silverlight charts.

Apologies for the terrible video quality, I really am going to have to work out how to do this properly one day!

You can view the mobile web site shown above on your own device from here. Note, on a WP7 device, set your IE to render the ‘mobile version’ of websites to see the Metro theme.

Introduction

A couple of weeks ago Microsoft announced the formation of Microsoft Open Technologies Inc. which will contribute to open source projects, standards and interoperability. For Windows Phone 7 developers, where the mobile OS market is highly fragmented, any efforts to push standards and interoperability are a very good thing. The first project backed by the Open Tech interop team was Apache Cordova (PhoneGap) allowing you to run HTML5 applications on your WP7, as covered in one of my previous blog posts. A few days ago, the team announced another release, jQuery Mobile (jQM) Metro. In this blog post we’ll take a look at what jQM is and how it helps you build HTML5-based mobile applications.

HTML5 is becoming an increasingly popular technology for the creation of mobile applications, allowing developers to leverage their existing JavaScript and CSS skills, regardless of the native language requirements of the mobile platform being targeted (WP7, iOS, Android etc …). One of the greatest challenges for developers of HTML5-based mobile applications is the creation of user-interfaces that mimic the native look and feel. This is where technologies like jQuery Mobile come in handy, this framework provides a standard set of styles and markup for creating a wide range of mobile layouts, controls and transitions.

If you look at the jQM website you will find that the interface quite closely mimics the iOS look and feel. A couple of months ago the jQM team announced WP7 support, however, this release simply allowed the iOS-style interface to render on a WP7 device.

The more recent release from MS Open Tech allows you to use jQM to produce Metro interfaces using HTML5. This makes use of the pre-existing jQM theme support, and as a result, you can use the same markup for both iOS and Metro themed UIs, with only a change in stylesheet being required.

The jQM Metro Theme is not an official part of jQM yet and is currently available via its own github page. I anticipate that it will make its way into the core jQM shortly. In the current release you will also see quite a few references to Apache Cordova (previously called PhoneGap), it is worth mentioning that Cordova and jQM are quite independent frameworks. Cordova provides a mechanism for deploying HTML5 applications within a native wrapper (see my previous blog post), and does not require you to use jQM – in fact you can use any UI framework your please (or roll your own).

This blog post will provide a brief introduction to jQM, demonstrating how you can create a mobile website that detects the mobile browser being used, delivering a Metro UI to WP7 devices and iOS to others. I will not be using Cordova for this example, just to keep it simple!

Introducing jQuery Mobile

The easiest way to understand jQM is via a simple example, a page with a heading and one line of text:

<!DOCTYPE html>
<html>
<head>
  <title>My Page</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
 
  <link rel="stylesheet" href="themes/default/jquery.mobile.css" title="default" />
 
  <script type="text/javascript" charset="utf-8" src="lib/jquery.js"></script>
  <script type="text/javascript" charset="utf-8" src="lib/jquery.mobile-1.0.js"></script>
</head>
<body>
  <div data-role="page">
    <div data-role="header" >
      <h1>jQM</h1>
    </div>
    <div data-role="content">
      Hello from jQuery Mobile!
     <button data-role="button">I am a button</button>
    </div>
  </div>
</body>
</html>

You can see in the above HTML the following elements:

  • The jQM CSS file
  • Two JavaScript files, jQuery and jQueryMobile
  • Some HTML content that is ‘annotated’ using data-role attributes.

Loading this into the browser (and shrinking it to a mobile-esque size) yields the following:

Which is a pretty decent replica of a native iOS UI, complete with gradients, button states and other chrome.

Considering that jQM is all about styling, why do we have JavaScript files as well as CSS files in our project? If you look at the source of the rendered page, you will see why. The simple button in our source HTML is now the following:

<div data-theme"c" class="ui-btn ui-btn-corner-all ui-shadow ui-btn-up-c" aria-disabled="false">
  <span class="ui-btn-inner ui-btn-corner-all" aria-hidden="true">
    <span class="ui-btn-text">I am a button</span>
  </span>
  <button data-role="button" class="ui-btn-hidden ui-btn ui-btn-corner-all ui-shadow ui-btn-up-c"
           aria-disabled="false" data-theme="c">
   <span class="ui-btn-inner ui-btn-corner-all" aria-hidden="true">
     <span class="ui-btn-text">I am a button</span>
   </span>
  </button>
</div>

That’s quite a lot of extra HTML! What’s all this extra junk doing in my page?

Unfortunately CSS isn’t quite powerful enough to radically transform the way which the standard HTML elements are rendered. When the page is loaded the jQM JavaScript runs through the page, looking for the various data-role attributes, adding in the structural HTML required to support the described style.

This is a bit of a shame really. The way that jQM ‘enhances’ your HTML can cause problems when trying to integrate with other frameworks such as KnockoutJS which dynamically insert elements into the DOM.

To be fair, the jQM JavaScript isn’t only required to give CSS a helping hand. It also does clever things such as load pages that the user clicks on using AJAX (yuck – I hate that term!) so that it can be rendered off screen then slid into view, mimicking the slick iOS page transitions.

jQM has a wide range of built in styles covering all the common mobile controls. For creating mobile UIs, jQM is a massive time saver. I really wouldn’t want to write (and test) all this CSS myself!

Go Metro!

We’ve seen how to build a simple iOS style mobile UI, but what about this new Metro theme? To use it, simply change the CSS to reference the Metro theme:

<link rel="stylesheet" href="themes/metro/jquery.mobile.metro.theme.css" title="default" />

I’ve also explicitly targeted the ‘dark’ theme by adding the following attribute to the page:

<div data-role="page" data-theme="a">

(Without this, the UI doesn’t quite look right, I think this is a bug … I’ll raise a ticket on github shortly).

With this simple change our UI is now Metro:

The above page uses the WP7 Segoe font, has a lower caps title, is authentically digital, favours content over chrome … etc … isn’t it lovely?

Building UIs with jQM is really quite simple, your markup is simple and clean, annotated with the various data- attributes. The jQM framework is really quite expansive, providing pretty much everything you might need for a standard mobile application.

For the rest of this article we’ll look at building a more complex example, that dynamically picks the theme based on the device viewing it.

SandwichFlow

I’ll re-use the data I collected for my SandwichFlow application to create a HTML5-based webpage where you can browse sandwich recipes. The index page is simply a list of sandwiches, sorted alphabetically:

<!DOCTYPE html>
<html>
<head>
  <!-- CSS and JS files included as above -->
</head>
<body>
  <div data-role="page">
    <div data-role="header" >
      <h1>Sandwich Flow</h1>
    </div>
    <div data-role="content">
      <ul data-role="listview">
        <li data-role="list-divider" class="ui-index">C</li>
        <li><a href="1.html">Chargrilled salmon open sandwich</a></li>
        <li><a href="2.html">Chicken, pesto and rocket sandwich</a></li>
        <li><a href="3.html">Christmas club sandwich</a></li>
        <li><a href="4.html">Cream cheese and cucumber sandwiches</a></li>
        <li data-role="list-divider" class="ui-index">D</li>
        <li><a href="5.html">Duck breast with mushroom and onion sandwich, puree of leeks
          and orange and balsamic sauce</a></li>
        <li data-role="list-divider" class="ui-index">E</li>
        <li><a href="6.html">Egg and cress finger sandwiches</a></li>
        ...
      </ul>
    </div>
  </div>
</body>
</html>

The above code uses a list-divider, which renders as follows with the iOS theme:

Whereas, with the metro theme, it gives the appearance of a jump list:

Sadly the list isn’t a real jump list, those buttons aren’t clickable. Perhaps the jQM Metro team might be interested in the HTML5 jump list I wrote a while back?

Automatically Choosing a Theme

What I’d like to do is deliver an interface that is appropriate for the device it is being viewed on, so this means the Metro theme on a WP7 device and the iOS theme on others (sorry Android!). We can detect a WP7 device via the user agent string:

var isWindowsPhone = navigator.userAgent.indexOf("Windows Phone OS 7.5") != -1;

The web page will include both CSS files, with the Metro theme being included as an alternate:

<link rel="stylesheet" href="themes/default/jquery.mobile.css"
      title="default" />
<link rel="alternate stylesheet" href="themes/metro/jquery.mobile.metro.theme.css"
      title="metro" />

Then if a WP7 device is detected, we use a bit of JavaScript to activate our metro theme (courtesy of a list apart):

if (isWindowsPhone) {
  setActiveStyleSheet("metro");
}
 
function setActiveStyleSheet(title) {
  var i, a, main;
  for (i = 0; (a = document.getElementsByTagName("link")[i]); i++) {
    if (a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) {
      a.disabled = true;
      if (a.getAttribute("title") == title) a.disabled = false;
    }
  }
}

The Recipes

My previous SandwichFlow application was written using Silverlight and contained an XML file with the various recipes. To re-use this within a jQM application I need to turn each recipe into an individual HTML file. Now, I am not keen on doing this sort of thing manually, so I wrote a T4 template that reads this XML file, and spits out an HTML file for each recipe:

<#@ template language="C#" hostSpecific="true" debug="true" #>

<#@ template language="C#v3.5" #>

<#@ include file="Util.tt" #>
<#@ include file="EnvDTE.tt" #>
<#

var project = FindProjectHost();

int lastSlash = project.FileName.LastIndexOf(@"\");
string projectPath = project.FileName.Substring(0,lastSlash);

XDocument xmlFile = XDocument.Load(projectPath + "\\CodeGen\\sandwiches.xml");

int index=1;
var sarnies = xmlFile.Descendants("sandwich")
                     .OrderBy(sarnie => sarnie.Attribute("title").Value);
foreach(var sarnie in sarnies)
{
  GenerateSandwichFile(sarnie, project,
    projectPath + "\\www\\" + index.ToString() + ".html", xmlFile);
  index++;
}
#>
<#+

private void GenerateSandwichFile(XElement sarnie, Project project, string filename, XDocument xmlFile)
{
#>
<!DOCTYPE html>
<html>
<head>
  <title>My Page</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <link rel="stylesheet" href="themes/default/jquery.mobile.css" title="default" />
  <link rel="stylesheet" href="style-other.css" title="default" />

  <link rel="alternate stylesheet" href="themes/metro/jquery.mobile.metro.theme.css"
    title="metro" />
  <link rel="alternate stylesheet" href="style-metro.css" title="metro" />

  <script type="text/javascript" charset="utf-8" src="lib/jquery.js"></script>
  <script type="text/javascript" charset="utf-8" src="lib/jquery.mobile-1.0.js"></script>
  <!--<script type="text/javascript" charset="utf-8" src="lib/cordova-1.5.0.js"></script>-->
  <script type="text/javascript" charset="utf-8" src="app.js"></script>
</head>
<body>
  <div data-role="page">
    <div data-role="header">
      <a href="index.html" data-icon="back" data-rel="back">Back</a>
      <h1>Recipe</h1>
    </div>
    <div data-role="content" class="recipe">
      <h3><#= sarnie.Attribute("title").Value #></h3>
      <#+
      var keyword = sarnie.Descendants("keyword").First().Value;
      var key = xmlFile.Descendants("keywordDefs")
                       .Descendants("keyword")
                       .Where(s => s.Value == keyword)
                       .SingleOrDefault();
      var img = "food/images/food_16x9_608/recipes/ovenbakedsweetmisoma_73596_16x9.jpg";
      if (key!=null) 
      {
        img = key.Attribute("url").Value;
      }
      #>
      <img class="yummyFood"
            src='http://www.bbc.co.uk<#= img #>' />
      <h4>Ingredients</h4>
      <ul>
      <#+
      foreach(var ingredient in sarnie.Descendants("ingredient"))
      {
        #><li><#= ingredient.Value #></li>
        <#+
      }
      #>
      </ul>
      <h4>Instructions</h4>
      <ul>
      <#+
      foreach(var instruction in sarnie.Descendants("instruction"))
      {
        #><li><#= instruction.Value #></li>
        <#+
      }
      #>
      </ul>
    </div>
  </div>
</body>
</html>
<#+
  SaveOutput(filename, project);
}
#>

The above code uses a few T4 ‘tricks’ I developed in an earlier article, including code that creates multiple output files from the T4 template and also automatically adds these files to the Visual Studio project.

An example recipe is shown below:

Now there isn’t really a suitable jQM UI for the ingredients list, so I styled these directly:

You’ll also notice that this page has a back-button. This is required because iPhones do not have a hardware back button. However, if we re-use this same UI in our WP7 version, even with a Metro theme, it will look quite wrong. A simple bit of jQuery is all that is required to remove these buttons when viewing with a WP7:

$("div[data-role='page']").live('pagecreate', function (event) {
  if (isWindowsPhone) {
    $("a[data-rel='back']").remove();
  }
});

The above code isn’t quite as simple as you might expect. Firstly, as mentioned previously jQM uses AJAX to load pages, so a jQuery live() function is used to match new DOM elements as they are added. We are handling the jQM pagecreate event which fires when the AJAXed page is initially added to the DOM but before the additional structure has been added, the code that is executed simply removes back linking anchor tags.

The resulting WP7 UI is as follows:

Conclusions

It’s great to see that Microsoft are not only backing HTML5 for their browsers (on the desktop and WP7) but are also working with the open source community on projects that make cross-browser and cross-platform development easier.

I am still in two minds about jQM, on the plus side, it does remove the need to write and test bucketloads of CSS and is very simple to use. However, there are some negatives …

The jQM UI looks almost identical to the native iOS on static screenshots, but the dynamic behaviour is nowhere near the native experience. For example, the iOS slide transition is surprisingly complex, with at least five separate animation components as described in this interesting blogpost. The jQM Metro theme is also lacking in the fluid aspects of the WP7 UI, this is most likely due to the lack of touch events and 3D CSS transforms on WP7. Ironically, iOS and Android phones are actually more capable of mimicking the Metro theme as demonstrated by Microsoft’s HTML5-based Metro demo for iOS and Android owners. Also, other key controls which define the Metro UI, such as Pivot and Panorama are absent from jQM Metro. These controls do lend themselves to HTML5 implementations, as demonstrated by jq-metro – hopefully this sort fo control will also find its way into jQM Metro. Finally, I couldn’t finish an article on HTML5-based WP7 applications without mentioning the ‘gray shading’ of clicked links which spoils jQM Metro just as much as it has all my previous HTML5 based applications ;-)

Ending on a positive note, I am sure that these issues will be resolved in time, and I do like the simplicity of jQM. If you want to rapidly create a simple mobile website or HTML5 mobile application that looks great, jQM is an excellent choice.

You can download the HTML / JS for this article here: SandwichFlowjQM.zip

Regards, Colin E.

WPF Charting Performance Comparisons (the Battle Continues)

April 24th, 2012

This blog post presents a thorough analysis of the performance of various WPF Charting components. The results show that a new class of charting solutions, which use raster-based graphics as opposed to retained mode vector graphics, provide a considerable performance advantage.

Introduction

Readers of my blog will know that charting and performance are two things that interest me greatly. One of the first things I did back in 2009 when I started working with WPF and Silverlight was have a go with the Microsoft ‘toolkit’ charts. Unfortunately I found these charts, and the various third party competitors, to be painfully slow when rendering just a few hundred datapoints. As a result of these findings I set about creating a high performance chart for Silverlight and WPF, which eventually became Visiblox charts.

In December 2010 I published a performance comparison that demonstrated that Visiblox was approximately 50-100 times faster than the Toolkit charts and 10 times faster than Visifire charts. At the time the only charts which came close were those developed as part of Microsoft’s now abandoned Dynamic Data Display project. Since publishing these figures, a number of the WPF and Silverlight charting vendors have started to take performance much more seriously, with Visifire more than doubling performance amid claims of being the fastest chart, amCharts have also publishing some very good performance figures as have Telerik.

Much has changed in the year and a half since my original performance blog post and I thought it would be a good idea to repeat the tests. However, this time I wanted to be more thorough, including a few different types of tests and also using WPF instead of Silverlight, due to the number of email requests I have had for a WPF charting comparison.

The Test Suite

In order to allow me to collect performance data for a range of WPF charts across a range of tests, I have written an automated performance test suite. The application uses MEF in order to allow me to easily slot in new tests and new charting providers. If you want a copy of the code, please get in touch.

The suite executes the following tests:

  1. Line Series Frame Rate – this test initially renders a ‘streaming’ line series which a fixed number of datapoints. New data is added to the chart as quickly as possible, and each time a new point is added to the front and old point is removed in order to keep a fixed number of points in view. The chart axes are auto-scaled (API permitting). The test initially starts with 50 datapoints, with each test run doubling this number.
  2. Scatter Series Frame Rate – a number of points are added to the chart. The location of these points is then animated in a manner that emulates Brownian motion. The test initially starts with 50 datapoints, with each test run doubling this number.
  3. Scatter Series Memory Usage – the above test is re-run, but this time rather than measuring render frame rate, the memory consumed as a result of adding the datapoints is recorded.

Initially I used a timer to measure framerate, followed by an attempt to measure via CompositionTarget.Rendering. However, I found that neither method gave an accurate frame rate measure, indeed the WPF team report that the CompositionTarget.Rendering can fire multiple times per frame. Instead, I opted for a more manual measurement using the WpfPerf tool, which makes use of the ETW events emitted by WPF.

Line Series Results

The results of the line series framerate tests are shown below:

NOTE: I am using a log-log scale for the above chart in order to make it easier to see the shape of the various curves.

Regarding which charting vendors I used for comparison, I tried to include all established and well known vendors in my comparison. For those which have already published performance figures or comments relating to Visiblox, I have included their names. For the others I have simply given them a token name ‘Vendor X’, in order to comply with the trial licencing terms which typically prohibit the publishing of performance figures.

One thing worth noting is that some charting vendors use sampling in order to improve framerates. I found that Vendor A (not included above) uses sampling without providing a mechanism for turning it off. Whereas most vendors that do support sampling allow you to turn it on or off and configure the sampling algorithm used. In order to provide a fair comparison, sampling was turned off on all the charts.

The chart above reveals some interesting patterns, due to the two very different classes of chart under test.

Vector based charts – WPF UIs are rendered via retained mode vector graphics. Whilst this approach is what has given rise to the very rich UI framework that WPF applications enjoy, it has been found that this approach just doesn’t perform as well as the bitmap-based approach used by Windows Forms when faced with complex UIs. This has led some people to use WinForms charts within their WPF applications! We can see that the faster vector charts from Microsoft Toolkit, Vendor B, the updated Visifire and Visiblox charts are all close to the limit of what is possible with this style of rendering.

“ … the major ‘partners’ cannot create a WPF chart that renders 2000 floating points of data in less that 5 seconds. I have tried them all and they are slow so we have had to regress to a WinForms version that renders the same data in milliseconds.” – from the channel 9 forums.

Raster based charts – Because of the limits of the WPF rendering system the two fastest charts in this test, Visiblox (via the new raster series type as part of the Ultimate Editition) and SciChart (a newcomer that exclusively uses this approach) both use a raster / bitmap graphics approach, which the WPF and Silverlight frameworks both have support for via the WriteableBitmap class. This approach yields results which are more than 100 times faster than what is possible with vector graphics.

One of the other common complaints made about WPF charts is the initial render time, with charts containing just a few thousands datapoints taking seconds to show on screen. Whilst this test focusses in framerates, it is also gives a good indication of the initial render times, with raster based charts appearing almost instantly when loaded with tens of thousands of points.

Scatter Series Results

The results of the Scatter series tests are shown below:

Again, the same pattern emerges, with the raster based approach yielding a significant increase in frame rate over the vector based.

Scatter Series Memory Usage

The final test looks at the memory consumption of the various charting providers:

The above shows that the memory consumption is directly related to the number of datapoints present in the chart, however, the scale of this relationship is very different for the charts under test. I have a feeling that the Toolkit charts have a memory leak which contributes to the poor performance in this test.

Conclusions

The overall performance of the charting solutions available to WPF (and Silverlight) developers is improving. However, the performance of the WPF rendering system appears to create an upper limit which constrains what can be achieved. The raster-based approach is not subject to these same constraints and as a result provides a considerable improvement in performance.

If you want to have access to the code I used to make these tests, please get in touch. Also, if you are a charting vendor and think you might be Vendor A, B or C in these tests, and wish to be named, let me know.

Everything you wanted to know about databinding in WPF, Silverlight and WP7 (Part Two)

April 20th, 2012

Introduction

This is the second post in my series about databinding in Silverlight and WPF. In the first post I looked at how you wire-up UI controls to a model in the absence of a databinding framework. I showed how databindings can be created in code-behind, removing the need for the various event handlers that the manual method requires, resulting in more readable code, where the connection between a UI control and a model property is all in one place. In this blog post I’ll look at how bindings can be defined in XAML, providing a more concise and flexible method of wiring model objects to your view.

The rough outline for this series is as follows:

  • Part One – Life before binding, INotifyPropertyChanged and creating bindings in code-behind
  • Part Two (this one) – The binding markup extensions, the DataContext and path syntax
  • Part Three – Other binding sources, ElementName, TemplatedParent, TemplateBinding
  • Part Four – Value converters
  • Part Five – List binding

Code-behind binding: a re-cap

The previous blog post worked through the creation of a very simple application which creates a model object that represents an event (INotifyPropertyChanged implementation omitted for clarity)

/// <summary>
/// A simple model object that represents an event
/// </summary>
public class EventModel : INotifyPropertyChanged
{
  /// <summary>
  /// Gets / sets the event title
  /// </summary>
  public string Title { ...  }
 
 
  /// <summary>
  /// Gets / sets the date of this event
  /// </summary>
  public DateTime Date   { ...  }
}

And render it with the following UI:

The XAML for the UI is as follows:

<Grid>
  ...
  <TextBlock Text="Name:"
             Grid.Row="1" />
  <TextBox x:Name="EventTitle"
            Grid.Row="1" Grid.Column="1"/>
 
  <TextBlock Text="Date:"
             Grid.Row="2"/>
  <sdk:DatePicker x:Name="EventDate"
                  Grid.Row="2" Grid.Column="1"/>
</Grid>

The previous blog post wired up the above UI by creating bindings in code-behind:

public MainPage()
{
  InitializeComponent();
 
  // create a model object
  _event = new EventModel()
  {
    Date = new DateTime(2011, 7, 1),
    Title = "Silverlight User Group"
  };
 
  // bind the Date to the UI
  EventDate.SetBinding(DatePicker.SelectedDateProperty, new Binding("Date")
  {
    Source = _event,
    Mode = BindingMode.TwoWay
  });
 
  // bind the Title to the UI
  EventTitle.SetBinding(TextBox.TextProperty, new Binding("Title")
  {
    Source = _event,
    Mode = BindingMode.TwoWay
  });
}

Most applications create bindings within the XAML markup … and that is exactly what we shall do next!

Binding Markup Extension

It is quite unusual to see code which creates bindings in C# (code behind), this is because there is a simpler, more elegant way. Firstly, we’ll change the code above to remove all of the bindings, and instead set the DataContext of the page to the event that we wish to edit:

public MainPage()
{
  InitializeComponent();
 
  // create a model object
  _event = new EventModel()
  {
    Date = new DateTime(2011, 7, 1),
    Title = "Silverlight User Group"
  };
 
  // bind the Date to the UI
  this.DataContext = _event;
}

Next we’ll update the XAML, removing the names of the controls used to edit this event (we only named them so that they were accessible form code-behind), and adding bindings as follows:

<Grid x:Name="LayoutRoot" Background="White">
  ...
 
  <TextBlock Text="Name:"
              Grid.Row="1"/>
  <TextBox Text="{Binding Path=Title, Mode=TwoWay}"
           Grid.Row="1" Grid.Column="1"/>
 
  <TextBlock Text="Date:"
              Grid.Row="2"/>
  <sdk:DatePicker SelectedDate="{Binding Path=Date, Mode=TwoWay}"
                  Grid.Row="2" Grid.Column="1"/>
</Grid>

Compiling and running this modified version of our code yields exactly the same result. The UI displays the initial values of the event, and the bindings take care of updating the UI if the model changes and updating the model based on user interactions with the controls. So let’s take a closer look at how these binding work.

Within XAML, any attribute value that is surrounded in curly braces {…} is a markup extension. Whilst most of your XAML markup is simply used to construct controls and panels in order to assemble the visual tree of your application, markup extension inject extra functionality into the XAML parser. The Binding Markup Extension constructs a binding and associates it with the UIElement or FrameworkElement that the property belongs to.

As you might recall from the previous blog post, all bindings have a source object, source property, target object and target property:

How do these map to our XAML binding? Let’s look at the various components of our markup:

The target object is the object that owns the property which we are binding to, i.e. the UI control rendering our data. The target property is the property that has been set via the markup extension, and the source property is the path of the binding.

However, there is something missing? Where is the source object? In our example above, where is the object that owns this Title property we are binding to the UI? If you recall earlier we set the DataContext property of our MainPage to the event class which is being edited … this is our source object. The DataContext is a rather special property for a couple of reasons:

  1. Inheritence – The DataContext value is inherited down the visual tree from one control to the next. Even though we set the DataContext of MainPage to our model object, if you set a breakpoint in the code and inspect the DataContext of the above TextBox you will also find that it is set to the same event object.
  2. Default source – Any bindings that are defined without the source object being specified (via the Binding.Source property), will take the DataContext of the target object as the source. In the case illustrated above this is the DataContext of the TextBox, which has been inherited from MainPage.

These two properties of DataContext and the binding framework result in a concise and elegant way to wire up your applications user-interface.

The Property Path Syntax

We’ll explore a few other features of the binding framework via a more complex example, this time we have a model object, PersonModel, that has a relationship to another model object, AddressModel. A summary of these classes is show below (INotifyPropertyChanged implementation omitted for clarity):

public class PersonModel : INotifyPropertyChanged
{
  public string Forename { ...  }
 
  public string Surname { ...  }
 
  public AddressModel WorkAddress { ...  }
}
 
public class AddressModel : INotifyPropertyChanged
{
  public string Street { ...  }
 
  public string City { ...  }
}

Again, we create an instance of this class and set it as the DataContext of our user control:

_model = new PersonModel()
{
  Surname = "Eberhardt",
  Forename = "Colin",
  WorkAddress = new AddressModel()
  {
    Street = "6 Charlotte Square",
    City = "Newcastle"
  }
};
 
 
// bind the Date to the UI
this.DataContext = _model;

(Aren’t C# object initializers just great!)

Binding the Surname and Forename to the UI is straightforward, but how about the WorkAddress? The Path property of a Binding supports a special property path-syntax which has a dot notation for navigating relationships. We can bind our UI to the various properties of the Address as follows:

<TextBlock Text="Street:"  ... />
<TextBox Text="{Binding Path=WorkAddress.Street, Mode=TwoWay}" ... />
 
<TextBlock Text="City:" ... />
<TextBox Text="{Binding Path=WorkAddress.City, Mode=TwoWay}" ... />

Which yields the following UI:

Now because Address implements INotifyPropertyChanged, if we change the Street or City of the object bound to the UI, the binding framework will take care of pushing this change to the binding targets (i.e. the TextBox instances). But, what if we replace the Address instance entirely? For example …

private void Button_Click(object sender, RoutedEventArgs e)
{
  _model.WorkAddress = new AddressModel()
    {
      Street = "62 Arcacia Ave.",
      City = "Bananaville"
    };
}

Again, the binding framework updates the UI. The binding framework not only detects changes in the source property, it is able to detect changes at any point in the chain of property relationships from the DataContext. That’s pretty smart!

The property-path syntax supports binding to arrays and dictionaries via indexers, for example:

{Binding Path=ArrayOfThings[0]}

and

{Binding Path=DictionaryOfStuff["foo"]}

I’m not going to give examples of all the various bindings that are possible, MSDN has a good reference for these.

Creating Binding ‘Islands’

In the previous example we had two bindings that navigated the relationship from Person to Address to bind to properties of the Address object. Instead of repeatedly navigating the same relationship, we can bind a ‘region’ of our UI to the WorkAddress property.

If you recall, the DataContext is inherited throughout the visual tree and is the default source for bindings. If we change the DataContext of a common root element of our various Address bindings to the Person.WorkAddress, we can simplify our bindings. We could set the DataContext in code-behind, but there is a more elegant way:

<TextBlock Text="Forename:"  ... />
<TextBox Text="{Binding Path=Forename, Mode=TwoWay}"  ... />
 
<Border DataContext="{Binding WorkAddress}">
  <Grid util:GridUtils.RowDefinitions=",," util:GridUtils.ColumnDefinitions=",">
 
    <TextBlock Text="Street:"  ... />
    <TextBox Text="{Binding Path=Street, Mode=TwoWay}"  ... />
 
    <TextBlock Text="City:"  ... />
    <TextBox Text="{Binding Path=City, Mode=TwoWay}"  ... />
  </Grid>
</Border>

In the above XAML we are binding the DataContext of the Border element to the WorkAddress property of the Person instance (which was set as the DataContext of our UI in code-behind). As a result, all the children of the Border have the Address instance as their DataContext, so we can bind to the properties directly. This creates an ‘island’ within our UI that is bound to Address as shown graphically below:

Binding Shorthand and Longhand

We’ll wrap up part two of the series on databinding by looking at a couple of variations in the binding syntax, the first is a ‘longhand’ version of the binding. Instead of using the binding markup extension, it is possible to create the binding instance in XAML, for example, the simple binding to Forename:

<TextBox Text="{Binding Path=Forename}"/>

Can be expressed as follows:

<TextBox>
  <TextBox.Text>
    <Binding Path="Forename"/>
  </TextBox.Text>
</TextBox>

This yields exactly the same result. What’s the point in the longhand version? Good question, I have only used it occasionally myself, typically within multi-bindings, or where validation rules are being added.

If instead we want to make our bindings simpler, we can omit the Path and simply express the binding as follows:

<TextBox Text="{Binding Forename}"/>

Now there are some instances where you do not want to bind to a property of your source (i.e. DataContext), rather you want to bind to the source itself. The syntax for this is a single ‘dot’:

<TextBox Text="{Binding Path=.}"/>

Or, in this case, we can use the very-very short:

<TextBox Text="{Binding}"/>

We’ll see some instances of when this might be useful in a future part of this blog series on binding when we look at collection-binding.

Summary

In this blog post we have looked at the binding markup extension and how this provides a concise mechanism for creating bindings. We have also seen how the DataContext, which is the default source for our bindings, plays a pivotal role in the Silverlight and WPF binding frameworks. Finally, we have seen how we can use bindings to ‘switch’ the DataContext in order to create binding ‘islands’ within out UI.

In the next instalment we’ll look at some of the other ways we can specify the binding source and when you might use them, but now we’ll take a well-earned break … see you next time.

You can download the sourcecode for the examples described in this blogpost: DatabindingExamplesPartTwo.zip

Regards, Colin E.

KnockoutJS vs. Silverlight – a new CodeProject article

April 12th, 2012

I have just published a new article over on CodeProject called “KnockoutJS vs. Silverlight”. It demonstrates the implementation of the same application using both frameworks, and seeks to answer the question “Which is better, Silverlight or Knockout?”

It’s a bit of an epic (6,500 words). I hope people find it useful!

Regards, Colin E.