<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>David Hill's WebLog : Helix</title><link>http://blogs.msdn.com/dphill/archive/tags/Helix/default.aspx</link><description>Tags: Helix</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Custom Content Loaders in Silverlight 4.0</title><link>http://blogs.msdn.com/dphill/archive/2009/12/24/custom-content-loaders-in-silverlight-4-0.aspx</link><pubDate>Thu, 24 Dec 2009 15:51:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9940972</guid><dc:creator>dphill</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/dphill/comments/9940972.aspx</comments><wfw:commentRss>http://blogs.msdn.com/dphill/commentrss.aspx?PostID=9940972</wfw:commentRss><description>&lt;p&gt;Silverlight 3.0 supports navigation by providing a Frame control into which you can load various pages as the user clicks on hyperlink controls in the application’s UI. Each page is specified by a Uri. As navigation takes place, the browser’s history and address bar is updated with this Uri. This allows the user to use the browser’s forward and back buttons to navigate around within the Silverlight application or to use deep links. You can map ‘friendly’ Uri’s to real page Uri’s so that the browser’s address bar doesn’t display the internal details of your application’s UI structure.&lt;/p&gt;  &lt;p&gt;The Silverlight 3.0 navigation framework has some very interesting capabilities, but it does have some limitations too. One of these limitations is that all of the pages that can be navigated to have to be defined in the application’s primary XAP file. For composite applications, that typically consist of multiple XAP files, this has proven to be quite a problem. Various workarounds have been proposed but they are all pretty clunky. The underlying problem is that the Silverlight 3.0 navigation framework doesn’t provide any extensibility hooks to implement this capability properly.&lt;/p&gt;  &lt;h4&gt;The Good News&lt;/h4&gt;  &lt;p&gt;Happily, this is about to change in Silverlight 4.0, which will allow you to specify a &lt;strong&gt;Content Loader &lt;/strong&gt;for each Frame instance:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; myFrame.ContentLoader = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CustomContentLoader();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The content loader is responsible for loading whatever content is associated with the target Uri. By giving folks the ability to create custom content loaders of their own, Silverlight 4.0’s navigation framework opens up some very interesting extensibility options. A custom content loader, for example, can remove the need for clunky shims and pass-through loader pages when navigating to pages located in other XAP files. They can also allow you to use navigation Uri’s which don’t necessarily have to map directly to UI content, or allow you to control the target page’s construction (so you can hook up it’s ViewModel), etc.&lt;/p&gt;

&lt;h4&gt;The Bad News&lt;/h4&gt;

&lt;p&gt;There is a rather large drawback with custom content loaders though: they are executed &lt;strong&gt;&lt;em&gt;asynchronously&lt;/em&gt;&lt;/strong&gt;. This makes them quite tricky to implement. A custom content loader implements the INavigationContentLoader interface which includes Begin and End methods and uses an IAsyncResult object to coordinate the asynchronous interaction between the Frame and the content loading logic. This asynchronous call pattern is known as the .NET Asynchronous Programming Model (APM). It’s &lt;em&gt;notoriously&lt;/em&gt; tricky to implement properly – not least of which because you have to account for the 3 or 4 ways in which the caller can execute the call, and you have to handle exceptions, cancellations and wait handles very carefully.&lt;/p&gt;

&lt;p&gt;So why is navigation executed asynchronously you may ask. That’s a very good question! I was involved in the early design discussions for the Silverlight navigation framework and argued against an asynchronous model for a couple of reasons. My main argument was that navigation invariably means you have to construct the new UI to which you’re navigating, and this has to happen &lt;em&gt;synchronously&lt;/em&gt; on the UI thread. My other argument&amp;#160; was to do with user experience – more on this later.&lt;/p&gt;

&lt;p&gt;Ah, yes, (so the counter-argument went) but what happens if you want to download some content/data from the host web site, or make a web service call, or load data from a database, or maybe do some complex calculation – you can’t tie up the UI thread! These are all valid things to do in an application of course, &lt;em&gt;just not within the navigation operation itself!!!&lt;/em&gt; Apart from anything else, these are pretty advanced scenarios and &lt;em&gt;by far &lt;/em&gt;the majority of navigation scenarios will just involve mapping Uri’s to UI content which just needs to be loaded (on the UI thread!!). In addition, all of these scenarios can be achieved fairly easily on top of a synchronous navigation model, &lt;em&gt;and &lt;/em&gt;in a way that makes for a better user experience too.&lt;/p&gt;

&lt;p&gt;Ok, rant over. I feel much better now :-) INavigationContentLoader is what it is. The Silverlight folks have worked hard to open up the navigation framework a little and given us a key extensibility point. We just have to try and leverage it as best we can…&lt;/p&gt;

&lt;p&gt;So, in this post I’ll describe the implementation of a base class (&lt;strong&gt;ContentLoaderBase&lt;/strong&gt;) that can be used to easily implement custom content loaders in Silverlight 4.0. You can use this base class to implement any number of different content loaders, including &lt;strong&gt;synchronous&lt;/strong&gt; content loaders or &lt;strong&gt;asynchronous&lt;/strong&gt; content loaders that download content in the background or that use a background thread for background processing. Hopefully this base class will provide you with a reasonable starting point for implementing whatever type of content loader you need in your application. At the end of this post I’ll talk briefly about how the &lt;strong&gt;ContentLoaderBase&lt;/strong&gt; base class works.&lt;/p&gt;

&lt;p&gt;You can download the sample code &lt;a href="http://dphill.members.winisp.net/Download/ContentLoaderSample.zip" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It’s built on Visual Studio 2010 Beta 2 and Silverlight 4.0 Beta. The sample shows how to configure and use various synchronous and asynchronous content loaders and their effect on navigation. You can switch between the sample content loaders in MainPage.xaml.cs.&lt;/p&gt;

&lt;h4&gt;Implementing a Synchronous Content Loader&lt;/h4&gt;

&lt;p&gt;The &lt;strong&gt;ContentLoaderBase&lt;/strong&gt; base class provides a small number of virtual methods. You can implement a synchronous or an asynchronous custom content loader simply by overriding the right methods. In the simple (and most common) case of an synchronous content loader, you simply need to override a single method – &lt;strong&gt;LoadContentSync&lt;/strong&gt; – which looks like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; LoadContentSync( Uri targetUri,&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt;                                            Uri currentUri )&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ControlOrPage();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;In this method you simply create or load whatever UI content you need based on the new (and maybe the current) Uri. You can do this in any number of ways – using a switch statement or using a lookup table for example. The important thing to note is that this method is called on the UI thread so you don’t have to worry about creating UI content or making cross-thread calls.&lt;/p&gt;

&lt;p&gt;Of course, since the call is made on the UI thread, you shouldn’t do crazy things like make a network call or do a lengthy calculation in this method. If you need to do anything like that then you &lt;em&gt;may&lt;/em&gt; need an asynchronous content loader (though I’ll argue later that even if you do need to do anything like this you shouldn’t do it during navigation). In the meantime here’s how you can do it using the &lt;strong&gt;ContentLoaderBase&lt;/strong&gt; class…&lt;/p&gt;

&lt;h4&gt;Implementing an Asynchronous Content Loader&lt;/h4&gt;

&lt;p&gt;You can implement an asynchronous content using the &lt;strong&gt;ContentLoaderBase&lt;/strong&gt; class by overriding two virtual methods (and implementing one or two callbacks). The first method to override is the &lt;strong&gt;GetLoadBehavior&lt;/strong&gt; method which defines whether the navigation operation for a particular Uri is synchronous or asynchronous (the default value is synchronous which is why we didn’t need to override this method in the synchronous case above).&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; LoadBehavior GetLoadBehavior( Uri targetUri )&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// Content is loaded asynchronously for all Uris.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; LoadBehavior.Asynchronous;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;In this example, navigation for all Uri’s is asynchronous, though we could of course have some Uri’s handled synchronously and some handled asynchronously (which is useful when, for example, we’ve cached content that was previously downloaded asynchronously so that subsequent navigations can be handled synchronously).&lt;/p&gt;

&lt;p&gt;The other method you need to override is the &lt;strong&gt;LoadContentAsync&lt;/strong&gt; method. This is where you initiate whatever asynchronous operation you need. When that operation is completed, you simply need to call the &lt;strong&gt;LoadContentAsyncComplete &lt;/strong&gt;method in the base class to complete the navigation operation.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; LoadContentAsync(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt;                     ContentLoaderAsyncResult asyncResult )&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// Initiate asynchronous operation here...&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// When the asynchronous operation is completed, call the&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// LoadContentAsyncComplete method on the base class to&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// complete the navigation operation.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Broadly speaking, there are two types of asynchronous operations that you &lt;em&gt;might &lt;/em&gt;want to do when loading content during a navigation operation. The first involves downloading some form of content, data or configuration from the host web site. The second involves performing some form of processing or calculation on a background thread.&lt;/p&gt;

&lt;p&gt;Either way, once the async operation is completed you will still need to load or create the actual UI content to which you’re navigating on the UI thread. The way you do that in each of these two scenarios are slightly different and may require you to implement one or more callbacks. Let’s look at each of these scenarios in turn…&lt;/p&gt;

&lt;h4&gt;Downloading Content During Navigation&lt;/h4&gt;

&lt;p&gt;Retrieving or sending data from the host web site is a common scenario in Silverlight. The Silverlight WebClient class makes this fairly straightforward by providing an asynchronous event-based callback mechanism – you can start the download or upload process and the WebClient class will call you back when its complete. They key feature of this class is that the callback happens on the &lt;em&gt;UI thread&lt;/em&gt;, which in turn means that you don’t have to worry about cross-thread UI access. It’s a pity that the navigation framework didn’t adopt the same event-driven approach… Ho hum…&lt;/p&gt;

&lt;p&gt;To use the WebClient class in a content loader, we simply need to start a download process (or whatever we need) in the LoadContentAsync method and specify a callback method. Since the callback method is called on the UI thread we can load or create whatever UI content we need there. The completed sample looks something like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; LoadContentAsync(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt;                             ContentLoaderAsyncResult asyncResult )&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// Use the WebClient class to download a file from the&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// web server. This is an asynchronous method call and&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// will return immediately.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;     webClient.OpenReadAsync(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Uri( &lt;span style="color: #006080"&gt;&amp;quot;NavigationData.xml&amp;quot;&lt;/span&gt;, UriKind.Relative ),&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt;                 asyncResult );&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnOpenReadCompleted( Object sender,&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt;                                   OpenReadCompletedEventArgs e )&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt;  14:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt;  15:&lt;/span&gt;     ContentLoaderAsyncResult asyncResult =&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt;  16:&lt;/span&gt;                     (ContentLoaderAsyncResult)e.UserState;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt;  17:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt;  18:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// Since the WebClient callback is on the UI thread,&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt;  19:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// we can create the UI we're navigating to here.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt;  20:&lt;/span&gt;     Object content = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ControlOrPage();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum21"&gt;  21:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum22"&gt;  22:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// Inform the base class that the async request has&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum23"&gt;  23:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// been completed.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum24"&gt;  24:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.LoadContentAsyncComplete( content, asyncResult );&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum25"&gt;  25:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Notice how the UI content&amp;#160; that was created in the callback method is passed back to the base class via the LoadContentAsyncComplete method call. The base class then completes the asynchronous navigation operation and passes the content to the Frame.&lt;/p&gt;

&lt;h4&gt;Background Processing During Navigation&lt;/h4&gt;

&lt;p&gt;The other scenario where you might want to use an asynchronous content loader is where you want to use a background thread to perform some kind of calculation or background process. In this case, the &lt;strong&gt;LoadContentAsync&lt;/strong&gt; method might look something like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; LoadContentAsync(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt;                             ContentLoaderAsyncResult asyncResult )&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// Use the thread pool to queue up a background operation.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;     ThreadPool.QueueUserWorkItem( BackgroundTask, asyncResult );&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Where BackgroundTask is the method that defines the background process. This method will of course be called on the background thread, not the UI thread, so when the calculation is finished how do we load the UI content that we need to navigate to? To do that, when we inform the base class that the calculation has finished, we provide &lt;em&gt;another &lt;/em&gt;callback. The base class makes sure that this callback will be called on the UI thread so we can load our UI content there. The completed sample looks something like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; BackgroundTask( Object state )&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;     ContentLoaderAsyncResult asyncResult =&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;                 (ContentLoaderAsyncResult)state;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// Simulate some lengthy calculation or process.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;     Thread.Sleep( 4000 );&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// We can't create the necessary UI content&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// here because we're on a background thread.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// So we create the UI in a callback method.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// The base class will call the callback on the UI thread.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.LoadContentAsyncComplete( LoadContentUICallback,&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt;  14:&lt;/span&gt;                                    asyncResult, asyncResult );&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt;  15:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt;  16:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt;  17:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Object LoadContentUICallback( Object callbackState )&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt;  18:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt;  19:&lt;/span&gt;     Debug.WriteLine( &lt;span style="color: #006080"&gt;&amp;quot;LoadContentUICallback&amp;quot;&lt;/span&gt; );&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt;  20:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum21"&gt;  21:&lt;/span&gt;     ContentLoaderAsyncResult asyncResult =&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum22"&gt;  22:&lt;/span&gt;                 (ContentLoaderAsyncResult)callbackState;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum23"&gt;  23:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum24"&gt;  24:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// Since THIS callback is on the UI thread, we can&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum25"&gt;  25:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// create the UI we're navigating to here.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum26"&gt;  26:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ControlOrPage();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum27"&gt;  27:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h4&gt;TODO: Cancelation&lt;/h4&gt;

&lt;p&gt;The above code snippets are simplified a little to show you the essentials. If you have an asynchronous content loader you will find that a navigation operation will often be canceled. To implement an asynchronous content loader properly you will therefore have to account for cancelation.&lt;/p&gt;

&lt;p&gt;Why is navigation canceled so often? Because the navigation framework does not provide any built-in mechanism to give feedback to the user during an asynchronous navigation operation. Since the user &lt;em&gt;expects &lt;/em&gt;navigation to be instantaneous, they have a tendency to click the navigate button or hyperlink control multiple times, and each time they do, the previous navigation operation will be cancelled. So it’s very important to handle cancellations properly, otherwise you can easily run into tricky-to-handle exceptions during navigation. The irony of course, is that asynchronous navigation was meant to improve the user experience…&lt;/p&gt;

&lt;p&gt;To illustrate the effects of network latency or lengthy processing during navigation, the sample code includes artificial delays. For the download sample, a HTTP handler is used to introduce an artificial delay during the download of the dummy file. Similarly, the background thread sample includes a 3 second Thread.Sleep in the background task method.&lt;/p&gt;

&lt;p&gt;When navigation is asynchronous, you’ll quickly notice that clicking on the navigation links during an existing navigation operation will cause the previous navigation operation to be canceled. The sample code shows how you might handle this situation but there are some complications that have not yet been ironed out (see the comments in the code for more details). In the download case you will need to somehow cancel the previous download operation. In the background thread case you will have to find a way to abort or cancel the calculation or background process gracefully if navigation is cancelled…&lt;/p&gt;

&lt;h4&gt;ContentLoaderBase Class Implementation Details&lt;/h4&gt;

&lt;p&gt;The key to the ContentLoaderBase Class is the object that implements the IAsyncResult interface. For that I leveraged the excellent coding skills of Jeffery Richter and his MSDN magazine article (&lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163467.aspx" target="_blank"&gt;here&lt;/a&gt;) from a few years back. That article and the accompanying code, describes many of the subtle details that you have to worry about when implementing the APM. With the IAsycnResult object implemented properly, the ContentLoaderBase class ‘simply’ has to make sure that the right virtual methods are called in the right order and that the LoadContentUICallback is executed on the UI thread.&lt;/p&gt;

&lt;h4&gt;An Easier Approach&lt;/h4&gt;

&lt;p&gt;The ContentLoaderBase class simplifies things quite a bit, especially when implementing a synchronous content loader. But I think you can probably see that asynchronous content loaders are still a little complicated to implement properly. I’m sure that I have not even begun to iron out all of the subtle issues that inevitably show up when you’re doing anything asynchronously (e.g. cancelation as noted above).&lt;/p&gt;

&lt;p&gt;For reasons of complexity, plus the bad user experience that can result, I would recommend using only &lt;em&gt;synchronous&lt;/em&gt; content loaders wherever possible. But what about those situations where you &lt;em&gt;absolutely &lt;/em&gt;need to download or calculate something during navigation? My advice is to do these things &lt;em&gt;outside&lt;/em&gt; of the navigation framework and to do them &lt;em&gt;in the target page itself&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So for example, for the two scenarios above, you would navigate to a page (synchronously) that will then download the content or perform the calculation (in its ViewModel of course). Furthermore, while the page is downloading the content or performing the calculation, it can provide visual feedback to the user! To the user, the navigation is instantaneous, even though the target page might take a while to initialize itself. By providing visual feedback while this happens you will likely prevent the user from getting frustrated and repeatedly clicking the navigate button or link.&lt;/p&gt;

&lt;p&gt;I’ll explore this approach, plus some other interesting things you can do with a custom content loader, in a future post…&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9940972" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/dphill/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.msdn.com/dphill/archive/tags/Helix/default.aspx">Helix</category></item><item><title>The Breadcrumb Navigation Pattern</title><link>http://blogs.msdn.com/dphill/archive/2009/10/15/the-breadcrumb-navigation-pattern.aspx</link><pubDate>Thu, 15 Oct 2009 22:16:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9907866</guid><dc:creator>dphill</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/dphill/comments/9907866.aspx</comments><wfw:commentRss>http://blogs.msdn.com/dphill/commentrss.aspx?PostID=9907866</wfw:commentRss><description>&lt;p&gt;The Breadcrumb Navigation pattern provides a visual representation of the path the user took as they navigated to a particular state in an application. It provides context so the user can see where they are logically within the application structure, and it allows them to quickly navigate that structure by jumping straight to previous breadcrumbs.&lt;/p&gt;  &lt;p&gt;Perhaps the most common example of the breadcrumb navigation pattern is Windows Explorer – as you navigate the file system, the breadcrumb control at the top of window displays the path to the current folder, with each folder in the chain displayed as a button. You can jump directly to any of the parent folders by clicking on it.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/TheBreadcrumbNavigationPattern_8E11/clip_image001_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/TheBreadcrumbNavigationPattern_8E11/clip_image001_thumb.jpg" width="454" height="114" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You often see the pattern used in web sites, especially ones where the user is navigating through a lot of hierarchical data. For example, a lot of ecommerce site allows the user to browse the product catalog by drilling into product categories and by specifying search criteria and filters. Here’s a good example from &lt;a href="http://www.guitarcenter.com/" target="_blank"&gt;GuitarCenter.com&lt;/a&gt; – you can navigate around within the product catalog by product category and filter the view by price or manufacturer.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/TheBreadcrumbNavigationPattern_8E11/clip_image002_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/TheBreadcrumbNavigationPattern_8E11/clip_image002_thumb.jpg" width="454" height="32" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;The Breadcrumb Navigation Pattern in Helix&lt;/h3&gt;  &lt;p&gt;This post describes how you can implement the breadcrumb navigation pattern in Helix, my prototype navigation framework for Silverlight. You can download the latest version of Helix from &lt;a href="http://dphill.members.winisp.net/Download/Helix-Navigation-0.4.zip" target="_blank"&gt;here&lt;/a&gt;, and run the sample described below &lt;a href="http://dphill.members.winisp.net/BreadcrumbSample.html" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;h4&gt;The BreadcrumbBar Control&lt;/h4&gt;  &lt;p&gt;Implementing the Breadcrumb Navigation pattern in Helix turned out to be quite straightforward. The main element is the BreadcrumbBar control. This control displays the breadcrumbs as the user navigates within an associated Frame. The user can click on any of the breadcrumbs causing the associated Frame to navigate back to the corresponding point in the navigation history. &lt;/p&gt;  &lt;p&gt;The BreadcrumbBar control is actually a sub-classed and re-templated ListBox control that is bound to the target Frame's journal. As the user navigates between Pages in the target Frame, journal entries are added to the journal. Each journal entry is represented in the BreadcrumbBar control as a ListBox item. The BreadcrumbBar control's template displays each item horizontally as a chevron, along with the corresponding page title. The most difficult part to getting this to work is the control template itself. I used Blend 3.0 to edit the template so even that wasn't that difficult. I also made a couple of changes to the Helix library itself to support breadcrumb style navigation in the Journal. More details on this below.&lt;/p&gt;  &lt;h4&gt;The Sample Application&lt;/h4&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/TheBreadcrumbNavigationPattern_8E11/clip_image004_2.jpg"&gt;&lt;img style="border-right-width: 0px; margin: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/TheBreadcrumbNavigationPattern_8E11/clip_image004_thumb.jpg" width="454" height="175" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Patterns &amp;amp; practices guidance is organized by four high-level focus areas – Fundamentals, Client, Server and Services. Within each area there can be a number of sub-categories (such as security, performance, etc), and within sub-categories there is the guidance itself. Since the catalog is hierarchical, it’s a natural fit for the breadcrumb navigation pattern. I’ll describe a simple application that uses the BreadcrumbBar control and Helix to allow the user to browse through the patterns &amp;amp; practices guidance catalog. You can see the completed application and the BreadcrumbBar control in action &lt;a href="http://dphill.members.winisp.net/BreadcrumbSample.html" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;This is a simple application that has a simple shell that contains a BreadCrumbBar control and a Frame control in a grid:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;BreadcrumbBar&lt;/span&gt; &lt;span class="attr"&gt;Grid&lt;/span&gt;.&lt;span class="attr"&gt;Row&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;       &lt;span class="attr"&gt;NavigationTarget&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{Binding ElementName=frame}&amp;quot;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;       &lt;span class="attr"&gt;ClearForwardStack&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;False&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Frame&lt;/span&gt; &lt;span class="attr"&gt;x:Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;frame&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Grid&lt;/span&gt;.&lt;span class="attr"&gt;Row&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;2&amp;quot;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="attr"&gt;NavigationUIVisibility&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Hidden&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;InitialUri&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;HomePage&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;The BreadcrumbBar control is connected to the target Frame through simple data binding. Since we’re using the BreadcrumbBar control we don’t need the Frame’s back/forward buttons so we can hide the Frame’s navigation UI. The Frame navigates to the HomePage on startup. That’s pretty much it. I’ll talk about the ClearForwardStack below. You can tweak some of the visual aspects of the BreadcrumbBar control, or even replace the control template, to suit your application’s UI style.&lt;/p&gt;

&lt;h4&gt;How Does It Work?&lt;/h4&gt;

&lt;p&gt;The BreadcrumbBar control is just a sub-classed and re-templated ListBox. When the NavigationTarget property value is set, it sets the base class ItemSource to the journal back stack.&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;this&lt;/span&gt;.ItemsSource = NavigationTarget.Journal.BackStack;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;If the user changes the current selection (i.e. by clicking on a previous breadcrumb), the target Frame is navigated to the associated Uri. To support this I added two new methods to the IJournal interface – GoBackTo and GoForwardTo. These two methods allow the journal to navigate directly to an entry that’s in the back stack or the forward stack, without having to navigate backwards or forwards multiple times.&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;NavigationTarget.Journal.GoBackTo( entry, ClearForwardStack );&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Two other things to note:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The current selection of the underlying ListBox tracks the last entry in the journal. In other words, as the user navigates to new pages within the Frame, a journal entry for it is added and it becomes the current selection in the BreadcrumbBar control. 
    &lt;br /&gt;&lt;/li&gt;

  &lt;li&gt;The ClearForwardStack parameter is used to control how the journal’s forward stack is affected when the user clicks on a previous breadcrumb. Most often you’ll want the forward stack to be cleared, and this is the default. Sometimes you might want to keep the forward stack intact so the user can go forward again. To enable this, just set the ClearForwardStack parameter to false. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;What’s Next For Helix?&lt;/h3&gt;

&lt;p&gt;Now that Silverlight 3.0 supports navigation, the need for Helix is not as great as it was. I actually wrote the original specs for the Silverlight 3.0 Navigation feature. The original design in fact was very similar to Helix, but due to a number of constraints the design evolved and became a little less extensible than originally planned. There are key extensibility points that Helix provides which enable a whole host of interesting scenarios that are difficult or impossible to achieve with the current Silverlight navigation implementation. I’ve really only scraped the surface of these in this series so I’ll continue to evolve Helix in order to explore these scenarios. I’m working with the Silverlight team to explore ways in which these key extensibility points can be opened up in upcoming Silverlight releases.&lt;/p&gt;

&lt;p&gt;In the meantime, if you’re building a Silverlight application that requires navigation functionality, you should use the Silverlight 3.0 navigation framework since it’s robust and fully supported. Hopefully, the need for Helix will go away altogether once the Silverlight navigation framework is more extensible.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9907866" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/dphill/archive/tags/Patterns+and+Practices/default.aspx">Patterns and Practices</category><category domain="http://blogs.msdn.com/dphill/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.msdn.com/dphill/archive/tags/Helix/default.aspx">Helix</category></item><item><title>Blend Behaviors</title><link>http://blogs.msdn.com/dphill/archive/2009/09/25/blend-behaviors.aspx</link><pubDate>Sat, 26 Sep 2009 02:18:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9899750</guid><dc:creator>dphill</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/dphill/comments/9899750.aspx</comments><wfw:commentRss>http://blogs.msdn.com/dphill/commentrss.aspx?PostID=9899750</wfw:commentRss><description>&lt;p&gt;Expression Blend 3 includes a number of very cool new features (see &lt;a href="http://www.microsoft.com/expression/products/Blend_Features.aspx" target="_blank"&gt;here&lt;/a&gt; for a good summary). But there are two that I think are particularly important – SketchFlow Rapid Prototyping, and Blend Behaviors. I’ll cover SketchFlow in some depth in a future post. In this post I’m going to talk about Blend behaviors and how they can be used to extend Helix, my prototype Silverlight navigation framework.&lt;/p&gt;  &lt;h4&gt;What Are Behaviors?&lt;/h4&gt;  &lt;p&gt;Behaviors are objects that encapsulate some form of interactive behavior. Blend allows them to be easily 'attached’ to visual elements in the UI, via drag-drop or declaratively in XAML. They enable developers or designers to rapidly add rich interactivity to the UI without having to write code.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/BlendBehaviors_8E68/image_2.png"&gt;&lt;img style="border-right-width: 0px; margin: 5px 10px 5px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" align="left" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/BlendBehaviors_8E68/image_thumb.png" width="244" height="212" /&gt;&lt;/a&gt; Blend 3 ships with a number of behaviors (shown left) that allow you to easily animate an element, change it’s visual state, start/stop a storyboard, play sounds, etc.&lt;/p&gt;  &lt;p&gt;However, the key thing is that Blend allows you to create new behaviors of your very own. And not only that, but when you do they will automatically show up in the Blend toolbox ready for use by a developer or a UI designer.&lt;/p&gt;  &lt;p&gt;There is also an Expression Gallery &lt;a href="http://gallery.expression.microsoft.com/en-us/site/search?f%5B0%5D.Type=Tag&amp;amp;f%5B0%5D.Value=Behavior" target="_blank"&gt;here&lt;/a&gt; dedicated to community developed behaviors, so if you develop a particularly cool behavior you can readily share it with other Blend users.&lt;/p&gt;  &lt;h4&gt;Behaviors – Think XAML Extension Methods!&lt;/h4&gt;  &lt;p&gt;The implementation details and concepts behind Blend behaviors are pretty simple. They leverage the simple but powerful ‘attached property’ mechanism in WPF and Silverlight. Instead of attaching a simple value though (like Grid.Row=”2”) you’re attaching an object that encapsulates behavior. Such objects are sometimes called Attached Behaviors. They provide an elegant way to extend existing controls without having to modify the control’s code or it’s UI template. I like to think of attached behaviors as the XAML equivalent of extension methods in C#.&lt;/p&gt;  &lt;p&gt;Developers have been using attached behaviors for quite a while now as a way of extending Silverlight and WPF. In fact, they are pretty much the only way that you &lt;em&gt;can&lt;/em&gt; extend Silverlight, since it lacks a number of other key extensibility mechanisms (such as custom markup extensions). As such, they’ve proven to be a very useful way to add missing functionality to Silverlight.&lt;/p&gt;  &lt;p&gt;For example, since Silverlight controls do not (yet) inherently support commanding, we used this technique in Prism for wiring up button-derived controls to commands on the ViewModel:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;prism:Click&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;{Binding ViewOrdersCommand}&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;I also used this technique in Helix to implement CollectionView support (now thankfully redundant since it’s supported in Silverlight 3.0).&lt;/p&gt;

&lt;p&gt;Both Prism and Helix provide base classes that allow you to more easily create attached behaviors, and there are a number of other third party behavior frameworks that you can use too. But now that we have the Blend Behaviors Framework, we can hopefully all standardize on a single framework.&lt;/p&gt;

&lt;h4&gt;Triggers, Actions and Behaviors&lt;/h4&gt;

&lt;p&gt;Blend behaviors actually come in two main flavors – Actions and what I’ll call Full Behaviors.&lt;/p&gt;

&lt;p&gt;Actions are simple behaviors that encapsulate an action (believe it or not) that are associated with a trigger. You can use an action and trigger pair to make something happen as the result of an event fired by the parent control. You can, for example,&amp;#160; change a property value, control a storyboard, play a sound, or cause a control to move to a particular visual state as the result of a Click, MouseLeave, MouseEnter, MouseLeftButtonDown event, or any other event that the parent control fires.&lt;/p&gt;

&lt;p&gt;Here’s a simple example – when the user moves the mouse over the image, the opacity property is changed to 0.5:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;MyImage.png&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;i:Interaction.Triggers&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;      &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;i:EventTrigger&lt;/span&gt; &lt;span style="color: #ff0000"&gt;EventName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;MouseEnter&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;          &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ic:ChangePropertyAction&lt;/span&gt; &lt;span style="color: #ff0000"&gt;PropertyName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Opacity&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;0.5&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;      &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;i:EventTrigger&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;i:Interaction.Triggers&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;You could of course choose a different event to trigger the action, or choose a different property to change. Blend makes it very easy to drag an action onto a control and to configure it to do what you want.&lt;/p&gt;

&lt;p&gt;Some actions operate solely on the parent control that the trigger is connected to. Some actions can operate on a control other than the parent. These actions are called Targeted Actions. If no target is explicitly specified, the target defaults to the parent control.&lt;/p&gt;

&lt;p&gt;You’ll notice that the EventTrigger is added to a triggers collection. That means you can add as many triggers to a control as you like. Other types of triggers are possible too, not just ones that are associated with the target control’s events. For example, you can imagine using mouse/stylus gestures as triggers, etc.&lt;/p&gt;

&lt;p&gt;Full behaviors are useful for encapsulating more complex interactive behavior that aren’t necessarily associated with a single trigger. The following example uses one of the coolest behaviors that Blend provides – the MouseDragElementBehavior. By simply attaching this behavior to a control, you can allow the user to drag it around in the UI!&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;MyImage.png&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;i:Interaction.Behaviors&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;il:MouseDragElementBehavior&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ConstrainToParentBounds&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;True&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;i:Interaction.Behaviors&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Again, you’ll notice that it gets added to a behavior collection, so you can have multiple behaviors on a single control.&lt;/p&gt;

&lt;p&gt;Blend provides an assembly, &lt;strong&gt;System.Windows.Interactivity&lt;/strong&gt;, that contains a number of base classes that you can use to define your own triggers, actions and behaviors. Simply add a reference to this assembly to your project (you’ll find it in the ‘C:\Program Files\Microsoft SDKs\Expression\Blend 3\Interactivity\Libraries\Silverlight|WPF’ directory or thereabouts) and away you go. Any triggers, actions, or behaviors that you define will automatically be available in the Blend toolbox. Let’s see this in action…&lt;/p&gt;

&lt;h4&gt;A Custom Action&lt;/h4&gt;

&lt;p&gt;Some of you may have been following my series of posts on the Helix navigation framework for Silverlight. If so, you’ll know that Helix provides a NavigateLink control that you can use within a page to link to another page that the user can navigate to. The NavigateLink control derives from Silverlight’s HyperlinkButton control. It’s a very simple control – the only thing is really does is to fire a navigate event up the visual tree so that it can be handled by a Frame control which then manages the actual navigation.&lt;/p&gt;

&lt;p&gt;But what if you don’t want to use a NavigateLink button control to initiate navigation? Say you want to navigate using a different control, like an Image or a ListBox, or in response to a different event than Click, like MouseEnter/Leave or SelectionChanged? Well, now you can with the HelixNavigateAction!&lt;/p&gt;

&lt;p&gt;The HelixNavigateAction class is pretty simple. It derives from the Blend TargetedTriggerAction class – the target in this case is a Frame so you can initiate navigation on a specific frame. It defines two dependency properties, NavigateUri and NavigationParameter. The overridden Invoke method is the only interesting part of this class and is shown below.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Invoke( &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; parameter )&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    Uri navigationUri = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.NavigateUri;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// Navigate to the specified Uri.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ( &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.NavigateUri != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; )&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// See if we have to format the navigation Uri with&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// any parameters.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        ...&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// See if the target frame has been specified explicitly.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// If not, bubble a request navigate event through the visual tree.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        Frame frame = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Target &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; Frame;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ( frame != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; )&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            frame.Navigate( navigationUri );&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #008000"&gt;// Bubble the RequestNavigate event to the nearest&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #008000"&gt;// parent Frame.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            UIElement parent = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AssociatedObject &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; UIElement;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            parent.RaiseEvent(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;              Microsoft.Samples.Helix.Controls.Frame.RequestNavigateEvent,&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;              &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RequestNavigateEventArgs( navigationUri, TargetName ) );&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;As you can see, we first check to see if a target Frame has been specified. If it has, we call the Navigate method on it directly. If not, then we raise a RequestNavigate event which will bubble up through the visual tree until a containing Frame control is found. That’s pretty much it. In the next section we’ll see how we can use the HelixNavigateAction class in Blend.&lt;/p&gt;

&lt;table style="border-bottom: #808000 thin solid; border-left: #808000 thin solid; border-top: #808000 thin solid; border-right: #808000 thin solid" border="0" cellspacing="0" cellpadding="8" width="80%" bgcolor="#bdb76b" frame="border" align="center"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="100%"&gt;While creating actions in Blend is fairly straightforward, there are a couple of wrinkles to be aware of… 
        &lt;br /&gt;

        &lt;br /&gt;If you look closely at the classes provided in the System.Windows.Interactivity namespace, you’ll see that there are two main action classes – TriggerAction&amp;lt;T&amp;gt; and TargetedTriggerAction&amp;lt;T&amp;gt;. Both ultimately derive from the TriggerAction base class. Now you’d probably think that the generic parameter &amp;lt;T&amp;gt; in each of these classes would specify the same kind of type. 

        &lt;br /&gt;

        &lt;br /&gt;Well, it seems that the &amp;lt;T&amp;gt; in TriggerAction&amp;lt;T&amp;gt; specifies the type of &lt;strong&gt;&lt;u&gt;Associated&lt;/u&gt;&lt;/strong&gt; (parent) control, but the &amp;lt;T&amp;gt; in TargetedTriggerAction&amp;lt;T&amp;gt; specifies the type of the &lt;strong&gt;&lt;u&gt;Target&lt;/u&gt;&lt;/strong&gt; control. For a TargetedTriggerAction, to constrain the type of the parent control, you have to add a TypeContstraint attribute to the class: 

        &lt;br /&gt;

        &lt;br /&gt;

        &lt;div id="codeSnippetWrapper"&gt;
          &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
            &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;[TypeConstraint( &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;( UIElement ) )]&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
        &lt;/div&gt;

        &lt;br /&gt;Not sure why they did it like this… This design seems a little weird to me. I would have thought something like TargetedTriggerAction&amp;lt;A,T&amp;gt; would have worked better, then you could specify the types of the Associated and Target controls in the same consistent way… 

        &lt;br /&gt;

        &lt;br /&gt;The other thing to be aware of is that, if a Target value is not explicitly defined for an Action, the Target property will be set to the Associated parent control instance. This means that the type of the Target has to be &lt;strong&gt;&lt;u&gt;assignable&lt;/u&gt;&lt;/strong&gt; to the type of the Associated control. For example, we’d ideally like our HelixNavigateAction class to target Frame controls, but be associated with any type of control. Something like this: 

        &lt;br /&gt;

        &lt;br /&gt;

        &lt;div id="codeSnippetWrapper"&gt;
          &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
            &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;[TypeConstraint( &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;( UIElement ) )]  &amp;lt;- Type of Associated Control&lt;/pre&gt;
&lt;!--CRLF--&gt;

            &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; HelixNavigateAction :&lt;/pre&gt;
&lt;!--CRLF--&gt;

            &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        TargetedTriggerAction&amp;lt;Frame&amp;gt; &amp;lt;- Type of Target Control&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
        &lt;/div&gt;

        &lt;br /&gt;This won’t work unfortunately since if a Target is not explicitly specified, it will be assigned the Associated control (which is probably not a Frame) so an InvalidOperation exception will be thrown at runtime. Again, not sure why they did it like this. I would have thought that leaving Target as null if it hadn’t been explicitly specified would have worked better. Yes, you’d have to check for null and then perform the action on the Associated object (maybe) but you’d have much more control and flexibility… Ho hum… 

        &lt;br /&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;h4&gt;HelixNavigateAction In Action&lt;/h4&gt;

&lt;p&gt;So with our newly minted HelixNavigateAction class all compiled, let’s put it through it’s paces in Blend. You can download the sample project (including the latest version of Helix) &lt;a href="http://dphill.members.winisp.net/Download/Helix-Navigation-0.31.zip" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We’ll start with a simple app with main screen that contains a frame (the big area on the left) and four headline controls (on the right).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/BlendBehaviors_8E68/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/BlendBehaviors_8E68/image_thumb_1.png" width="404" height="296" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We’re going to use the HelixNavigateAction to navigate the frame to various pages as the user clicks on the headline controls on the right. If you click on the Assets tab and then on Behaviors, you will see a list of Behaviors and Actions that you can use. You’ll notice that the HelixNavigateAction is already there for us!&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/BlendBehaviors_8E68/image_8.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/BlendBehaviors_8E68/image_thumb_3.png" width="404" height="144" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Simply drag the HelixNavigateAction over and drop it one of the headline controls on the right hand side of the main screen. You see the action get added to the object tree and the property grid will show various trigger and action properties. Let’s setup the trigger first by choosing the MouseLeftButtonDown event in the EventName dropdown. Next, we’ll set the target. For this we can use the rather nifty target picker! You just click on the round target icon and then click on the Frame and hey presto! the TargetName property is filled in:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/BlendBehaviors_8E68/image_14.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/BlendBehaviors_8E68/image_thumb_6.png" width="404" height="117" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Finally, we just have to specify the Uri to navigate to. For that we simply use the dropdown on the NavigateUri property and select whichever page we want to navigate to:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/BlendBehaviors_8E68/image_16.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/BlendBehaviors_8E68/image_thumb_7.png" width="417" height="287" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Repeat for the other three controls and that’s it, we’re all done! For grins, change the trigger event to MouseEnter to get a ‘hot-spot’ navigation effect. You can run the completed app &lt;a href="http://dphill.members.winisp.net/BlendBehaviorSample.html" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With Blend and the Blend Behaviors Framework we have a pretty powerful and flexible way to create re-usable components that encapsulate interactive behavior and a way to use them to snap together an application very rapidly.&lt;/p&gt;

&lt;p&gt;I’ve only really scratched the surface here. There are plenty of other cool and powerful things that we can do with behaviors. Also, it may be that we can leverage this framework in the next release of Prism, and thereby replace our implementation in favor of the Blend implementation. Not only will this reduce the amount of code in Prism, it will also allow us to leverage the built-in design-time support that Blend provides…&lt;/p&gt;

&lt;h4&gt;Helix&lt;/h4&gt;

&lt;p&gt;I made a few small changes to the Helix framework to support the use of Blend Behaviors. I also updated the samples for Silverlight 3.0. You can download the latest version &lt;a href="http://dphill.members.winisp.net/Download/Helix-Navigation-0.31.zip" target="_blank"&gt;here&lt;/a&gt; (version 0.31).&lt;/p&gt;

&lt;h4&gt;Blend Behavior Resources&lt;/h4&gt;

&lt;p&gt;You might find the following resources useful as you explore Blend and the Blend Behaviors Framework:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The Expression Blend home page: &lt;a title="http://expression.microsoft.com/en-us/cc136530.aspx" href="http://expression.microsoft.com/en-us/cc136530.aspx"&gt;http://expression.microsoft.com/en-us/cc136530.aspx&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;Expression Behavior Gallery: &lt;a title="http://gallery.expression.microsoft.com/en-us/site/search?f%5B0%5D.Type=Tag&amp;amp;f%5B0%5D.Value=Behavior" href="http://gallery.expression.microsoft.com/en-us/site/search?f%5B0%5D.Type=Tag&amp;amp;f%5B0%5D.Value=Behavior"&gt;http://gallery.expression.microsoft.com/en-us/site/search?f%5B0%5D.Type=Tag&amp;amp;f%5B0%5D.Value=Behavior&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;Christian Schormann’s posts on Behaviors: &lt;a title="http://electricbeach.org/?cat=30" href="http://electricbeach.org/?cat=30"&gt;http://electricbeach.org/?cat=30&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;Kirupa Chinnathambi’s posts on Behaviors: &lt;a title="http://blog.kirupa.com/?cat=18" href="http://blog.kirupa.com/?cat=18"&gt;http://blog.kirupa.com/?cat=18&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9899750" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/dphill/archive/tags/Prism/default.aspx">Prism</category><category domain="http://blogs.msdn.com/dphill/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.msdn.com/dphill/archive/tags/Helix/default.aspx">Helix</category><category domain="http://blogs.msdn.com/dphill/archive/tags/Blend/default.aspx">Blend</category></item><item><title>ViewModel and Dependency Injection</title><link>http://blogs.msdn.com/dphill/archive/2009/05/18/viewmodel-and-dependency-injection.aspx</link><pubDate>Mon, 18 May 2009 22:28:23 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9625816</guid><dc:creator>dphill</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/dphill/comments/9625816.aspx</comments><wfw:commentRss>http://blogs.msdn.com/dphill/commentrss.aspx?PostID=9625816</wfw:commentRss><description>&lt;p&gt;In my last post – &lt;a href="http://blogs.msdn.com/dphill/archive/2009/04/28/silverlight-navigation-part-3.aspx"&gt;Silverlight Navigation Part 3&lt;/a&gt; – I outlined a mechanism whereby you could navigate to a View and have the application create and wire up the associated ViewModel automatically. I also showed the inverse of this, where you could navigate to a ViewModel and have the application automatically create and wire up the associated View automatically.&lt;/p&gt;  &lt;p&gt;Whether you prefer the View-First or the ViewModel-First approach, the essential feature that really supports the ViewModel pattern is that the system should be able to create a ViewModel for a View (or vice versa) automatically. Otherwise, the burden falls to the developer to do this in code, which can result in a complicated architecture that’s either inflexible or difficult to understand and maintain.&lt;/p&gt;  &lt;p&gt;Let’s say, for example, that you have adopted a View-First approach. Now, you could just have some code in your application (say, in a controller component or event handler somewhere) that simply creates the required View and it’s associated ViewModel and wires them together like this:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ShowCustomer()&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    CustomerView view = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CustomerView();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    CustomerViewModel viewModel = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CustomerViewModel();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    view.DataContext = viewModel;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    myContentControl.Content = view;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;You can use this approach with a ViewModel-First approach too. Another simple approach is to just get the View to create its own ViewModel, either in its constructor:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; CustomerView : UserControl&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; CustomerView()&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        InitializeComponent();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DataContext = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CustomerViewModel();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;or via XAML:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;UserControl.DataContext&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CustomerViewModel&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;UserControl.DataContext&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;All three of these approaches work great, except that they hard code your application to use specific View and ViewModel types. This may very well not be an issue for you, and if it isn’t, I say go for it!&lt;/p&gt;

&lt;p&gt;However, there are times when you’ll want to have the View and the ViewModel types more loosely coupled. An example might be when you want to decide at run-time which View to display for a particular ViewModel based on, say, the user’s role, chosen UI theme, screen size, or even the type of device that the user is using(!). So, while the approaches above are simple, they are relatively inflexible.&lt;/p&gt;

&lt;h3&gt;Dependency Injection To The Rescue?&lt;/h3&gt;

&lt;p&gt;It is at this point that the Dependency Injection folks will start to gesticulate wildly and remind us that this is &lt;em&gt;exactly&lt;/em&gt; the situation in which DI excels. Remember that with DI, if you have a dependency between one class and another, the system (i.e. the DI container) can automatically fulfill that dependency dynamically at run-time for you. This allows the classes to be more loosely coupled and removes the need for you to manage the creation of dependent classes yourself. Let’s see how this works…&lt;/p&gt;

&lt;p&gt;Say we have a class ‘A’ that depends on (i.e. has a reference to) a class ‘B’. Typical DI containers (including Unity) require that we express the dependency between A and B using a type – typically (but not necessarily) an intermediate interface type, say IB – and that we define a constructor on A that takes a reference to that type. We then register our implementation of the intermediate interface type with the container – so that it knows that whenever anybody wants an implementation of IB it will create an instance of B.&lt;/p&gt;

&lt;p&gt;So, when we want an instance of class A, we just ask the container to create one for us. It spots that class A requires a reference to an IB implementation, so it goes and creates a B for us automatically and passes a reference to it to A’s constructor. The container manages the creation of dependent classes for us!&lt;/p&gt;

&lt;p&gt;It is of course true that in many situations DI is a good solution for this kind of problem. I think though, that for the ViewModel scenario DI is not ideal. To illustrate why, let’s see how DI typically works in View-First and ViewModel-First scenarios…&lt;/p&gt;

&lt;h4&gt;The Perils of IViewModel&lt;/h4&gt;

&lt;p&gt;In our View-First example above, we have a View that wants a reference to (depends on) a ViewModel, so we’d first register an implementation of our ViewModel with the container:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;_container.RegisterType&amp;lt;ICustomerViewModel, CustomerViewModel&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;and we’d design the View so that it gets a reference to the ViewModel implementation in its constructor:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; CustomerView( ICustomerViewModel viewModel )&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DataContex = viewModel;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Finally, we’d get the container to create an instance of the View. The container will automatically create an instance of the registered ViewModel type and pass a reference to it into the View’s constructor.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;CustomerView view = _container.Resolve&amp;lt;CustomerView&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Ok this works, but I think there are a number of problems with this approach:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;To create the View we have to use the DI container. We can’t just create the View using ‘new’ and we can’t create it declaratively via XAML (since that will use the default constructor which won’t pass in a reference to the required ViewModel). In other words, we have to have a controller or event handler or some code somewhere that creates the View via the container by calling Resolve.&lt;/li&gt;

  &lt;li&gt;The UI designer (even if the UI designer is really a developer) should not have to write code in the View just to make it work. If there is some complicated UI behavior that can’t be done declaratively, then code &lt;em&gt;may&lt;/em&gt; be required, but this should be a special case and not required every time just to get stuff wired up and working. Even implementing the simple constructor above takes some explanation and can be easily forgotten or incorrectly implemented. &lt;/li&gt;

  &lt;li&gt;We have defined a ‘marker’ interface type that we don’t really need – i.e. the interface has no properties or methods, we’re just using it as a marker. Yes, we &lt;em&gt;could&lt;/em&gt; define some properties and method on it, but the View should not be programmatically calling into the ViewModel. Remember, UI designers should not have to write any code. All interactions between View and ViewModel should be done via bindings and attached behaviors so that the View is just a loosely coupled observer of the ViewModel. &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;The Evils of IView&lt;/h4&gt;

&lt;p&gt;So that’s Dependency Injection in a View-First world. What about a ViewModel-First world? Well, things are no better here either. Similar to the process outlined above, we’d probably define an IView interface; register an implementation of it with the container; define a constructor on the ViewModel that accepts an IView reference; then create an instance of the ViewModel using the container:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;_container.RegisterType&amp;lt;ICustomerView, CustomerView&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;...&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; CustomerViewModel( ICustomerView view )&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    ((FrameworkElement)view).DataContext = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;...&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;CustomerViewModel viewModel = _container.Resolve&amp;lt;CustomerViewModel&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Again, a couple of problems with this approach:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Again, we can’t create a View declaratively using XAML – the container will create the View as a result of creating an instance of the ViewModel class – so we’d have to have a controller or event handler or some code somewhere to kick things off. &lt;/li&gt;

  &lt;li&gt;We’d have a marker interface that we’d don’t really need and that won’t define any properties or methods – the ViewModel should &lt;strong&gt;not&lt;/strong&gt; be programmatically calling into a View. &lt;/li&gt;

  &lt;li&gt;The UI designer would have to implement an interface on the View each and every time they create one. It’s not terribly complicated, but the UI designer should not be required to write any code except for advanced scenarios. &lt;/li&gt;

  &lt;li&gt;The ViewModel-First approach is actually slightly worse that the View-First approach because of the nasty cast in the constructor. This is required in order to set the view’s data context to the ViewModel. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Wouldn’t It Be Nice If…&lt;/h3&gt;

&lt;p&gt;In my last post on navigation, I showed a couple of different approaches to the problem of conjuring up a View for a ViewModel (or vice versa) without using a Dependency Injection approach.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;For View-First, instead of using DI and defining interfaces and constructors, I just used an attached property on the View to specify the type name of the ViewModel (ViewModel.TypeName) and the system automatically constructed the ViewModel for me and wired it up to the View’s DataContext.&lt;/li&gt;

  &lt;li&gt;Going the other way (ViewModel-First) , I just used a naming convention to infer the name of the View from the ViewModel’s type name, created an instance of that View and set it’s DataContext.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither of these approaches are ideal though, so I got to thinking what an ideal approach might look like… The key is that we need a simple way of expressing the relationship between the View and the ViewModel types so that the system can just make the right things happen!&lt;/p&gt;

&lt;p&gt;If you’re familiar with DataTemplates in WPF, you know that it’s possible to define a DataTemplate (somewhere in the application’s resources) for a particular (non UI) type. Whenever the system has to display an object of that type, the DataTemplate is automatically used to visually represent it. Under the covers, the system creates an instance of the DataTemplate, sets its DataContext to the object that it represents, and then displays it in the UI. Silverlight does not yet support implicit data templating – you have to specify the DataTemplate explicitly for each control – but the mechanism is very similar.&lt;/p&gt;

&lt;p&gt;I think this is close to what we want…&lt;/p&gt;

&lt;p&gt;I think of DataTemplates simply as “Thin Views” – i.e. purely declarative Views with no code behind. They are very useful, but sometimes you just need to have some code in the View (for complex visual behavior that can’t be done declaratively). So, if the system could be extended to include Views that could have code behind, it would all fit together in a nice, simple, consistent model. It could look something like this…&lt;/p&gt;

&lt;p&gt;We define a View as usual and simply declare that it is associated with a ViewModel data type:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;UserControl x:Class=&amp;quot;MySample.CustomerView&amp;quot;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;             DataType=&amp;quot;{x:Type MySample.CustomerViewModel}&amp;quot;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;For the ViewModel-First approach, we simple create (or navigate to) an instance of the ViewModel and display it. For example,&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;MyContentControl.Content = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CustomerViewModel();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The system would then step in and create an instance of the View that corresponds to this type and would wire up the DataContext for us – just like the system does today with DataTemplates!!!&lt;/p&gt;

&lt;p&gt;Similarly, for View-First, where we simply create (or navigate to) a View, the system would automatically create an instance of the associated ViewModel type for us and wire up the DataContext. There would likely be another property to control this behavior.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;I think this approach has a number of benefits:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The system carries the burden of finding and creating corresponding Views and ViewModels, making our application code much, much simpler. And simpler means that it’s faster to write, easier to debug, and easier to unit test!&lt;/li&gt;

  &lt;li&gt;It gives us a single consistent model that works for Views &lt;strong&gt;with&lt;/strong&gt; and &lt;strong&gt;without&lt;/strong&gt; code behind.&lt;/li&gt;

  &lt;li&gt;It works declaratively as well as programmatically giving us a lot of freedom to create Views or ViewModels in code or in XAML as desired. It works great with navigation too.&lt;/li&gt;

  &lt;li&gt;It allows Views to express a dependency on a particular ViewModel, while allowing ViewModels to remain completely View agnostic. This opens up a whole host of interesting design-time tooling possibilities – like you get with DataTemplates today – but with more explicit support for the ViewModel pattern. For example, you can imagine that the UI designers can provide intelli-sense or drag &amp;amp; drop support for binding expressions and behaviors (because the design-time system can determine the ViewModel’s commands, notifications and properties).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You’ll have noticed that we’re not using an intermediate interface type to loosely couple the View and ViewModel. The approach could be extended to support that though, for example by using the upcoming Managed Extensibility Framework (MEF), or by building in some form of simple Dependency Injection mechanism into the XAML loader system.&lt;/p&gt;

&lt;p&gt;Until I prototype this approach more fully, it’s not clear whether it will &lt;em&gt;really&lt;/em&gt; work as well as expected. Also, it’s not clear at this stage when (or if) we could expect it this approach to be implemented in the platform.&lt;/p&gt;

&lt;p&gt;We can but dream though…&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9625816" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/dphill/archive/tags/Patterns+and+Practices/default.aspx">Patterns and Practices</category><category domain="http://blogs.msdn.com/dphill/archive/tags/Prism/default.aspx">Prism</category><category domain="http://blogs.msdn.com/dphill/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.msdn.com/dphill/archive/tags/Helix/default.aspx">Helix</category><category domain="http://blogs.msdn.com/dphill/archive/tags/ViewModel/default.aspx">ViewModel</category></item><item><title>Silverlight Navigation Part 3</title><link>http://blogs.msdn.com/dphill/archive/2009/04/28/silverlight-navigation-part-3.aspx</link><pubDate>Tue, 28 Apr 2009 23:45:26 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9574249</guid><dc:creator>dphill</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/dphill/comments/9574249.aspx</comments><wfw:commentRss>http://blogs.msdn.com/dphill/commentrss.aspx?PostID=9574249</wfw:commentRss><description>&lt;p&gt;Welcome to the third post in my series on navigation in Silverlight! The goal of this series of posts is to provide a simple to use framework (called Helix) for building Silverlight applications that are based on a flexible navigation mechanism and the ViewModel separated presentation pattern. This post is long and was a tough one to write (which is partly why it took so long to complete!) but this post takes us much closer to our goal.&lt;/p&gt;  &lt;p&gt;If you’ve been reading this series from the beginning, you’ll have noticed that we’re taking something of an agile approach to building Helix. You can think of each post in this series as an iteration. And like all good agile projects, we’re not afraid of a bit of refactoring, or of adding or significantly altering features as we tackle new scenarios. So in the latest version of Helix you’ll find some changes compared the version in part 2.&lt;/p&gt;  &lt;p&gt;Some of these changes are bug fixes, but most are new features or extensions to existing features to support the ViewModel pattern alongside navigation. You’ll also find more samples and unit tests in this drop. There is a summary of the main changes and new features at the end of this post. You can download the latest release from &lt;a href="http://dphill.members.winisp.net/Download/Helix-Navigation-0.3.zip" target="_blank"&gt;here&lt;/a&gt; and you can run all of the latest samples from &lt;a href="http://dphill.members.winisp.net" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;The Story So Far…&lt;/h3&gt;  &lt;p&gt;Before we get into any details, let’s quickly review what we’ve covered in previous posts…&lt;/p&gt;  &lt;p&gt;In the first &lt;a href="http://blogs.msdn.com/dphill/archive/2008/10/07/silverlight-navigation-part-1.aspx"&gt;post&lt;/a&gt; in the series, I introduced the Helix Frame and NavigationLink controls and showed how they could be used together with a simple Journal to implement a simple navigation mechanism between pages in a Silverlight 2.0 application.&lt;/p&gt;  &lt;p&gt;In the second &lt;a href="http://blogs.msdn.com/dphill/archive/2008/11/02/silverlight-navigation-part-2.aspx"&gt;post&lt;/a&gt; in the series, I introduced the Route, NavigationHandler and NavigationController classes and demonstrated how they can be used to implement navigation between pages based on parameterized navigation links. That post also showed two ways of passing parameters via the navigation link to the target page, so that the page can be initialized or have it's context set appropriately.&lt;/p&gt;  &lt;p&gt;One way was to use the NavigationPageController class which passes all of the navigation parameters to the target page's OnNavigate method (through the INavigationPage interface). The other way was to use the PageActionController class which invokes a page action method on the target page by mapping the navigation parameters to the method's name and it's parameters.&lt;/p&gt;  &lt;p&gt;Both of these approaches created an instance of the target page and then passed the navigation parameters directly to it. As noted in the second post, this is clearly not ideal since it means that the page will then contain application logic as well as UI – not good for a lot of reasons!!!&lt;/p&gt;  &lt;p&gt;Separated presentation patterns like the ViewModel pattern help to keep the UI and application logic cleanly separated. I described the ViewModel pattern in a previous &lt;a href="http://blogs.msdn.com/dphill/archive/2009/01/31/the-viewmodel-pattern.aspx"&gt;post&lt;/a&gt;, but to recap, the ViewModel pattern separates UI and presentation logic into View and ViewModel classes, and uses data binding and commands to communicate between them. In &lt;a href="http://blogs.msdn.com/dphill/archive/2009/02/11/collectionviewmodel.aspx"&gt;this&lt;/a&gt; post, I provided an implementation of a generic ViewModel for handling collections, imaginatively called CollectionViewModel. In this &lt;a href="http://blogs.msdn.com/dphill/archive/2008/12/05/ui-composition-patterns.aspx"&gt;post&lt;/a&gt;, I described two strategies in which the View and the ViewModel can get created and linked up. In View-First composition, the view is logically created first. In Presenter-First composition, the presenter (the ViewModel is our case) is logically created first.&lt;/p&gt;  &lt;p&gt;These three additional posts can be considered parts 2a, 2b and 2c of this series, so please check them out if you haven't already done so. We’ll be building on the concepts and features they describe in this post.&lt;/p&gt;  &lt;p&gt;Ok, that’s the background information out of the way. Let’s get started extending the Helix navigation framework so that it works alongside the ViewModel separated presentation pattern…&lt;/p&gt;  &lt;h3&gt;The Challenge: Mixing ViewModels and Navigation&lt;/h3&gt;  &lt;p&gt;One of the challenges with any separated presentation pattern is that you have to have some way of creating, hooking up and managing the additional components that are involved. In our preferred ViewModel pattern these additional components are principally Views, ViewModels and Models.&lt;/p&gt;  &lt;p&gt;Now, if your application is fairly static, it’s fairly straightforward to create and hook up these components. But if your application is more dynamic (for example, when the UI changes constantly because the user is navigating around within the application!) then things are not quite so simple. As well as creating and hooking up these components during navigation, we also have to figure out how the other parts of the application are going to interact and communicate with them.&lt;/p&gt;  &lt;p&gt;In my experience, this issue – the handling of Views, ViewModels and Models in a dynamic application that includes navigation – is the one that causes the most confusion and pain for folks building real-world applications using the ViewModel pattern. It is this very issue that we’re going to tackle in this post…&lt;/p&gt;  &lt;h4&gt;Choosing A Navigation Scheme&lt;/h4&gt;  &lt;p&gt;Before we get into the details on the integration of the ViewModel pattern into the Helix navigation framework, we first have to think about the different ways in which we can structure our application so we can and navigate around within it.&lt;/p&gt;  &lt;p&gt;Helix essentially allows you to design a &lt;strong&gt;navigation scheme&lt;/strong&gt; for your application by allowing you to decide how the various elements in your application are linked together by parameterized Uri's. When you define the format of the navigation links in your application, you are designing the way in which the user will navigate through your application to access its functionality and content by identifying the main navigational elements in your application and identifying which parameters are passed to them. At a high level, there are two basic navigation schemes to choose from.&lt;/p&gt;  &lt;p&gt;Perhaps the simplest navigation scheme is one where the application's navigational links refer directly to the application's visual elements. Using this scheme means that we'll link the application together using Uri's that refer to pages or controls within the application and allow the user to navigate between them. This is the navigation scheme that we used in the last two posts of the series. I think this type of navigation scheme tends to work great for &lt;strong&gt;content-centric&lt;/strong&gt; applications – i.e. when the user &lt;em&gt;expects&lt;/em&gt; to be primarily navigating through &lt;em&gt;content&lt;/em&gt;. Blog readers, news readers, and media sharing apps are good examples of this type of application. &lt;/p&gt;  &lt;p&gt;With Helix you are not limited to using simple page-based navigation schemes. You can link your application together in other interesting ways. In particular, you can structure your application so that it's composed of tasks or actions that the user carries out. I call these types of applications &lt;strong&gt;task-centric&lt;/strong&gt; applications.&lt;/p&gt;  &lt;p&gt;Let's look at a simple example – an expense reporting application. In terms of tasks, the user can create, edit, submit, approve, reject, or archive expense reports, so we could structure our application so that the user naturally navigates between these tasks in sequences that are natural. For example, the user may start by creating a new expense report and then submit it for approval; then they may edit a draft expense report and save it for later submission; then they may review their approved expense reports and archive them away for safe keeping.&lt;/p&gt;  &lt;p&gt;I think this type of navigation scheme is very interesting. It means for instance, that we can align our application’s navigational structure with the application's use-cases and the user’s tasks, rather than having to strictly follow the visual structure of the application. This means that we can more cleanly separate the visual structure of the application from its logical structure and work flow, which in turn means that we can more easily test the application, and have more flexibility when designing a fluid, animated UI for it. In addition, when we consider &lt;strong&gt;deep linking&lt;/strong&gt; (in a future post) we'll see that the user, or other systems, very often will be exposed to the navigational structure of the application, so having a navigation scheme that’s independent of the visual structure can also be important for many other reasons.&lt;/p&gt;  &lt;p&gt;At this point you might be asking: “Yes, but does it really matter what the navigational scheme for an application is since the user never sees it – they just click on links and the UI gets updated?”. This is of course true, up to a point. It’s not clear that one approach is superior to the other – I can see advantages and disadvantages with each – so we’ll explore both approaches to see what each feels like when building an application.&lt;/p&gt;  &lt;p&gt;Whatever your choice of navigation scheme, content-centric or task-centric, the important thing is that you are comfortable with it and use it consistently throughout your application. Using multiple schemes within the same application can lead to user confusion and an application that’s difficult to maintain or extend. Choosing a navigational scheme that's natural for your application will help you build, test and extend it &lt;em&gt;much&lt;/em&gt; more easily and will help to make it easier to use, so it’s important to design your navigation scheme wisely and to stick to it.&lt;/p&gt;  &lt;h4&gt;Ah, But What About The ViewModel?&lt;/h4&gt;  &lt;p&gt;Regardless of the navigation scheme, things get even more interesting when we introduce the ViewModels pattern into the navigational picture. Using the ViewModel pattern means that we'll have a component that encapsulates the UI (the View), and a component that encapsulates the presentation logic and state (the ViewModel). My post &lt;a href="http://blogs.msdn.com/dphill/archive/2009/01/31/the-viewmodel-pattern.aspx" target="_blank"&gt;here&lt;/a&gt; describes the ViewModel pattern in some detail.&lt;/p&gt;  &lt;p&gt;The View and the ViewModel have to get created and hooked up together and this can happen in one of two ways – the view is either logically created first followed by the ViewModel on which is depends, &lt;em&gt;or&lt;/em&gt; the ViewModel is logically created first followed by the View on which it depends. I call these two mechanisms &lt;strong&gt;View-First&lt;/strong&gt; or &lt;strong&gt;ViewModel-First&lt;/strong&gt; composition respectively – see my post &lt;a href="http://blogs.msdn.com/dphill/archive/2008/12/05/ui-composition-patterns.aspx" target="_blank"&gt;here&lt;/a&gt; for more details.&lt;/p&gt;  &lt;p&gt;Now – and this is a key point – if you think about a &lt;strong&gt;content-centric&lt;/strong&gt; navigation scheme as described above, you'll see that this maps very naturally to &lt;strong&gt;View-First&lt;/strong&gt; composition! The user is logically navigating to a View so we construct the View first, followed by the ViewModel on which it depends and that provides a clean separation between UI and presentation logic.&lt;/p&gt;  &lt;p&gt;On the other hand, with a task-centric navigation scheme, the user is logically navigating to a component that manages an activity or task. This component (as we'll see below) maps quite naturally to a ViewModel, so logically we're creating the ViewModel first, followed by the View on which it depends so that it can be visually represented in the UI. In other words, &lt;strong&gt;task-centric&lt;/strong&gt; navigation maps naturally to &lt;strong&gt;ViewModel-First&lt;/strong&gt; composition!&lt;/p&gt;  &lt;p&gt;So, we can clearly identify two distinct navigational styles:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;View-First Navigation&lt;/strong&gt; – Where the user navigates between Views in a content-centric application, &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;ViewModel-First Navigation&lt;/strong&gt; – Where the user navigates between ViewModels that represent tasks or activities within the application. &lt;/li&gt; &lt;/ul&gt;  &lt;div style="border-bottom: #808000 thin solid; border-left: #808000 thin solid; padding-bottom: 1px; background-color: #c8b793; margin: 12px; padding-left: 8px; padding-right: 8px; vertical-align: top; border-top: #808000 thin solid; border-right: #808000 thin solid; padding-top: 1px"&gt;Interestingly, you can also see the correlation between &lt;strong&gt;content-centric navigation and view-first composition&lt;/strong&gt;, and &lt;strong&gt;task-centric navigation and presenter-first composition&lt;/strong&gt;, in ASP.NET web applications.     &lt;p&gt;With traditional ASP.NET web applications, the application consists of a number of pages that are linked together by simple Uri's. In other words, the navigational structure of the application is based on visual elements linked together. With ASP.NET WebForms, the pages can be richly defined using server-side controls, client-side AJAX controls, and with MasterPages and so on, but the navigational structure is always based on pages and the ASP.NET runtime will create the pages as you navigate to them. You may optionally choose to separate the presentation or business logic from the UI by using an MVP pattern, but in this case, the Presenter will be constructed by the page itself.&lt;/p&gt;    &lt;p&gt;On the other hand, using ASP.NET's MVC framework, we can define a navigational scheme that follows the logical structure of our application and that is independent of the visual pages within the application. By defining suitable navigation routes we will logically navigate to a controller component which then allows us to create a suitable view and hook it up to a data model component. We technically have &lt;em&gt;controller-first&lt;/em&gt; composition, but hopefully you can see that this is the moral equivalent of constructing a ViewModel before the View.&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;In this latest drop of Helix, I’ve added support for both View-First navigation and ViewModel-First navigation by implementing a navigation controller for each. The rest of the Helix architecture remains essentially the same (though there are some new features and some fixes as detailed at the end of this post). Remember, you can always implement a custom controller if you want to change the implementation that’s described below.&lt;/p&gt;  &lt;p&gt;Instead of walking through the implementation of these controllers, it’s probably more useful to walk through a sample application for each navigation style so you can see how they are both put together. In the examples below, I’m also using some of the new and improved features in Helix that are common to both styles of navigation.&lt;/p&gt;  &lt;p&gt;Ok, enough theory, let’s see some code!&lt;/p&gt;  &lt;h3&gt;View-First Navigation&lt;/h3&gt;  &lt;p&gt;To illustrate View-First Navigation, I took the Order Entry sample application from the second post and converted it to use ViewModel pattern. You’ll remember that this sample was based on a navigation scheme where the links referred to the pages within the application, so it was relatively straightforward to keep that navigation scheme and introduce the ViewModel pattern into it. You can run the final application &lt;a href="http://dphill.members.winisp.net/OrderEntryVMSample.html" target="_blank"&gt;here&lt;/a&gt;. Let’s walk through the application so you can see how it all fits together…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart3_EEB8/Helix1_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 10px 0px; display: inline; border-top: 0px; border-right: 0px" title="Helix1" border="0" alt="Helix1" align="left" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart3_EEB8/Helix1_thumb.png" width="209" height="273" /&gt;&lt;/a&gt;The application consists of a number of Models, ViewModels and Views, plus a RootPage and an Application&amp;#160; class. The RootPage is a simple page with a Frame control – as we navigate between pages, they will displayed here.&lt;/p&gt;  &lt;p&gt;The application uses three model classes to represent the customer, sales order and the sales order line items. In this sample these are just simple classes with a number of properties. These are all defined in the Models folder.&lt;/p&gt;  &lt;p&gt;The ViewModels for the application are defined in the ViewModels folder. The ViewModels implement a number of commands and properties that the Views can bind to. The application’s pages are all defined in the Views folder. None of the pages have any code behind; all of the UI is defined declaratively in XAML. The pages bind against the ViewModel’s commands and properties.&lt;/p&gt;  &lt;p&gt;All of these classes are connected together at run-time through navigation. The navigation scheme for the application is defined in App.xaml. With the latest drop of Helix, we can define the navigation routes, and associated controller and default parameter values, as an application resource. This allows us to define the navigation scheme for our application declaratively without having to write any code.&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;n:RouteTable&lt;/span&gt; &lt;span class="attr"&gt;x:Key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;GlobalNavigationRoutes&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;n:Route&lt;/span&gt; &lt;span class="attr"&gt;UriTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;/[PageName]&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;n:Route.Controller&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;c:PageController&lt;/span&gt; &lt;span class="attr"&gt;DefaultResourcePath&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Views&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;n:Route.Controller&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;n:Route&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;n:Route&lt;/span&gt; &lt;span class="attr"&gt;UriTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;/[PageName]/[CustomerID]&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;n:Route.Controller&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;c:PageController&lt;/span&gt; &lt;span class="attr"&gt;DefaultResourcePath&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Views&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;n:Route.Controller&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;n:Route&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;n:Route&lt;/span&gt; &lt;span class="attr"&gt;UriTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;/[PageName]/[CustomerID]/[SalesOrderID]&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;n:Route.Controller&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;c:PageController&lt;/span&gt; &lt;span class="attr"&gt;DefaultResourcePath&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Views&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;n:Route.Controller&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;n:Route&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;n:RouteTable&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;








.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;In this application we have three navigation routes. The first route defines no parameters just the page name, but the second and third routes add CustomerID and SalesOrderID parameters. Each route uses a PageController. The DefaultResourcePath tells the controller where to look in the application for the pages that we will navigate to.&lt;/p&gt;

&lt;p&gt;The bulk of the application’s logic is defined in the ViewModel classes. The ViewModels implement a number of commands and properties and expose them to the UI for binding. Helix includes a number of features to help with View to ViewModel binding.&lt;/p&gt;

&lt;p&gt;Simple properties exposed by the ViewModel are easy to bind to. In the case where the underlying data managed by the ViewModel is a collection (for example, a collection of customers), the ViewModel creates a CollectionViewModel class to wrap it. This class manages currency, selection and sorting of the underlying collection. The View and CollectionViewModel are kept in sync using the SynchronizeCollectionView attached behavior like this:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ListBox&lt;/span&gt; &lt;span class="attr"&gt;ItemsSource&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{Binding Customers}&amp;quot;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;     &lt;span class="attr"&gt;h:SelectionChanged&lt;/span&gt;.&lt;span class="attr"&gt;SynchronizeCollectionView&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{Binding Customers}&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;




.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type="text/css"&gt;








.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;My post &lt;a href="http://blogs.msdn.com/dphill/archive/2009/02/11/collectionviewmodel.aspx" target="_blank"&gt;here&lt;/a&gt; on CollectionViewModel describes in detail how this attached behavior works. I have now rolled the CollectionViewModel and the SynchronizeCollectionView attached behavior classes into Helix so everything is in one place.&lt;/p&gt;

&lt;p&gt;The ViewModels also implement commands that the View can bind to. Commands are implemented using the Prism DelegateCommand class – see &lt;a href="http://msdn.microsoft.com/en-us/library/dd458928.aspx" target="_blank"&gt;here&lt;/a&gt; for more information on Prism and Delegate Command pattern. Commands can be bound to UI elements using the Prism Command attached behavior. Command parameters can also be defined using the CommandParameter attached behavior.&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Button&lt;/span&gt; &lt;span class="attr"&gt;Content&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Edit&amp;quot;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="attr"&gt;prism:Click&lt;/span&gt;.&lt;span class="attr"&gt;Command&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{Binding ViewOrdersCommand}&amp;quot;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="attr"&gt;prism:Click&lt;/span&gt;.&lt;span class="attr"&gt;CommandParameter&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{Binding Customers.CurrentItem}&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;








.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;In the example above, we’re binding the Edit button to the ViewOrders command and passing in the currently selected customer as a command parameter. When the user clicks the button, the command’s method will be invoked with the current customer as a parameter. If the Edit command is not available, the button is disabled automatically.&lt;/p&gt;

&lt;p&gt;Many of the commands in the application result in a navigation. Commands which result in navigation are typically implemented like this:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ViewOrders( Customer customer )&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="rem"&gt;// Navigate to the Orders page.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    Uri navUri = &lt;span class="kwrd"&gt;new&lt;/span&gt; Uri( &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format( &lt;span class="str"&gt;&amp;quot;/Orders/{0}&amp;quot;&lt;/span&gt;, customer.CustomerID ),&lt;/pre&gt;

  &lt;pre class="alt"&gt;                          UriKind.Relative );&lt;/pre&gt;

  &lt;pre&gt;    _navigationContext.Target.RequestNavigate( navUri );&lt;/pre&gt;

  &lt;pre class="alt"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;




.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;The Uri above is formatted in accordance with the navigation scheme that we defined in App.xaml. The Uri can include parameters such as the customer ID and these are passed to the target ViewModel when it’s created. This makes it very easy to pass parameters around during navigation. Since we have a View-First navigation application, we could also use the Helix NavigationLink control and navigate directly from the page.&lt;/p&gt;

&lt;p&gt;The navigation context you can see above is passed to the ViewModel by the framework when it is first constructed as a result of navigation. You can use the navigation context class to get access to the navigation parameters, or to ask the navigation target to navigate to another Uri as shown above. The NavigationContext class is discussed in more detail below.&lt;/p&gt;

&lt;p&gt;There are just a couple of final things that we need in order to stitch everything together. Since we’re using a View-First navigation controller, navigation Uris, such as the one above, specify the name of the page to navigate to. In the example above, we’re navigating to the Orders.xaml page in the Views folder. So far so good, but how does the framework know which ViewModel to create for this view?&lt;/p&gt;

&lt;p&gt;There are a number of ways to solve this problem. Ultimately we need to know the Type of the ViewModel class so we can instantiate it. One way to get this type is to infer it from the type of the View – so, for example, a view with a type name of ‘MyApp.MyView’ would infer a ViewModel of type say ‘MyApp.MyViewModel’. This would work but means that we would have to know about the naming convention and the relevant namespaces and we would have to follow both carefully when creating our ViewModel classes.&lt;/p&gt;

&lt;p&gt;Another approach, and the one that is implemented in this sample application, is to allow the View to explicitly specify the type of the ViewModel it was designed for. To do that we just use a simple attached property. The Customers page, for example, specifies that it needs an instance of the CustomersViewModel class like this:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;NavigationPage&lt;br /&gt;  &lt;/span&gt;&lt;span class="attr"&gt;x:Class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Samples.Helix.OrderEntrySample.CustomersPage&amp;quot;&lt;/span&gt;
  ...
  &lt;span class="attr"&gt;ViewModel&lt;/span&gt;.&lt;span class="attr"&gt;TypeName&lt;/span&gt;&lt;span class="kwrd"&gt;=&lt;br /&gt;    &amp;quot;Microsoft.Samples.Helix.OrderEntrySample.ViewModels.CustomersViewModel&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;You can imagine some day in the far flung future, when the tooling folks finally embrace the notion of separated presentation patterns, that the ViewModel’s type could be automatically specified by the tool when the user is designing the view – maybe even as a proper Type parameter making the View a generic type, for example MyView&amp;lt;ViewModelType&amp;gt;. We can only hope that that day will come soon…&lt;/p&gt;

&lt;p&gt;In any case, when the framework creates the View it checks to see if there is a ViewModel specified, and if so, it instantiates the ViewModel and sets it as the View’s DataContext. All of this is handled by the PageController which is described in more detail below.&lt;/p&gt;

&lt;p&gt;The last piece of the puzzle is the navigation context. Once the View and ViewModel have been created and hooked up, the controller passes in the navigation context which contains the navigation parameters and a whole bunch of other stuff. The ViewModel (or the View) can opt to receive the navigation context by implementing the INavigationAware interface, which consists of a single method OnNavigate:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="preproc"&gt;#region&lt;/span&gt; INavigationAware Members&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnNavigate( NavigationContext context )&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="rem"&gt;// Store the navigation context for later.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    _navigationContext = context;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    ...&lt;/pre&gt;

  &lt;pre&gt;}&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type="text/css"&gt;








.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;The ViewModel can then retrieve the parameters it’s interested and retrieve the relevant data to initialize itself.&lt;/p&gt;

&lt;h4&gt;The PageController Class Dissected&lt;/h4&gt;

&lt;p&gt;The View-First application described above uses the PageController class to handle navigation. This controller does all of the heavy lifting and stitches everything together. It carries out four steps in sequence:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart3_EEB8/Helix2_4.png"&gt;&lt;img style="border-right-width: 0px; margin: 10px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Helix2" border="0" alt="Helix2" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart3_EEB8/Helix2_thumb_1.png" width="450" height="64" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The first step is to create the View. The View’s name is specified as a parameter as part of the navigation Uri, as defined in the navigation routes in App.xaml. The View is created by loading the resource, prefixed with the DefaultResourcePath if one is specified. &lt;/li&gt;

  &lt;li&gt;The next step is to create the ViewModel. The ViewModel's type is specified using an attached property value on the View. If the View doesn’t specify a ViewModel type, this step is skipped. &lt;/li&gt;

  &lt;li&gt;If a ViewModel has been created, the next step is to set the View’s DataContext to the it. This allows the View to binding to the ViewModels properties and commands. &lt;/li&gt;

  &lt;li&gt;The final step is to set the navigation context on the View or ViewModel. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The last step probably needs some explanation. In part 2 of this series you may recall that we passed the navigation parameters to the target View using the INavigationPage interface. Now that we have ViewModel support, we probably don’t want to pass the navigation parameters to the page; we want to pass them to the ViewModel instead. In the latest drop of Helix, I have added a new interface INavigationAware that can be implemented by a View or a ViewModel (or both). The PageController checks to see if either the View or the ViewModel implements this interface and if so, calls the OnNavigate method, passing in the NavigationContext.&lt;/p&gt;
&lt;style type="text/css"&gt;








.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;NavigationContext is a new class. It provides a single object from which to retrieve all of the information about the current navigation operation, including the navigation parameters, mode, Uri and target, etc. Most of the ViewModels in the sample application store a reference to the NavigationContext to use for initiating further navigation operations later on and for retrieving the parameters that they require.&lt;/p&gt;

&lt;p&gt;The implementation of the PageController class described here is pretty simple. The strategy it implements is the one I settled on during my investigations, but you can easily change the implementation to suit your needs. For example, you can change the way in which the View or ViewModel gets created, or they way in which they get hooked-up, to whatever strategy you prefer. The beauty of the Helix framework is that you can make these changes in a single place without having to make multiple changes throughout the entire application!&lt;/p&gt;

&lt;h3&gt;ViewModel-First Navigation&lt;/h3&gt;

&lt;p&gt;OK, so much for View-First navigation. Let’s see what ViewModel-First navigation looks like…&lt;/p&gt;

&lt;p&gt;To illustrate ViewModel-First navigation, I implemented a sample expense reporting application. You can run the application &lt;a href="http://dphill.members.winisp.net/ExpenseSample.html" target="_blank"&gt;here&lt;/a&gt;. As described above, this application provides a number of tasks that the user can carry out. Each task will be rendered visually, so the user will experience these states through the UI, but to a large extent the tasks exist independently of how they are rendered.&lt;/p&gt;

&lt;p&gt;The following diagram illustrates the tasks and the commands that lead to the transitions (navigation!) between the tasks. From the View Expense Reports task, for example, the user can create, edit, review, submit or archive an expense report; from the Edit Expense Report task the user can save the expense report and the application moves back to the View Expense Reports task.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart3_EEB8/Helix5_2.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Helix5" border="0" alt="Helix5" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart3_EEB8/Helix5_thumb.png" width="466" height="206" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart3_EEB8/Helix3_2.png"&gt;&lt;img style="border-right-width: 0px; margin: 0px 0px 5px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Helix3" border="0" alt="Helix3" align="right" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart3_EEB8/Helix3_thumb.png" width="217" height="342" /&gt;&lt;/a&gt;The structure of the project is similar to the Order Entry sample described above. It consists of three folders that contain the application’s Models, ViewModels and Views, a root page and an application class.&lt;/p&gt;

&lt;p&gt;The essential difference between this application and the Order Entry application described above is that navigation occurs between ViewModels. Each ViewModel represents a task so the bulk of the application logic is defined in the ViewModels. Each ViewModel implements properties and commands similar to those described above.&lt;/p&gt;

&lt;p&gt;The ViewModel folder also contains a couple of ViewModel helper classes that perform data formatting for expense amounts and dates. These classes aren’t ViewModels per se, but they are used by the Views to help them render the data correctly.&lt;/p&gt;

&lt;p&gt;There is a corresponding View for each ViewModel, defined in the Views folder. Again, the views contain no code behind.&lt;/p&gt;

&lt;p&gt;Ok, let’s see how all of this fits together. First, the application’s navigation scheme is defined in App.xaml:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RouteTable&lt;/span&gt; &lt;span class="attr"&gt;x:Key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;GlobalNavigationRoutes&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Route&lt;/span&gt; &lt;span class="attr"&gt;UriTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;/[ViewModelTypeName]/[ExpenseID]&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Route.Controller&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ViewModelController&lt;/span&gt; &lt;span class="attr"&gt;DefaultResourcePath&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Views&amp;quot;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;                &lt;span class="attr"&gt;DefaultNamespace&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Samples.Helix.ExpenseSample.ViewModels&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Route.Controller&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Route.Defaults&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;NavigationParameter&lt;/span&gt; &lt;span class="attr"&gt;ParameterName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ExpenseID&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;ParameterValue&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;-1&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Route.Defaults&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Route&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;RouteTable&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;




.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;This application defines a single route that has two parameters – the ViewModel type name, and the expense report ID. A default value for the expense report ID is specified, so the navigational Uri’s don’t necessarily have to specify it. This route uses the ViewModelController navigation controller class. This is the class that coordinates how the ViewModels &amp;amp; Views get created, hooked-up, and initialized with the navigation context.&lt;/p&gt;

&lt;p&gt;The ViewModelController has two properties – DefaultResourcePath, which tells it where to look for Views, and DefaultNamespace, which specifies the default namespace for the ViewModel classes. The operation of this controller class is described below, but essentially it works by creating a ViewModel then a suitable View for it, hooks them up via the View’s DataContext and then sets the navigation context.&lt;/p&gt;

&lt;p&gt;The interaction between the Views and the ViewModels is the same as described above and includes commands and the CollectionViewModel sync attached behavior. Navigation between tasks occurs as commands are invoked on the ViewModels. A typical implementation of a command looks like this:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; CreateExpenseReport( ExpenseReport expenseReport )&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;    ExpenseReport newExpenseReport = _expenseReports.CreateNewExpenseReport();&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="rem"&gt;// Navigate to the Edit ViewModel.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    _navigationContext.Target.RequestNavigate( &lt;span class="kwrd"&gt;new&lt;/span&gt; Uri(&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format( &lt;span class="str"&gt;&amp;quot;/EditExpenseReport/{0}&amp;quot;&lt;/span&gt;, newExpenseReport.ExpenseID ),&lt;/pre&gt;

  &lt;pre&gt;                           UriKind.Relative ) );&lt;/pre&gt;

  &lt;pre class="alt"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;The format of the Uri is as defined in the navigation route in App.xaml. In the example above, we’re passing an expense report ID as a parameter to the target EditExpenseReport ViewModel. When that ViewModel is instantiated, the parameter will be passed in as part of the navigation context and the ViewModel can retrieve the corresponding expense report. In this way, we can control not only what gets instantiated during navigation, but also how parameters flow around the system. This really simplifies how applications like this are put together…&lt;/p&gt;

&lt;h4&gt;The ViewModelController Class Dissected&lt;/h4&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Hopefully you won’t be surprised to learn that the ViewModelController creates the ViewModel first and then creates a suitable View for it. The sequence goes like this:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; margin: 10px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Helix4" border="0" alt="Helix4" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart3_EEB8/Helix4_thumb.png" width="450" height="56" /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;In the first step, the ViewModel is instantiated using the ViewModelTypeName navigation parameter, prefixed with the DefaultNamespace if one is specified. So for a ViewModel type name of ‘EditExpenseReport’, the type ‘Microsoft.Samples.Helix.ExpenseSample.ViewModels.EditExpenseReport’ will be instantiated. &lt;/li&gt;

  &lt;li&gt;The next step is to create a suitable View. The details of this step are described below. If a View can’t be instantiated, an exception is thrown. &lt;/li&gt;

  &lt;li&gt;The next step is to set the View’s DataContext to the ViewModel. This allows the View to binding to the ViewModels properties and commands. &lt;/li&gt;

  &lt;li&gt;The final step is to set the navigation context on the View or ViewModel. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the View-First strategy described above we had the challenge of figuring out which ViewModel to instantiate for a given View. In ViewModel-First navigation we have the opposite problem – given a ViewModel, we have to decide which View to instantiate for it.&lt;/p&gt;

&lt;p&gt;The current implementation takes a simple approach – we just append the ViewModel’s short type name with ‘View’ and load the corresponding View resource. So for the ‘EditExpenseReport’ ViewModel, we’d load the View ‘EditExpenseReportView’ located in the Views folder. This was an experiment to see how a naming-convention based approach would work.&lt;/p&gt;

&lt;p&gt;There are other ways to solve this problem, but for the purposes of this sample, it works pretty well. You can always implement an alternate strategy in a custom controller class if you prefer a different way to create and hook-up the ViewModel or View.&lt;/p&gt;

&lt;h3&gt;End of Part 3&lt;/h3&gt;

&lt;p&gt;Well, that was a long post wasn’t it? We covered a lot of ground though. Since we’re building Helix from the ground up there are a lot of details to grok, and just like sausages and laws, it’s not always pretty seeing how things are made. The final framework, though, should be drop-dead simple to use – that’s the goal anyway!&lt;/p&gt;

&lt;p&gt;We’ve been experimenting with alternate approaches to discover their advantages and disadvantages and to see which one might work as a default approach that will work for most applications. We’ve essentially identified two broad approaches that have potential and we can now build applications with a View-First navigational style, or with a ViewModel-First navigational style.&lt;/p&gt;

&lt;p&gt;Which approach you use depends on your application and which approach feels most natural to you. The implementations described here work pretty well for both approaches but there are few things that need some improvement. The nice thing about Helix, though, is that it’s simple to implement alternate strategies or to tweak the behavior of the navigation scheme in an application. With a few changes here and there we can customize navigation without having to rewrite big chunks of our application.&lt;/p&gt;

&lt;p&gt;Personally, I believe the ViewModel-First approach has a lot of advantages over View-First approach, but it takes some getting used to. The example above doesn’t really highlight the advantages of this approach in terms of testability and UI flexibility. I’ll try and focus on those in the next post in the series, as well as deep linking. I promise that you won’t have to wait as long for that post…&lt;/p&gt;

&lt;p&gt;On another note, whatever approach we choose, there is always the ‘tooling problem’. In other words, what would the ideal tooling experience be like for building applications based on both a separated presentation pattern and a flexible navigation system? It’s not an easy question to answer. I have some ideas but they will have to wait for a future post too…&lt;/p&gt;

&lt;p&gt;As always, please let me know what you think of Helix – what you like or don’t like, etc. If you have any feedback on Helix, please drop me a line.&lt;/p&gt;

&lt;p align="center"&gt;oO------Oo&lt;/p&gt;

&lt;h3&gt;Helix 0.3: Changes and New Features&lt;/h3&gt;

&lt;p&gt;A quick summary of the main changes and new features in this drop of Helix:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Added support for global routes. Global routes are managed by the Navigation Manager and can be defined as an application-level resource in XAML. If not global routes are defined, a default global rout is added automatically. Frame-local routes can also be defined and are checked for a match first during navigation. If a match at the Frame level is not found, then the global routes are checked. This provides a lot of flexibility when implementing hierarchical navigation scenarios in an application. &lt;/li&gt;

  &lt;li&gt;Moved the page loader code to the static Navigation Manager class. Centralizing this code allows for multiple controller classes to take advantage of it (and allows for it’s ultimate replacement by the Silverlight framework itself if and when it supports the ability to load pages by resource name). &lt;/li&gt;

  &lt;li&gt;Removed the need to register the application’s main assembly with the Navigation Manager class. The Navigation Manager now searches all assemblies in the application manifest (except those beginning with System). This also the Navigation Manager to instantiate Views and ViewModels without the developer having to specify which assembly they are defined in, which in turn allows for easier integration between UI and non-UI application layering. &lt;/li&gt;

  &lt;li&gt;Default constructors added for Route and Journal classes. Using the default constructor for a Route object instantiates a default PageController instance. Similarly, using the Journal’s default constructor instantiates a default RouteNavigationHandler instance. These default constructors allow for simpler declarative setup in code or XAML. &lt;/li&gt;

  &lt;li&gt;NavigationParameter and related classes were also changed to support default construction and the ability to declaratively specify default values in Routes. &lt;/li&gt;

  &lt;li&gt;Refactored the regular expressions in the Route class to const strings to allow for easier customization. Also tidied up the regular expression for identifying fields in the navigation Uris. This allows you to more easily change which characters are allowed in navigation fields (e.g. you can now define fields that include period and dash, so you can use GUIDS for example). &lt;/li&gt;

  &lt;li&gt;Refactored all Controller and Journal classes into their own namespaces. &lt;/li&gt;

  &lt;li&gt;NavigationUIVisibility is now in the Helix Controls namespace. &lt;/li&gt;

  &lt;li&gt;Controller parameters – added the ability for a controller to specify its required parameters using an attribute. This allows the controller base class to automatically check incoming parameters to make sure that all required parameters have been provided. This simplifies error handling and the implementation of derived controller classes. This also allows for the associated Route object to check for a compatible controller when the Route is first registered.&lt;/li&gt;

  &lt;li&gt;Navigation Context – Added Navigation Context class which includes all of the information pertaining to the current navigation operation, including the navigation parameters, original Uri and the navigation target. This provides for a simple API, better extensibility and allows ViewModels to store a reference to their navigation context so they can initiate or initiate/cancel/redirect a navigation operation. &lt;/li&gt;

  &lt;li&gt;Added PageController and ViewModelController classes. Removed the NavigationPageController class (this functionality is now provided by the PageController class). The PageActionController class is now derived from the PageController class. &lt;/li&gt;

  &lt;li&gt;Added DefaultResourcePath property on PageController &amp;amp; ViewModelController to allow views to be loaded from a sub-folder in the project. The previous version of Helix required all pages to be defined at the project root level. &lt;/li&gt;

  &lt;li&gt;Added InitialUri dependency property on the Frame Control. This allows the Frame to navigate to the specified Uri when the Frame is first loaded, removing the need for code behind in the root page. &lt;/li&gt;

  &lt;li&gt;Added CollectionViewModel to Helix library. Also added a number of bug fixes in the Refresh and OnModelChanged method. The latter is required due to weird behavior with the Silverlight DataGrid control. &lt;/li&gt;

  &lt;li&gt;Added a unit test project with unit test for Routes, Navigation Manager, Page and ViewModel Controllers, CollectionViewModel, etc.&lt;/li&gt;

  &lt;li&gt;That’s all the changes I can remember… &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A quick note on &lt;strong&gt;Silverlight 3.0 Beta&lt;/strong&gt;: Helix and all of the associated samples are built for Silverlight 2.0. However, you should have no problem using Helix with the Silverlight 3.0 Beta. There are a few known issues in Silverlight 3.0 Beta to do with memory leaks but these probably won’t affect you too much and they’ve been fixed in later versions.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9574249" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/dphill/archive/tags/Prism/default.aspx">Prism</category><category domain="http://blogs.msdn.com/dphill/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.msdn.com/dphill/archive/tags/Helix/default.aspx">Helix</category></item><item><title>Mix 09!</title><link>http://blogs.msdn.com/dphill/archive/2009/03/18/mix-09.aspx</link><pubDate>Wed, 18 Mar 2009 20:35:42 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9487435</guid><dc:creator>dphill</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/dphill/comments/9487435.aspx</comments><wfw:commentRss>http://blogs.msdn.com/dphill/commentrss.aspx?PostID=9487435</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://live.visitmix.com/" target="_blank"&gt;&lt;img style="border-right-width: 0px; margin: 0px 10px 10px 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="mix09header" align="left" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/Mix_7428/mix09header_3.jpg" width="109" height="88" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Mix 09 starts today! There have been a number of key announcements made at Mix, especially concerning Silverlight 3.0 and Blend 3.0. If you are at all interested in Web and Silverlight development then be sure to check out the &amp;quot;Gu's&amp;quot; keynote highlights &lt;a href="http://visitmix.com/Opinions/MIX09-Keynote-and-Partner-Highlights" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The next releases of Silverlight and Blend have lots of interesting features. I'll cover them in detail in a future post, but one question that I'm sure is top of mind is how the new version of Silverlight relates to Prism and Helix.&lt;/p&gt;  &lt;p&gt;Silverlight 3.0 provides a lot of new features that are nicely complementary to Prism. These new features help with data validation, data forms, navigation and with accessing business entities over the network. Prism focuses on patterns for flexible, modular, loosely coupled, unit-testable applications. These patterns can of course be used in Silverlight 3.0 just as effectively as in 2.0. The combination of Prism and the new Silverlight features provide a very powerful platform for building line of business RIA applications.&lt;/p&gt;  &lt;p&gt;We're planning the next release of Prism which will target Silverlight 3.0 (and WPF 4.0), so we're beginning to look at how we can evolve Prism to further integrate and complement Silverlight, Blend and WPF. We're especially looking forward to support the new Silverlight out-of-browser feature(!). So if you have any ideas on what you'd like to see in Prism 3.0, please send them our way!&lt;/p&gt;  &lt;p&gt;You'll also see that Silverlight 3.0 now has some support for navigation! I was part of the team behind the navigation features in Silverlight 3.0 last year before moving to the patterns &amp;amp; practices team. My original design for Silverlight navigation was of course very similar to Helix. The design changed quite a bit since I left that team, specifically so that it is more compatible with WPF's navigation model. I'll be posting details on the differences between the two designs, the advantages and disadvantages of each, and how to use them together soon.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9487435" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/dphill/archive/tags/Prism/default.aspx">Prism</category><category domain="http://blogs.msdn.com/dphill/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.msdn.com/dphill/archive/tags/Helix/default.aspx">Helix</category></item><item><title>Silverlight Navigation - Part 2</title><link>http://blogs.msdn.com/dphill/archive/2008/11/02/silverlight-navigation-part-2.aspx</link><pubDate>Sun, 02 Nov 2008 23:47:54 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9029620</guid><dc:creator>dphill</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/dphill/comments/9029620.aspx</comments><wfw:commentRss>http://blogs.msdn.com/dphill/commentrss.aspx?PostID=9029620</wfw:commentRss><description>&lt;p&gt;Welcome to the second in my short series of articles on navigation in Silverlight!&lt;/p&gt;  &lt;p&gt;In the &lt;a href="http://blogs.msdn.com/dphill/archive/2008/10/07/silverlight-navigation-part-1.aspx" target="_blank"&gt;first article&lt;/a&gt; I introduced the core Helix navigation framework and illustrated how the three main classes &amp;#8211; Form, NavigationPage, and NavigationLink &amp;#8211; could be used to support simple navigation scenarios in Silverlight. In this article I&amp;#8217;ll be adding to the core framework to support more advanced scenarios. This article will take us a bit further along the road to Navigation Nirvana. You can download the latest Helix source code from &lt;a href="http://dphill.members.winisp.net/Download/Helix-Navigation-0.2.zip" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The Helix navigation framework uses Uri&amp;#8217;s to link everything together within the application. Each navigable part of the application is associated with a specific Uri. The user switches between these navigable parts by navigating to the associated Uri. In the simple scenario described in part 1, each Uri simply refers to a page that&amp;#8217;s defined in the main application assembly. By navigating to the page&amp;#8217;s corresponding Uri, the page is created and shown in the Frame. Linking pages together in this way is very much like a traditional web application where each hyper-link refers to a distinct page by name.&lt;/p&gt;  &lt;p&gt;However, the Helix framework is not restricted to just linking pages together by simple names and can support many more flexible and powerful navigation strategies.&lt;/p&gt;  &lt;h3&gt;The Navigation Cycle&lt;/h3&gt;  &lt;p&gt;If you look at the underlying architecture of Helix, you&amp;#8217;ll see that it basically consists of a number of provider and handler classes chained together to make a pipeline for processing Uri&amp;#8217;s. This pipeline essentially takes a Uri, stores it in a journal, turns it into content and then passes the content to the navigation target. The architecture separates out the key elements of this navigation process into three pluggable components. Each of these is responsible for a specific stage of the navigation process and they work together to implement the overall navigation cycle.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/e1ded89c29c4_E73C/Nav1_2.png"&gt;&lt;img height="373" alt="The Helix Navigation Cycle" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/e1ded89c29c4_E73C/Nav1_thumb.png" width="524" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Let&amp;#8217;s take a closer look at each of these:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Journal&lt;/b&gt; &amp;#8211; The journal is responsible for keeping a record of the Uri&amp;#8217;s that have been visited (or that are to be visited). The user can navigate forward or backwards through the Uri&amp;#8217;s in the journal, or they can add a new Uri directly to the journal in order to navigate to it. Either way, once the Journal has a Uri to process, it passes it onto the navigation handler&amp;#8230;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Handler&lt;/b&gt; &amp;#8211; The navigation handler is responsible for turning a Uri into &amp;#8216;content&amp;#8217;. In part 1, the Uri referred to a page control in the application&amp;#8217;s resources, and so the handler simply created an instance of that page control. There are more interesting and flexible ways of turning a Uri into content, as we&amp;#8217;ll shortly see. Once the handler has the content ready, it is passed to the target&amp;#8230;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Target&lt;/b&gt; &amp;#8211; The target is the ultimate destination for the content. It is responsible for displaying the content in the UI. In part 1, the content was a page control and the navigation target was Frame (i.e. a ContentControl) which simply displayed the page control in the UI. To complete the picture, the Frame has a reference to the Journal so that it can initiate navigation as a result of the user&amp;#8217;s interaction with some part of the UI that is contained in the Frame, say by clicking on a NavigationLink.&lt;/p&gt;  &lt;p&gt;By plugging in different implementations of Journals, Handlers and Targets, you can implement many different navigation strategies. You can also configure the navigation strategy on a per Frame basis so you can use multiple strategies in different parts of your application, according to your needs.&lt;/p&gt;  &lt;h3&gt;A Custom Navigation Handler&lt;/h3&gt;  &lt;p&gt;To illustrate some of the flexibility of Helix, I&amp;#8217;m going to implement a new navigation handler that supports a more powerful and flexible navigation scheme than that shown in part 1. To illustrate the various concepts and features I&amp;#8217;m going to build a simple application for managing customers and theirs orders. In this application, the user can choose a customer from a list, review their current orders, and then edit an order. The application therefore has three pages &amp;#8211; Customers, Orders and OrderEdit.&lt;/p&gt;  &lt;p&gt;In part 1, the Uri&amp;#8217;s linking pages together were very basic and just contained the target page&amp;#8217;s name. While this basic mechanism is ok for linking simple pages together, it isn&amp;#8217;t very flexible and doesn&amp;#8217;t allow us to pass any parameters, context or state between pages. This means that the page itself has to figure out how to initialize itself or to retrieve any data for it to display.&lt;/p&gt;  &lt;p&gt;In our customer orders application, the Orders page will need to know the ID of the customer whose orders are to meant be displayed. How can we tell the Orders page which customer we are interested in? Well, wouldn&amp;#8217;t it be nice if we could pass the Customer ID parameter to the Orders page via the Uri so that it can use it to display the right set of orders?&lt;/p&gt;  &lt;p&gt;Let's implement a custom navigation handler to do just that&amp;#8230;&lt;/p&gt;  &lt;h4&gt;Imitation &amp;#8211; The Sincerest Form of Flattery&lt;/h4&gt;  &lt;p&gt;If you&amp;#8217;re familiar with ASP.NET you&amp;#8217;ll have seen much excitement recently about the new ASP.NET Model-View-Controller (MVC) Framework. This framework provides a way for a web application to separate out its state or data into a &amp;#8216;Model&amp;#8217; component, its UI into a &amp;#8216;View&amp;#8217; component, and the logic that coordinates the user&amp;#8217;s interaction with the application (by handling and responding to user input and actions) into a &amp;#8216;Controller&amp;#8217; component. One of the main benefits of the ASP.NET MVC framework is that it helps maintain a clean separation of concerns between the web application&amp;#8217;s data, business logic and user interface, which then allows the use of test driven development (TDD) for web application development. &lt;a href="http://weblogs.asp.net/scottgu/archive/tags/MVC/default.aspx" target="_blank"&gt;ScottGu&lt;/a&gt; has a great series of articles that describe the many powerful features of this framework.&lt;/p&gt;  &lt;p&gt;One of the coolest parts of the ASP.NET MVC framework is the &amp;#8216;routing&amp;#8217; mechanism which lets the developer define the format of the Uri&amp;#8217;s in their application and which ensures that incoming page requests are routed, according to their Uri format, to an appropriate controller for processing. Essentially, routing allows the developer to define how the Uri&amp;#8217;s are parameterized &amp;#8211; how it&amp;#8217;s various pieces are split out into individual values. The routing mechanism passes these parameters to the correct controller for processing. The controller typically uses the parameters to construct or initialize a View and a Model, and connects them together before the page is rendered to the user&amp;#8217;s browser.&lt;/p&gt;  &lt;p&gt;There are (at least) three things that I really like about this architecture:&lt;/p&gt;  &lt;p&gt;First, it helps to maintain a strong separation between the user interface of the application, and the non-visual &amp;#8216;guts&amp;#8217; of the application. This allows developers to focus on the application logic, while the designers can focus on the user experience. It also allows the developers to unit-test almost all of the non-visual parts of their application before it is even deployed and put in front of user.&lt;/p&gt;  &lt;p&gt;Second, it&amp;#8217;s an extremely powerful and flexible architecture that can very easily be tweaked to support a navigation strategy that suits my particular application. In my humble opinion, navigation is an often neglected but absolutely critical part of an application&amp;#8217;s design. From a usability perspective, structuring the application so that the user can easily and intuitively access its various features, functions and data is hugely important. From a development perspective, being able to implement this structure in a simple, flexible and testable way is critical. There will be times when a one-size-fits-all navigation framework will simply not work well for certain types of applications (one could argue that the default Web Form model in ASP.NET fits into this category).&lt;/p&gt;  &lt;p&gt;Third, it&amp;#8217;s an architecture that fits extremely well in a RIA scenario. There are various scenarios where the 'application' is really a hybrid of a web host application &lt;i&gt;and&lt;/i&gt; a Silverlight sub-application (or sub-applications). When this is the case, the user expects to be able to navigate seamlessly through the application and they don&amp;#8217;t want to worry about whether they are in a traditional web page or in Silverlight page. The ASP.NET MVC framework helps to support this scenario.&lt;/p&gt;  &lt;p&gt;So, to honor the great work that the ASP.NET guys have done with their MVC framework, I&amp;#8217;m going to borrow some of their ideas!&lt;/p&gt;  &lt;h4&gt;Navigation Routes&lt;/h4&gt;  &lt;p&gt;To support the same kind of flexibility that ASP.NET MVC provides, I built a custom navigation handler (called RouteNavigationHandler) that allows the developer to define parameterized Uri&amp;#8217;s for their application and to associate them with a controller component. There are three main classes to this implementation &amp;#8211; the RouteNavigationHandler itself, a Route class that defines a Uri template that specifies how a Uri is to be parameterized, and a Controller class that processes the parameters extracted from the Uri. To use these classes, we simply create an instance of a RouteNavigationHandler, add one or more Route objects to associate a Uri format with a controller instance, and then hook it up to the Frame&amp;#8217;s journal.&lt;/p&gt;  &lt;div&gt;   &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;     &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;RouteNavigationHandler handler = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RouteNavigationHandler();&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;handler.Routes.Add( &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Route( &lt;span style="color: #006080"&gt;&amp;quot;[PageName]&amp;quot;&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; NavigationPageController() ) );&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;rootFrame.Journal.NavigationHandler = handler;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;We&amp;#8217;ll talk more about controllers in the next section. In this section, we&amp;#8217;ll mainly focus on the Route object which is how the system parameterizes incoming Uri&amp;#8217;s.&lt;/p&gt;

&lt;p&gt;The above example shows a simple route that defines a Uri with a single parameter called PageName. Any Uri that contains a single value (say &amp;#8216;Page1&amp;#8217; or &amp;#8216;Page2&amp;#8217;) will match this route. When processed, the content of the Uri will be extracted and will be stored in a parameter called &amp;#8216;PageName&amp;#8217;. The PageName parameter will then be added to a list of navigation parameters and passed to the NavigationPageController for processing. This controller looks for a parameter called PageName in the list of parameters and then loads the corresponding page, just as in the previous article.&lt;/p&gt;

&lt;p&gt;This is just a basic example and doesn&amp;#8217;t even scratch the surface of the flexibility of this approach, but it does illustrate how the basic system works. The following diagram shows how this example fits together.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/e1ded89c29c4_E73C/Nav2_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="315" alt="Parameterizing Uri&amp;#39;s" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/e1ded89c29c4_E73C/Nav2_thumb.png" width="500" border="0" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;In the above example, the PageName parameter is an example of a &lt;strong&gt;positional parameter&lt;/strong&gt; - the value that this parameter will be assigned depends on the position of the value in the Uri. In this example the Uri contains only a single parameter so there is no relative positioning of parameters, but you could define two parameters separated by a forward slash like this:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Route( &lt;span style="color: #006080"&gt;&amp;quot;[Parameter1]/[Parameter2]&amp;quot;&lt;/span&gt;, myController )&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;and then the first value before the slash will be assigned to Parameter1, and the second value after the slash will be assigned to Parameter2.&lt;/p&gt;

&lt;p&gt;When defining routes, you can also define &lt;b&gt;fixed fields&lt;/b&gt;, as well as positional parameter fields. You can also define multiple routes. In this case, the RouteNavigationHandler will look for the first matching route and then pass control to the associated controller. This lets you direct processing to a specific controller according to the exact format of the Uri.&lt;/p&gt;

&lt;p&gt;For example, say we had a media style application and wanted to have two controllers, one to show the user&amp;#8217;s Photo collection, and one to show the user&amp;#8217;s Video collection. We could define two routes like this:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;RouteNavigationHandler handler = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RouteNavigationHandler();&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;handler.Routes.Add( &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Route( &lt;span style="color: #006080"&gt;&amp;quot;/Photos/[Tag]&amp;quot;&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PhotoController() ) );&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;handler.Routes.Add( &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Route( &lt;span style="color: #006080"&gt;&amp;quot;/Videos/[Tag]&amp;quot;&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; VideoController() ) );&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;rootFrame.Journal.NavigationHandler = handler;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The Uri &amp;#8216;/Photos/Vacation2008&amp;#8217; would be directed to the PhotoController, which would then likely locate and display all photographs with the &amp;#8216;Vacation2008&amp;#8217; tag, while the Uri &amp;#8216;/Videos/Wedding&amp;#8217; would be directed to the VideoController so that it can locate and display all videos with the tag &amp;#8216;Wedding&amp;#8217;. In both cases, each controller will receive a parameter called Tag which will contain the tag value specified on the actual Uri.&lt;/p&gt;

&lt;p&gt;We can also capture &lt;b&gt;query string parameters&lt;/b&gt; on the Uri by appending &amp;#8216;?[params]&amp;#8217; to the Route&amp;#8217;s Uri template like this:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;RouteNavigationHandler handler = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RouteNavigationHandler();&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;handler.Routes.Add( &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Route( &lt;span style="color: #006080"&gt;&amp;quot;[PageName]?[params]&amp;quot;&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; NavigationPageController() ) );&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;rootFrame.Journal.NavigationHandler = handler;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;When this route processes Uri&amp;#8217;s, any query string parameters on the Uri are added as name-value pairs to the navigation parameters. So for the example above, a Uri like this&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;MyPage?ID=17&amp;amp;OrderBy=Date&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;will cause three parameters to be passed to the controller &amp;#8211; PageName, ID, and OrderBy (with values of &amp;#8216;MyPage&amp;#8217;, 17, &amp;#8216;Date&amp;#8217; respectively). This is a quick way to allow arbitrary parameters to be extracted from the incoming Uri and passed on to the controller.&lt;/p&gt;

&lt;p&gt;The Uri route defined above (&amp;#8216;[PageName]?[params]&amp;#8217;) actually defines the default navigation routing strategy in Helix. It is, in fact, almost equivalent to the strategy used in the first article but with one important addition &amp;#8211; we can now add parameters to the page&amp;#8217;s Uri and have them passed to the target page! That job is actually handled by the navigation controller...&lt;/p&gt;

&lt;h4&gt;Navigation Controllers&lt;/h4&gt;

&lt;p&gt;Ok, so the Route object uses a template to define how parameters are to be extracted from a Uri. When an incoming Uri is matched by a Route, it extracts the actual values from the Uri and constructs named parameters, according to its Uri template, which it then adds to a collection. This collection of navigation parameters is simply a dictionary of string name-value pairs. The navigation parameters are then passed to the navigation controller specified by the route. This object does all of the heavy lifting to actually process the parameters and turn them into content ready for displaying in the Frame.&lt;/p&gt;

&lt;p&gt;A navigation controller is simply an object that implements the INavigationContoller interface. This interface defines a single method:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; INavigationController&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;{&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Execute( NavigationParameters parameters, NavigationMode mode );&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The Execute method takes the navigation parameters and does whatever it needs to do to process those parameters and return the content to be passed to the navigation target.&lt;/p&gt;

&lt;p&gt;The default PageNavigationController expects a PageName parameter. It uses this to create an instance of the specified page so it can be displayed in the target Frame. Any additional parameters added to the Uri as a query string will also be passed to the controller. It passes these on to the target page via a new method on the INavigationPage interface:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; INavigationPage&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;{&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; PageTitle { get; }&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;   KeepAlive { get; }&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;   CanNavigateAway { get; }&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;void&lt;/span&gt;   OnNavigate( NavigationParameters parameters, NavigationMode mode );&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;If the target page implements the INavigationPage interface, the OnNavigate method will be called and all of the parameters from the navigation Uri will be passed to it. The page can then extract the parameters that it needs, say to retrieve data or configure itself. If the target page doesn&amp;#8217;t implement this interface, then it is just displayed in the Frame as usual. The default implementation of this interface (the NavigationPage class) defines OnNavigate as a virtual method, so you just have to override this method if you want to handle navigation parameters on your page.&lt;/p&gt;

&lt;p&gt;Note that this mechanism has some drawbacks (that I&amp;#8217;ll discuss at length in the next article). In particular, having the page process the navigation parameters means that you&amp;#8217;ll likely have way too much presentation logic in the page, which is not good because it can&amp;#8217;t be easily unit tested. On the other hand, if you aren&amp;#8217;t particularly interested in unit testing, or in using strong separated UI patterns, this approach has the advantage of being relatively simple and light-weight.&lt;/p&gt;

&lt;h4&gt;Navigation Link Parameters&lt;/h4&gt;

&lt;p&gt;So now we can process a Uri by extracting parameter values from it and we can pass those parameters to a target page. But how do the parameters get included in the Uri in the first place?&lt;/p&gt;

&lt;p&gt;The NavigationLink control allows you to specify the navigation Uri so we could just specify the link explicitly and include any parameters (positional or query-string). So for example, we could have:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;NavigationLink&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Next&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;NavigateUri&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot; MyPage?ID=17&amp;amp;amp;OrderBy=Date&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;if we&amp;#8217;re using query string parameters (note the use of &amp;amp;amp; to specify an ampersand in XAML) , or something like&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;NavigationLink&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Next&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;NavigateUri&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot; MyPage/17/Date&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;if we&amp;#8217;re using positional parameters. This works fine as long as we know the parameter values up-front. But what about the times when, say, the link parameters depend on the currently bound item? This is the case when you use a link in a data template, say for items displayed in a list box.&lt;/p&gt;

&lt;p&gt;It would be rather nice if we could define something like&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;NavigationLink&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Next&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;NavigateUri&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot; MyPage/{Binding ID}/Date&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;but we can&amp;#8217;t embed binding expressions in the NavigateUri string like this unfortunately.&lt;/p&gt;

&lt;p&gt;In any case, since the link parameters basically define the user&amp;#8217;s navigation through the application, they represent, in some sense, presentation logic. Embedding presentation logic in the view is bad because it means that the application navigation can&amp;#8217;t be unit tested, and it means that the view designer has to know about the navigation scheme employed by the application.&lt;/p&gt;

&lt;p&gt;There are a few alternative approaches that we could use to solve this problem, but by far the simplest (and I would argue, the most elegant) is to use a ViewModel to encapsulate the application&amp;#8217;s presentation logic, including it&amp;#8217;s navigational or workflow structure. This means that we can just do this:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;NavigationLink&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Next&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;NavigateUri&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot; {Binding NextLink}&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;You&amp;#8217;ll see this in action in the sample application below, but it means that the view is largely decoupled from the navigational structure of the application, and that we can unit test the application (including the navigational structure!) without going through the UI. It also makes the view designer&amp;#8217;s life much easier. I&amp;#8217;ll be talking much more about how ViewModels and the Helix navigation framework can work together in the next article in the series.&lt;/p&gt;

&lt;h3&gt;Putting It All Together&lt;/h3&gt;

&lt;p&gt;With the RouteNavigationHandler, Route and NavigationController classes added to the mix, the Helix navigation pipeline now looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/e1ded89c29c4_E73C/Nav3_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="330" alt="Helix Navigation Framework Architecture" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/e1ded89c29c4_E73C/Nav3_thumb.png" width="590" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Since the default route and controller as described above are already setup by Helix, the only thing you really have to do receive additional navigation parameters in a target page is to implement the INavigationPage interface and extract the parameters in the OnNavigate method. If your page derives from the NavigationPage base class, you just need to override the virtual OnNavigate method.&lt;/p&gt;

&lt;h4&gt;The OrderEntry Sample Application&lt;/h4&gt;

&lt;p&gt;To see the complete system in action, let&amp;#8217;s build our simple order entry application. In this application, we&amp;#8217;ll define three pages &amp;#8211; Customers, Orders, and OrderEdit. The Customers page shows a list of customers. From there the user can select a customer and navigate to the Orders page, which will display the orders for that customer. From there, the user can elect to edit an order by navigating to the OrderEdit page.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://dphill.members.winisp.net/OrderEntry.html" target="_blank"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 20px 0px 0px; border-right-width: 0px" height="247" alt="OrderEntry Screen 1" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/e1ded89c29c4_E73C/image_14.png" width="244" align="left" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="http://dphill.members.winisp.net/OrderEntry.html" target="_blank"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 10px 0px 20px; border-right-width: 0px" height="247" alt="OrderEntry Screen 2" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/e1ded89c29c4_E73C/image_11.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;You can run the completed sample application &lt;a href="http://dphill.members.winisp.net/OrderEntry.html" target="_blank"&gt;here&lt;/a&gt;. Let&amp;#8217;s take a look at how this application is put together.&lt;/p&gt;

&lt;p&gt;First we&amp;#8217;ll define the view model(s) for the application. In this sample, I defined a set of simple classes for Customer, SalesOrder and LineItem. In a real-world app, you&amp;#8217;d likely define these entities based on a real database and populate the data model by retrieving data via a Data Service call. But to simplify things, I just created some dummy view model data as an application level resource:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Application.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;l:Customers&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x:Key&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;AppViewModel&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;l:Customer&lt;/span&gt; &lt;span style="color: #ff0000"&gt;CustomerID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;FirstName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Orlando&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;LastName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Gee&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                    &lt;span style="color: #ff0000"&gt;CompanyName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;A Bike Store&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Phone&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;245-555-0173&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;l:SalesOrder&lt;/span&gt; &lt;span style="color: #ff0000"&gt;SalesOrderID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;OrderDate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;10/15/2008&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                          &lt;span style="color: #ff0000"&gt;ShipDate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;10/21/2008&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Status&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Pending&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;l:LineItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;LineItemID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ProductID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;OrderQty&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;10&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;UnitPrice&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;356.99&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                &amp;#8230;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;l:SalesOrder&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;l:SalesOrder&lt;/span&gt; &lt;span style="color: #ff0000"&gt;SalesOrderID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;2&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;OrderDate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;10/25/2008&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                          &lt;span style="color: #ff0000"&gt;ShipDate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;10/31/2008&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Status&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Pending&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;l:LineItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;LineItemID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;5&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ProductID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;OrderQty&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;10&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;UnitPrice&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;356.99&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                &amp;#8230;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;l:SalesOrder&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;l:Customer&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &amp;#8230;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;l:Customers&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Application.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;With the application&amp;#8217;s ViewModel defined, we can turn our attention to the page navigational structure. For this application, I created two additional routes that define positional parameters that can be passed to the various pages.&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;RouteNavigationHandler handler = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RouteNavigationHandler();&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;NavigationPageController controller = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; NavigationPageController();&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;handler.Routes.Add( &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Route( &lt;span style="color: #006080"&gt;&amp;quot;/[PageName]/[CustomerID]&amp;quot;&lt;/span&gt;, controller ) );&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;handler.Routes.Add( &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Route( &lt;span style="color: #006080"&gt;&amp;quot;/[PageName]/[CustomerID]/[SalesOrderID]&amp;quot;&lt;/span&gt;, controller ) );&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;rootFrame.Journal.NavigationHandler = handler;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Remember, the default route already allows any Uri that just contains a page name to be handled just like in the previous article. These two additional routes define routes for Uri&amp;#8217;s that contain CustomerID and SalesOrderID positional parameters. All routes are handled by the same controller, so all of the parameters will be passed on to the target page via the OnNavigate method.&lt;/p&gt;

&lt;p&gt;Next, let&amp;#8217;s look at the pages themselves. The Customers page is simple. It displays the list of customers using a ListBox and lets the user navigate to the Orders page by clicking on a NavigationLink control. To display the customers, it defines a DataTemplate that defines how to render a Customer object in the UI. This data template includes a NavigationLink to the Orders page, parameterized on the customer ID. By clicking on this link, the user navigates to the Orders page and the corresponding customer ID is passed along with the parameters.&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 98.05%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; height: 327px; background-color: #f4f4f4"&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ListBox.ItemTemplate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;      &amp;#8230;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;      &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Column&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Orientation&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Vertical&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;4&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Orientation&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Horizontal&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;          &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt; &lt;span style="color: #ff0000"&gt;FontSize&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;14&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;{Binding FirstName}&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;          &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt; &lt;span style="color: #ff0000"&gt;FontSize&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;14&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;{Binding LastName}&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;4,0,0,0&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;{Binding CompanyName}&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;{Binding Phone}&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Orientation&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Horizontal&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;          &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;No. Of Orders:&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;          &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;{Binding SalesOrders.Count}&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;h:NavigationLink&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;View Orders...&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;NavigateUri&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;{Binding ViewOrders}&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;      &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ListBox.ItemTemplate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The data template just uses a grid to show the various properties of the customer. Notice the &amp;#8216;View Orders&amp;#8217; link binds to the ViewOrder property of the customer view model. The actual link that is constructed by the customer ViewModel is as defined by the routes above.&lt;/p&gt;

&lt;p&gt;Things get a bit more interesting in the Orders page. The UI of this page is very similar to the Customer page in that it uses a ListBox and a simple DataTemplate to define how individual SalesOrder objects are rendered. What&amp;#8217;s really different is that this page uses the parameters passed to it during navigation to determine which SalesOrders are to be displayed.&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnNavigate( NavigationParameters parameters, NavigationMode mode )&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;{&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;  &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ( parameters.ContainsKey( &lt;span style="color: #006080"&gt;&amp;quot;CustomerID&amp;quot;&lt;/span&gt; ) )&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;  {&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    Customers customers = Application.Current.Resources[ &lt;span style="color: #006080"&gt;&amp;quot;AppDataModel&amp;quot;&lt;/span&gt; ] &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; Customers;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    SalesOrders orders =&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        customers.First( c =&amp;gt; c.CustomerID == parameters[ &lt;span style="color: #006080"&gt;&amp;quot;CustomerID&amp;quot;&lt;/span&gt; ] ).SalesOrders;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DataContext = orders;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;  }&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The page first checks to make sure that the incoming navigation parameters include a CustomerID. It then gets a reference to the application data and uses a simple Linq query to extract the sales orders for the specified customer. Finally, it sets the data context of the page so that the data binding expressions in the data template can take over.&lt;/p&gt;

&lt;p&gt;Please note that, as I mentioned above, this approach is not really ideal since this kind of logic shouldn&amp;#8217;t really be in the view&amp;#8217;s code behind page. Also, a real application would likely get a reference to the correct data context through a data service agent rather than via a resource. I&amp;#8217;ll be addressing these issues in the next article, but in the meantime this simple approach will suffice - this article is long enough as it is :-)&lt;/p&gt;

&lt;p&gt;The data template for the Orders list box includes a link that&amp;#8217;s bound to the SalesOrder ViewModel&amp;#8217;s EditOrder property.&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;NavigationLink&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Edit Order...&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;NavigateUri&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;{Binding EditOrder}&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The OrderEdit page expects a CustomerID and a SalesOrderID to be passed to it during navigation, so it&amp;#8217;s OnNavigate method looks like this:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnNavigate( NavigationParameters parameters, NavigationMode mode )&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;{&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;  &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ( parameters.ContainsKey( &lt;span style="color: #006080"&gt;&amp;quot;CustomerID&amp;quot;&lt;/span&gt; ) &amp;amp;&amp;amp; parameters.ContainsKey( &lt;span style="color: #006080"&gt;&amp;quot;SalesOrderID&amp;quot;&lt;/span&gt; ) )&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;  {&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    Customers customers = Application.Current.Resources[ &lt;span style="color: #006080"&gt;&amp;quot;AppViewModel&amp;quot;&lt;/span&gt; ] &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; Customers;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    SalesOrders orders =&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        customers.First( c =&amp;gt; c.CustomerID == parameters[ &lt;span style="color: #006080"&gt;&amp;quot;CustomerID&amp;quot;&lt;/span&gt; ] ).SalesOrders;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    CurrentOrder = orders.First( o =&amp;gt; o.SalesOrderID == parameters[ &lt;span style="color: #006080"&gt;&amp;quot;SalesOrderID&amp;quot;&lt;/span&gt; ] ); ;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    DataContext = CurrentOrder;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;  }&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;And that's it. The OrderEntry application is a simple application but I think it illustrates some of the flexibility of the Helix navigation framework. The source code for it is included with the latest Helix source code &lt;a href="http://dphill.members.winisp.net/Download/Helix-Navigation-0.2.zip" target="_blank"&gt;here&lt;/a&gt;. In addition to the additions described above, you might also notice some minor name changes and I also tidied up some of the error state handling in the Frame control.&lt;/p&gt;

&lt;p align="center"&gt; oO------Oo&lt;/p&gt;

&lt;p&gt;In the next article, I&amp;#8217;ll be extending the Helix navigation to embrace separated presentation patterns like Model-View-ViewModel. This will simplify application construction significantly, add a great deal of flexibility and provide support for test driven development.&lt;/p&gt;

&lt;p&gt;Helix is a work in progress and is still in the experimental stage, but I&amp;#8217;d love to know what you think of it &amp;#8211; what you like, what you don&amp;#8217;t like, what&amp;#8217;s missing, what should be removed. So if you have any feedback on Helix please drop me a line.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9029620" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/dphill/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.msdn.com/dphill/archive/tags/Helix/default.aspx">Helix</category></item><item><title>Silverlight Navigation - Part 1</title><link>http://blogs.msdn.com/dphill/archive/2008/10/07/silverlight-navigation-part-1.aspx</link><pubDate>Wed, 08 Oct 2008 09:44:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8990874</guid><dc:creator>dphill</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/dphill/comments/8990874.aspx</comments><wfw:commentRss>http://blogs.msdn.com/dphill/commentrss.aspx?PostID=8990874</wfw:commentRss><description>&lt;p&gt;This is the first in a short series of articles on navigation in Silverlight.&lt;/p&gt;  &lt;p&gt;Navigation is an often neglected but critical part of an application&amp;#8217;s design. From a usability perspective, structuring the application so that the user can easily and intuitively access its various features, functions and data is hugely important. From a development perspective, being able to implement this structure in a simple, flexible and testable way is critical. Sadly, Silverlight 2.0 doesn&amp;#8217;t include any framework support for navigation. But on the bright side, missing framework features represent an opportunity to write some code!&lt;/p&gt;  &lt;p&gt;This series of posts describes a simple but flexible navigation framework that I&amp;#8217;ve been playing with that can hopefully fill some of the gaps in Silverlight 2.0. This first post describes the core elements of the framework and shows some of its basic features. In subsequent posts, I&amp;#8217;ll be talking about how the navigation framework can be extended to support data linking, deep linking and other interesting and cool scenarios.&lt;/p&gt;  &lt;p&gt;This article coincides with the recent release of the Silverlight 2.0 Release Candidate and all of the sample code is built for it. If you haven&amp;#8217;t done so already, install RC0 and the VS2008 tools from &lt;a href="http://silverlight.net/GetStarted/sl2rc0.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Vanilla Silverlight Navigation&lt;/h3&gt;  &lt;p&gt;If you create a new Silverlight 2.0 project in Visual Studio, you&amp;#8217;ll get a project that contains an Application class and a UserControl &amp;#8216;page&amp;#8217; class. The Application class creates an instance of the page class and sets it as the root visual. Unless you&amp;#8217;re building a really small app with a very simple UI, you&amp;#8217;ll likely need to add other pages and user controls to your application and then implement navigation by manually hiding, showing or replacing bits of the UI within the root page. In other words, you&amp;#8217;re pretty much on your own when it comes to navigation in Silverlight. This is a bit of a pain and means that you have to write code that&amp;#8217;s closely tied to the UI and hard to test.&lt;/p&gt;  &lt;p&gt;WPF on the other hand provides a fairly flexible navigation system based on Pages hosted in Frames and linked together by Hyperlinks. The Frame class provides a journal and UI so the user can also navigate forward and back through a series of pages. In an XBAP application, the root journal is even hooked into the browser so you can use the browser&amp;#8217;s forward and back buttons to navigate pages within the hosted XBAP application.&lt;/p&gt;  &lt;p&gt;In general, I think WPF&amp;#8217;s navigation model is pretty nice, though I find it can be a little inflexible and somewhat complicated at times. The navigation framework presented here is similar in a lot of ways to the WPF model but (I think) it is simpler and more flexible. In particular it address three of my main grievances with the WPF model &amp;#8211; it provides an &amp;#8216;open&amp;#8217; linking model, it makes it easier to pass state between pages, and it allows you to more easily unit test the navigational structure of your app.&lt;/p&gt;  &lt;p&gt;However, I haven&amp;#8217;t tried too hard to maintain any level of compatibility with WPF &amp;#8211; some of these additional features and capabilities would be difficult to implement in WPF &amp;#8211; but the basic model should be familiar to those who are familiar with WPF's model.&lt;/p&gt;  &lt;h3&gt;A Quick Tour Of Helix (not the one in Oregon)&lt;/h3&gt;  &lt;p&gt;When playing with or learning about a new technology, I like to build a &amp;#8216;playground&amp;#8217; project where I can experiment, try out a few ideas, build various bits of an application, and generally see how things fit together. In this case, the playground project was called Helix (named after a &lt;a href="http://maps.live.com/?mkt=en-us#JnE9eXAuaGVsaXglN2Vzc3QuMCU3ZXBnLjEmYmI9NjMuMzEyNjgyNzgwNDM0OCU3ZS04My43NTk3NjU2MjUlN2UyNS41NjIyNjUwMTQ0Mjc1JTdlLTE2MC40MDAzOTA2MjU=" target="_blank"&gt;small town&lt;/a&gt; in Oregon that I spotted on a map once and thought would make a cool code name). Over time, Helix grew into the prototype navigation framework presented here.&lt;/p&gt;  &lt;p&gt;Just as in the WPF navigation model, there are three central concepts in the Helix navigation framework &amp;#8211; Frames, Pages and Hyperlinks. Each of these are represented by a specific control class:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Frame&lt;/strong&gt; &amp;#8211; The Frame control is the center of the navigation framework. It is essentially a content control that displays and coordinates the pages within the application. Frames can be nested and can display a UI that allows the user to navigate through a series of pages using forward and back buttons. The Frame control provides various events and methods for navigating to pages or for traversing the journal programmatically. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Pages&lt;/strong&gt; &amp;#8211; Pages are really just user controls that get displayed in a frame. As the user navigates through the application, pages are created, initialized and set as the content within a Frame control. Pages can implement an optional interface that allows the page to interact and control some aspects of the navigation process. Pages are referenced by a Uri. Most of the time the Uri is a direct reference to the page, but sometimes the reference can be indirect (more on this later). &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;NavigationLink&lt;/strong&gt; &amp;#8211; The NavigationLink control encapsulates a Uri to a page. When the user clicks on the NavigationLink, the nearest parent frame navigates to the page specified by the Uri. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I&amp;#8217;ve provided the source to the core of the Helix navigation framework that contains these three controls along with a sample application &lt;a href="http://dphill.members.winisp.net/Download/Helix-Navigation-0.1.zip" target="_blank"&gt;here&lt;/a&gt;. I&amp;#8217;ll be adding to this core library over the next few articles in this series, but for now let's see how these core pieces fit together...&lt;/p&gt;  &lt;h4&gt;The Sign-Up Sample&lt;/h4&gt;  &lt;p&gt;To see these classes in action, I built a simple Silverlight &amp;#8216;Sign-Up&amp;#8217; application that allows a user to create a new account. You can run the sample application live &lt;a href="http://dphill.members.winisp.net/Signup.html" target="_blank"&gt;here&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;The application consists of three main pages. The first page allows the user to enter some basic information about themselves (name, age, gender, state, etc) , while the second page allows them to enter their email address, password and a secret question. The last page is a simple confirmation page with a link back to the first page.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart1_3B04/image_8.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="373" alt="image" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart1_3B04/image_thumb.png" width="559" border="0" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;To build this application, I started with a new Silverlight project and added a reference to the Helix library. Then I added Frame control to the root page (the control that is set as the root visual by the application class) like this:&lt;/p&gt;  &lt;div&gt;   &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;     &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;h:Frame&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x:Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;rootFrame&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;[You'll also need to add an xmlns reference to the Helix library to define the h: prefix]&lt;/p&gt;

&lt;p&gt;Next, I added three user controls, called Page1, Page2 and (rather imaginatively) Page3. These contain the UI for each of the steps in the sign-up process. To link these pages together, I added a number of NavigationLink controls and set their NavigateUri properties like this:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;h:NavigationLink&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Style&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;{StaticResource NavLinkButtonStyle}&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                  &lt;span style="color: #ff0000"&gt;Content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Step 2&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;NavigateUri&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Page2.xaml&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The Helix library provides a default template for the Frame and NavigationLink controls (in the generic.xaml file). The default control template for the NavigationLink control is very simple (and dull), so in the Sign-Up app I decided to jazz it up a bit by restyling it as a button (this also gave me a chance to play with the Visual State Manager feature of Silverlight!). The custom NavLinkButtonStyle style is defined in the Sign-Up application&amp;#8217;s resources. With this style applied, the navigation link looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart1_3B04/Pictureh11_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="64" alt="Pictureh11" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart1_3B04/Pictureh11_thumb.png" width="139" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Next, we have to add a couple of lines of code in the root page&amp;#8217;s code behind. First we have to tell the navigation manager where to go to find the pages that are specified in the navigation links:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;NavigationManager.ApplicationAssembly = Assembly.GetExecutingAssembly();&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;[This is hopefully a temporary measure, due to the lack of support for loading pages by name in Silverlight 2.0.]&lt;/p&gt;

&lt;p&gt;Finally, when the application starts up we want to show the first page, so in the Load event for the root page, we programmatically navigate to the first page.&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.rootFrame.Navigate( &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Uri( &lt;span style="color: #006080"&gt;&amp;quot;Page1.xaml&amp;quot;&lt;/span&gt;, UriKind.Relative ) );&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;If you run the application, you will be able to navigate between the pages by clicking on the navigation link buttons. That&amp;#8217;s essentially it as far as the basics, but there are many additional features in the core framework that we can take advantage of to make the user experience much better.&lt;/p&gt;

&lt;h4&gt;Navigation Bar&lt;/h4&gt;

&lt;p&gt;You can configure the Frame class to show a navigation bar so the user can navigate forwards or backwards through the journal.&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;h:Frame&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x:Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;rootFrame&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;NavigationUIVisibility&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Visible&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The frame will now display a navigation bar like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart1_3B04/image8.png"&gt;&lt;img height="64" alt="image" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart1_3B04/image8_thumb.png" width="240" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If the displayed page has specified a page title (see next section), it will be displayed in the navigation bar.&lt;/p&gt;

&lt;h4&gt;Navigation Pages&lt;/h4&gt;

&lt;p&gt;When you navigate to a page (remember, a page is just a user control) Helix checks to see if it implements the INavigationPage interface. Implementing this interface allows the page to influence the navigation process. The INavigationPage interface is defined as:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; INavigationPage&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;{&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; PageTitle       { get; }&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;   KeepAlive       { get; }&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;   CanNavigateAway { get; }&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The PageTitle property very simply allows the page to specify a page title that the Frame can use in the navigation bar and in the journal.&lt;/p&gt;

&lt;p&gt;The KeepAlive property allows the page to specify whether or not the navigation system should re-create a new instance of the page when the user navigates back or forward through the journal, or whether it should keep this instance alive and just re-show it. If you run the application described above with the frame&amp;#8217;s navigation bar displayed, the user is able to navigate via page links or by using the forward and back buttons of the frame. You&amp;#8217;ll notice pretty soon that if the user enters some data on page 1, navigates to page 2 and then clicks the back button, the data that they entered on page 1 is gone!&lt;/p&gt;

&lt;p&gt;In a real application the pages would probably be associated with a presentation or view model that would be responsible for maintaining the state for the pages. Then, when the user returns to a page, a new page UI would be created but it would be re-bound to a presentation model that contained all of the state for the page. However, for simple scenarios, you probably don&amp;#8217;t want to go to the trouble of creating and maintaining presentation or view models, so the KeepAlive flag provides a simple way to keep a page instance alive so that it is not recreated from scratch when the user returns to it via the forward or back buttons.&lt;/p&gt;

&lt;p&gt;Finally, the CanNavigateAway property allows the page to veto any attempt to navigate away from it (for example, to make sure that all of the data is valid on a form before it is submitted).&lt;/p&gt;

&lt;p&gt;Helix provides a base class that already implements this interface so you can simple subclass it to create your pages and set the required properties in the page xaml:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;h:NavigationPage&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x:Class&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Microsoft.Samples.Helix.SignUpSample.Page1&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    ...&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    &lt;span style="color: #ff0000"&gt;PageTitle&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Page 1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;KeepAlive&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;True&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    ...&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;h:NavigationPage&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;p&gt;and in the code behind:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Page1 : NavigationPage&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;{&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    ...&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h4&gt;Navigation Error Handling&lt;/h4&gt;

&lt;p&gt;What happens if you specify a Uri to a page that doesn&amp;#8217;t exist or you mistype the Uri? You might have noticed in the Sign-Up sample links to the privacy policy and the terms of service in the top right hand corner. If you click on these, you will see an error message saying that the pages couldn&amp;#8217;t be found. These links were added to show how Helix handles navigation errors. If there is a problem locating or loading the page specified by the Uri, the error is bubbled up to the Frame where it can handle it in one of two ways.&lt;/p&gt;

&lt;p&gt;First, the Frame will fire a NavigationFailed event which you can sink to provide whatever error handling your app requires. The Frame can also be configured to automatically show an error message. You can control this by setting the ShowErrorUI property. If this property is false, the frame won&amp;#8217;t show any error messages and will just fire the NavigationFailed event.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart1_3B04/image_12.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="365" alt="image" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart1_3B04/image_thumb_3.png" width="547" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;You'll also notice that the default Frame template displays a mask panel over the frame's contents making the message box semi-modal. This is to prevent the user from navigating to other content until they have closed the message box.&lt;/p&gt;

&lt;h4&gt;Nested Frames&lt;/h4&gt;

&lt;p&gt;The first page of the Sign-Up sample shows how Helix can support nested frames. In this (somewhat contrived) example, the first page employs an embedded frame to allow the user to check whether their chosen username is unique. To implement this, the Sign-Up app has two sub pages that are displayed in a sub frame. When Page1 is first shown, the frame shows sub page 1, but when the user clicks on the Suggest a Name navigation link, this frame navigates to sub page 2 where the user can choose a suggested name.&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;h:Frame&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x:Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;subFrame&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;BorderThickness&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;l:SubPage1&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;l:SubPage1&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;h:Frame&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The navigation links in the sub pages are just links to the corresponding sub pages. When the user clicks on these links, the navigation request event is bubbled to the nearest frame, in this case, the sub frame on page 1. If you need to have an inner link navigate an outer frame, you can specify the name of the target frame explicitly using the TargetName property.&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;h:NavigationLink&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Jump To Page 2&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;NavigateUri&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Page2.xaml&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TargetName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;rootFrame&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;When the navigation request event bubbles up to the nearest parent frame, Helix will check to see if a target name is specified and if it matches the current frame's name. If it doesn't match, the request continues to bubble up. If it does match, it is marked as handled and the event bubbling is halted.&lt;/p&gt;

&lt;h3&gt;Under the Covers&lt;/h3&gt;

&lt;p&gt;The sample and the features described above represent only the core part of the Helix navigation framework. In subsequent articles I'll be going into more detail on how to extend the framework to do things like data linking and deep linking. In the meantime, it's worth taking a quick look at the underlying architecture of Helix.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart1_3B04/HelixNavigation_6.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="312" alt="HelixNavigation" src="http://blogs.msdn.com/blogfiles/dphill/WindowsLiveWriter/SilverlightNavigationPart1_3B04/HelixNavigation_thumb_2.png" width="580" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The Frame class has a reference to a Journal Provider (which implements the IJournal interface). The journal is responsible for maintaining forward and back lists of pages. Each entry in the journal is a JournalEntry object. This object represents the page in the journal and coordinates the keep alive and page title behavior. By default, the frame will create an instance of the SimpleStackJournal provider. This is a simple implementation of a stack based journal.&lt;/p&gt;

&lt;p&gt;The journal in turn has a reference to a Navigation Handler. The navigation handler is responsible for processing page Uri's and for creating and initializing the pages that they refer to. Navigation handlers implement the INavigationHandler interface. The default navigation handler (PageNavigationHandler) only handles simple page Uri's that specify the page by name - e.g. &amp;quot;Page1.xaml&amp;quot;.&lt;/p&gt;

&lt;p&gt;[I should point out that the implementation of this handler is a little hacky because Silverlight doesn't really have a nice way of creating or loading controls by name. Instead you have to load the xaml as a resource and then parse it to get the corresponding class name and then create an instance of that class. Nasty. Hopefully this is a temporary limitation of Silverlight, or I can figure out a more robust way of doing this soon.]&lt;/p&gt;

&lt;p&gt;Once the navigation handler has created and initialized the page, it is passed back to the journal provider where a corresponding journal entry object is created and added to the stack. The journal then sets the content on the target frame via the INavigationTarget interface which it implements.&lt;/p&gt;

&lt;p&gt;In the following articles, we'll be plugging in different implementations of journal providers, navigation handlers and navigation targets to illustrate the flexibility of this design.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The Helix navigation framework is still a work in progress but I hope you find it useful and/or interesting. Let me know what you think, or if there are any features or scenarios you would like to see tackled.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8990874" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/dphill/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.msdn.com/dphill/archive/tags/Helix/default.aspx">Helix</category></item></channel></rss>