<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>davidpoll.com &#187; BusyIndicator</title>
	<atom:link href="http://www.davidpoll.com/tag/busyindicator/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.davidpoll.com</link>
	<description>Software development and other goofy geeky goodness.</description>
	<lastBuildDate>Sat, 18 Jun 2011 22:03:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>On-demand loading of assemblies with Silverlight Navigation &#8211; Revisited for Silverlight 4 Beta</title>
		<link>http://www.davidpoll.com/2010/02/01/on-demand-loading-of-assemblies-with-silverlight-navigation-revisited-for-silverlight-4-beta/</link>
		<comments>http://www.davidpoll.com/2010/02/01/on-demand-loading-of-assemblies-with-silverlight-navigation-revisited-for-silverlight-4-beta/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 08:28:17 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[BusyIndicator]]></category>
		<category><![CDATA[ContentLoader]]></category>
		<category><![CDATA[Dynamic Navigation]]></category>
		<category><![CDATA[Navigation]]></category>
		<category><![CDATA[Silverlight 4 Beta]]></category>
		<category><![CDATA[Silverlight and Beyond (SLaB)]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2010/02/01/on-demand-loading-of-assemblies-with-silverlight-navigation-revisited-for-silverlight-4-beta/</guid>
		<description><![CDATA[Way back in July, shortly after Silverlight 3 was released, I posted a technique that allowed you to use the Navigation framework in the SDK to load pages in dlls that would be downloaded as part of the navigation process.&#160; The solution relied on two things: a workaround to the navigation framework’s inability to navigate [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Way back in July, shortly after Silverlight 3 was released, <a href="http://www.davidpoll.com/2009/07/20/on-demand-loading-of-assemblies-with-silverlight-navigation/">I posted a technique</a> that allowed you to use the Navigation framework in the SDK to load pages in dlls that would be downloaded as part of the navigation process.&#160; The solution relied on two things: a workaround to the navigation framework’s inability to navigate to Pages in dynamically-loaded assemblies, and a derived version of the Frame class that hid many methods in order to orchestrate downloads of dlls and their dependencies.</p>
<p>With Silverlight 4’s INavigationContentLoader extensibility point, we can address this scenario much more effectively, and are no longer locked into the workarounds and strict constraints that Silverlight 3’s navigation feature placed on us.&#160; In this post, I’ll walk through the use of another ContentLoader I’ve been working on and look at how it simplifies building multi-xap applications.</p>
<h3></h3>
<h3>Getting a jump-start</h3>
<p>If you’d like to get started quickly and see the magic of multi-xap applications, follow these steps (note: Requires the Silverlight 4 Beta and an active internet connection) or download the source for the steps below <a href="http://www.davidpoll.com/Samples/Download/BasicXapLoaderApp.zip">here</a> (you may need to fix up the references after downloading <a href="http://www.davidpoll.com/Download/SLaB/SLaBv0.3.zip">SLaB</a>):</p>
<ol>
<li>Download and extract <a href="http://www.davidpoll.com/Download/SLaB/SLaBv0.3.zip">SLaB</a> </li>
<li>Open Visual Studio 2010 and create a new Silverlight 4 project using the Silverlight Navigation Application template.&#160; When prompted to create a corresponding ASP.NET web application, just click “OK” and let Visual Studio create a web project for you. </li>
<li>Add a reference to SLaB.Navigation.ContentLoaders.Xap.dll from the extracted Binaries folder. </li>
<li>Add the following line of code to App.xaml.cs: <span style="color: #2b91af">PackUriParser</span>.Initialize(); </li>
<li>Replace the Frame in MainPage.xaml with the following code (new code is bold/italic– the rest is identical to the default project xaml except for formatting): </li>
</ol>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;ContentFrame&quot;
                  </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">ContentFrameStyle</span><span style="color: blue">}&quot;
                  </span><span style="color: red">Source</span><span style="color: blue">=&quot;/Home&quot;
                  </span><span style="color: red">Navigated</span><span style="color: blue">=&quot;ContentFrame_Navigated&quot;
                  </span><span style="color: red">NavigationFailed</span><span style="color: blue">=&quot;ContentFrame_NavigationFailed&quot;&gt;
    &lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.UriMapper</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapper</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapping </span><span style="color: red">Uri</span><span style="color: blue">=&quot;&quot;
                                  </span><span style="color: red">MappedUri</span><span style="color: blue">=&quot;/Views/Home.xaml&quot; /&gt;
            &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapping </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/{pageName}&quot;
                                  </span><span style="color: red">MappedUri</span><span style="color: blue">=&quot;/Views/{pageName}.xaml&quot; /&gt;
        &lt;/</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapper</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.UriMapper</span><span style="color: blue">&gt;
<strong><em>    &lt;</em></strong></span><strong><em><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.ContentLoader</span></em></strong><strong><em><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">XapContentLoader </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">SLaB</span></em></strong><strong><em><span style="color: blue">=&quot;clr-namespace:SLaB.Navigation.ContentLoaders.Xap;assembly=SLaB.Navigation.ContentLoaders.Xap&quot;
                               </span><span style="color: red">EnableCrossDomain</span></em></strong><strong><em><span style="color: blue">=&quot;True&quot; /&gt;
    &lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.ContentLoader</span></em></strong><span style="color: blue"><strong><em>&gt;</em></strong>
&lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<ol start="6">
<li>Run the application. </li>
<li>Replace “#/Home” in your browser’s address bar with “#pack://http:,,open.depoll.com,SimpleApplication,SimpleApplication.xap/SimpleApplication;component/Depoll.xaml?Source=http://open.depoll.com&amp;File=wildlife.wmv” </li>
<li>Wait for a moment, and then enjoy the (admittedly underwhelming) show! </li>
</ol>
<h4>Whoa, what just happened?!</h4>
<p>You just created an application that loaded a page in another xap!&#160; It took only two actions to make this happen: registering the “PackUriParser” and setting the Frame’s ContentLoader to a XapContentLoader with cross-domain access enabled.&#160; When you added the “pack://…” to the browser’s address bar, you told the content loader to downlaod a xap at <a href="http://open.depoll.com/SimpleApplication/SimpleApplication.xap">http://open.depoll.com/SimpleApplication/SimpleApplication.xap</a> (which is on my personal site, and has a very permissive cross-domain policy) and load the page “Depoll.xaml”.</p>
<p>The XapContentLoader makes loading pages in other xaps (and reducing your download sizes) as easy as coming up with a URI that points to the page.&#160; Read on to learn more about how to use the XapContentLoader and some of the problems associated with multi-xap applications.</p>
<h4></h4>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h3>Why load pages in external xaps?</h3>
<p>This has always been a particularly interesting scenario to me.&#160; The size of your application’s xap file can have a big impact on your users’ experience with your Silverlight application.&#160; Since the entire xap and its dependencies (e.g. cached assemblies) must download before users can interact with your application, keeping the xap’s size small means users can start using your application sooner and are less likely to give up and click away.</p>
<p>Partitioning your application into smaller-sized chunks that download only when users attempt to access that piece of functionality can also save bandwidth (since users need not download parts of the application they won’t use).</p>
<p>The folks behind both <a href="http://www.codeplex.com/MEF">MEF</a> (Package catalogs) and <a href="http://www.codeplex.com/CompositeWPF">Prism</a> (Modules) have great libraries that help you accomplish this partitioning.&#160; To me, navigation is a natural delineator of application functionality – Pages represent pieces of functionality your users can access, so triggering loading of other assemblies/xaps as part of navigation means that users will get the pieces of the application when they want to use them.</p>
<p>In this post, I will be outlining a XapContentLoader, which makes loading pages in other Xaps a 2-lines-of-code problem to solve.&#160; I’ve added this ContentLoader and some related utilities to <a href="http://www.davidpoll.com/downloads-and-samples/#SLaB">SLaB</a>, so you can use it yourself or play with the code if you like!</p>
<h3>XapLoader</h3>
<p>The first component I needed to make this scenario work was a way to download and load xap files.&#160; As such, I wrote a XapLoader utility.&#160; The strategy I used for loading xaps was the following:</p>
<ol>
<li>Download the xap </li>
<li>Read the AppManifest.xaml within the xap to locate the assemblies therein </li>
<li>Load all assemblies within the xap </li>
<li>Download zip files for the “ExtensionParts” within the AppManifest (used for the “cached assemblies” feature) </li>
<li>Load the assembly associated with each zip file </li>
</ol>
<p>Why worry about ExtensionParts?&#160; My hope is to use this feature to solve the shared dependency problem.&#160; For example, the System.Windows.Controls.Data.dll file in the SDK (containing the DataGrid control) is a fairly large assembly (446 kb uncompressed).&#160; I’d like to avoid having users download this assembly when the app first loads, so I partition my application into four xaps: Main.xap, Foo.xap, Bar.xap, and Baz.xap.&#160; Foo.xap and Bar.xap both use the DataGrid control.&#160; Since I have no guarantees about the order in which my users will access the application, I need to make sure both of those xaps have access to that assembly, so I partition my application as follows:</p>
<p><a href="http://www.davidpoll.com/wp-content/uploads/2010/02/image.png"><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="Multiple xaps have a shared dependency" border="0" alt="Multiple xaps have a shared dependency" src="http://www.davidpoll.com/wp-content/uploads/2010/02/image_thumb.png" width="358" height="293" /></a>This is a bit painful, since now when I download both Foo.xap and Bar.xap, I’m forced to download System.Windows.Controls.Data.dll <strong><em>twice</em></strong>!&#160; Instead, if I turn on the assembly caching feature introduced in Silverlight 3, I can get both Foo.xap and Bar.xap to point to the same System.Windows.Controls.Data.dll.&#160; By taking it out of the actual xaps and making it a separate download, I need only download it once (in fact, the browser’s cache will take care of it for me!).&#160; Now, my application is partitioned in this way:</p>
<p><a href="http://www.davidpoll.com/wp-content/uploads/2010/02/image1.png"><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="Xaps with a cached assembly dependency" border="0" alt="Xaps with a cached assembly dependency" src="http://www.davidpoll.com/wp-content/uploads/2010/02/image_thumb1.png" width="640" height="293" /></a></p>
<p>And now I’ve effectively partitioned the application without keeping redundant libraries around that would increase the overall download size of the application.</p>
<p>My implementation allows you to do this (using the same mechanism as “assembly caching”), but has the following limitations:</p>
<ul>
<li>Cached assembly .zip files must contain only one assembly per zip. </li>
<li>The name of the .zip file must be the same as the assembly name (replacing “.dll” with “.zip”) </li>
</ul>
<p>This loader returns a “Xap” object, which has all of the loaded assemblies related with the xap, a “Manifest”, which contains the same data as the Deployment defined in AppManifest.xaml within the xap, and a means to get the original streams from which each assembly was loaded (for use in keeping local copies, if that’s what you’d like to do).&#160; The XapContentLoader, described below, uses this loader to find and load xaps that would contain additional pages.</p>
<h3>XapContentLoader</h3>
<p>The XapContentLoader is an implementation of INavigationContentLoader that will download an external xap and load a page in one of its assemblies.&#160; This content loader uses a slightly modified version of the <a href="http://msdn.microsoft.com/en-us/library/aa970069.aspx">pack uri scheme</a> (which I’m probably abusing a bit here, but oh well <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ).&#160; Technically, it only takes two lines of code/XAML to use the XapContentLoader:</p>
<p>First, add the following line to your Application’s startup code (usually in App.xaml.cs), which registers the pack uri scheme with the built-in Uri class, so that you can create pack Uris in code and XAML without having exceptions be thrown:</p>
<pre class="code"><span style="color: #2b91af">PackUriParser</span>.Initialize();</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Then, in XAML:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;ContentFrame&quot;
                  </span><span style="color: red">Source</span><span style="color: blue">=&quot;/Views/Home.xaml&quot;&gt;
    &lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.ContentLoader</span><span style="color: blue">&gt;
        <strong><em><span style="text-decoration: underline">&lt;</span></em></strong></span><strong><em><span style="text-decoration: underline"><span style="color: #a31515">xapLoader</span><span style="color: blue">:</span><span style="color: #a31515">XapContentLoader </span></span></em></strong><span style="color: blue"><strong><em><span style="text-decoration: underline">/&gt;</span></em></strong>
    &lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.ContentLoader</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>And that’s it!&#160; Alright, that’s all.&#160; See you later…</p>
<p>…</p>
<p>…</p>
<p>…</p>
<p>Ok, ok, I won’t leave you hanging like that!&#160; Let’s look at how you would now use this content loader to load a page in another xap.&#160; First, a quick review of the pack uri scheme as I understand it:</p>
<p><em>pack://&lt;authority&gt;/&lt;path&gt;</em></p>
<p>There are three parts to this Uri:</p>
<ul>
<li>“pack://” – this is the scheme name of the Uri.&#160; All absolute pack Uris begin with this. </li>
<li>“&lt;authority&gt;” – this is actually another Uri (just replace “/” with “,” and escape any other necessary characters).&#160; For the XapContentLoader, this is a path to some xap.&#160; For example, I might use the following authority: “http:,,www.davidpoll.com,xaps,MyApplication.xap”.&#160; This indicates that I’ll be loading a page within the xap at that location.&#160; I also support two other “special” authorities: “application:///” and “siteoforigin://”.&#160; “application:///” cannot have an additional path attached to it, since I translate this as the location of the initial xap from which the application was loaded.&#160; It’s basically equivalent to Application.Current.Host.Source.&#160; “siteoforigin://” is replaced with the directory from which the application’s xap was loaded.&#160; As such, any of the following authorities would be valid:
<ul>
<li>http:,,www.davidpoll.com,xaps,MyApplication.xap </li>
<li>https:,,www.davidpoll.com,securexaps,MySecureApplication.xap </li>
<li>application:,,, </li>
<li>siteoforigin:,,MyApplication.xap (equivalent to the first item in this list if MyApplication.xap was the entry point xap) </li>
</ul>
</li>
<li>“&lt;path&gt;” – this is the path within the xap.&#160; Usually, this looks like: “/SomeLibrary;component/Views/Page1.xaml”.&#160; If no assembly name is provided, I assume they are referring to the “EntryPointAssembly” referred to in the AppManifest.xaml file of the xap. </li>
</ul>
<p>Some examples of valid Uris to navigate to (all equivalent assuming MyApplication.xap was the initial xap):</p>
<ul>
<li>/Views/Page1.xaml </li>
<li>pack://application:,,,/Views/Page1.xaml </li>
<li>pack://application:,,,/MyApplication;component/Views/Page1.xaml </li>
<li>pack://http:,,www.davidpoll.com,xaps,MyApplication.xap/Views/Page1.xaml </li>
<li>pack://http:,,www.davidpoll.com,xaps,MyApplication.xap/MyApplication;component/Views/Page1.xaml </li>
<li>pack://siteoforigin:,,MyApplication.xap/Views/Page1.xaml </li>
<li>pack://siteoforigin:,,MyApplication.xap/MyApplication;component/Views/Page1.xaml </li>
</ul>
<p>Unfortunately, coming up with these Uris can be a bit of a pain, so I’ve provided a custom type of UriMapping that works on a per-xap basis to make this simpler:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.UriMapper</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">navUtils</span><span style="color: blue">:</span><span style="color: #a31515">UriMapper</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">xapLoader</span><span style="color: blue">:</span><span style="color: #a31515">PackUriMapping </span><span style="color: red">XapLocation</span><span style="color: blue">=&quot;siteoforigin://TernaryXap.xap&quot;
                                  </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/remote/{assemblyname}/{path}&quot;
                                  </span><span style="color: red">MappedPath</span><span style="color: blue">=&quot;/{path}&quot; /&gt;
    &lt;/</span><span style="color: #a31515">navUtils</span><span style="color: blue">:</span><span style="color: #a31515">UriMapper</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.UriMapper</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Now, I needn’t ever actually write a pack uri myself.&#160; Instead, I can have hyperlinks like “/remote/TernaryXap/Views/Page1.xaml”, and these mappings will generate the appropriate pack uris for you.&#160; They work just like the UriMapping built into the SDK in terms of replacing values in the MappedPath.&#160; “{assemblyname}” is a special token (that you could omit if you set the PackUriMapping.AssemblyName property) that allows you to make the assembly name part of your path.</p>
<h3>Enhancing the experience</h3>
<p>Great, so now we’ve got navigation integrated with on-demand xap loading.&#160; It takes very few lines of code, and is quick to set up.&#160; Note that my xaps have no concrete knowledge of one another (even the hyperlinks are just text, and users could manually enter other hyperlinks).&#160; But web requests are slow, and could fail.&#160; How can we improve the experience around this type of navigation?</p>
<p>Well, I’ve got two ideas for you that you might recognize: <a href="http://www.davidpoll.com/tag/busyindicator/">BusyIndicator</a> and <a href="http://www.davidpoll.com/2009/12/07/opening-up-silverlight-4-navigation-event-based-and-error-handling-inavigationcontentloaders/">ErrorPageLoader</a>.</p>
<p>Since web requests can fail (lost connectivity, bad links, servers being down, or other random problems), we should make sure users don’t see exceptions under those circumstances.&#160; For this, we’ll whip out the ErrorPageLoader from our trusty utility belt and use it to load a local error page if something goes wrong:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">loaders</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">loaders</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ContentLoader</span><span style="color: blue">&gt;
</span><span style="color: blue">        <strong><em><span style="text-decoration: underline">&lt;</span></em></strong></span><strong><em><span style="text-decoration: underline"><span style="color: #a31515">xapLoader</span><span style="color: blue">:</span><span style="color: #a31515">XapContentLoader </span></span></em></strong><span style="color: blue"><strong><em><span style="text-decoration: underline">/&gt;</span></em></strong>
</span><span style="color: blue">    &lt;/</span><span style="color: #a31515">loaders</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ContentLoader</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">loaders</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ErrorContentLoader</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">navigationLoader</span><span style="color: blue">:</span><span style="color: #a31515">PageResourceContentLoader </span><span style="color: blue">/&gt;
    &lt;/</span><span style="color: #a31515">loaders</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ErrorContentLoader</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">loaders</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPage </span><span style="color: red">ErrorPageUri</span><span style="color: blue">=&quot;/Views/ErrorPage.xaml&quot; /&gt;
&lt;/</span><span style="color: #a31515">loaders</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>You’ll notice that I’ve used the built-in (SDK) PageResourceContentLoader as my ErrorContentLoader.&#160; I did this because, presumably, something bad has happened with the XapContentLoader, so I want to use a ContentLoader with low likelihood of failure in order to display an error page.</p>
<p>Next, users shouldn’t be left hanging while they wait for a link to load.&#160; We can use the BusyIndicator control in the <a href="http://silverlight.codeplex.com">toolkit</a> in order to let the user know that something is going on.&#160; The XapContentLoader has an “IsBusy” property as well as a “Progress” property.&#160; We can make the BusyIndicator’s progress bar display progress and appear by binding it to these properties on the XapContentLoader.&#160; The following handy XAML accomplishes this:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">toolkit</span><span style="color: blue">:</span><span style="color: #a31515">BusyIndicator </span><span style="color: red">IsBusy</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">ContentLoader</span><span style="color: blue">.ContentLoader.IsBusy, </span><span style="color: red">ElementName</span><span style="color: blue">=ContentFrame}&quot;
                       </span><span style="color: red">DisplayAfter</span><span style="color: blue">=&quot;0:0:0.1&quot;&gt;
    &lt;</span><span style="color: #a31515">toolkit</span><span style="color: blue">:</span><span style="color: #a31515">BusyIndicator.BusyContent</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">Grid</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">Grid.RowDefinitions</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">RowDefinition </span><span style="color: red">Height</span><span style="color: blue">=&quot;Auto&quot; /&gt;
                &lt;</span><span style="color: #a31515">RowDefinition </span><span style="color: red">Height</span><span style="color: blue">=&quot;Auto&quot; /&gt;
            &lt;/</span><span style="color: #a31515">Grid.RowDefinitions</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">TextBlock </span><span style="color: red">Text</span><span style="color: blue">=&quot;Loading page...&quot; </span><span style="color: red">Margin</span><span style="color: blue">=&quot;0,0,0,4&quot; /&gt;
            &lt;</span><span style="color: #a31515">ProgressBar </span><span style="color: red">Grid.Row</span><span style="color: blue">=&quot;1&quot;
                         </span><span style="color: red">Minimum</span><span style="color: blue">=&quot;0&quot;
                         </span><span style="color: red">Maximum</span><span style="color: blue">=&quot;1&quot;
                         </span><span style="color: red">Height</span><span style="color: blue">=&quot;25&quot;
                         </span><span style="color: red">Value</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">ContentLoader</span><span style="color: blue">.ContentLoader.Progress, </span><span style="color: red">ElementName</span><span style="color: blue">=ContentFrame}&quot; /&gt;
        &lt;/</span><span style="color: #a31515">Grid</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">toolkit</span><span style="color: blue">:</span><span style="color: #a31515">BusyIndicator.BusyContent</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">toolkit</span><span style="color: blue">:</span><span style="color: #a31515">BusyIndicator.ProgressBarStyle</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">Style </span><span style="color: red">TargetType</span><span style="color: blue">=&quot;ProgressBar&quot;&gt;
            &lt;</span><span style="color: #a31515">Setter </span><span style="color: red">Property</span><span style="color: blue">=&quot;Visibility&quot; </span><span style="color: red">Value</span><span style="color: blue">=&quot;Collapsed&quot; /&gt;
        &lt;/</span><span style="color: #a31515">Style</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">toolkit</span><span style="color: blue">:</span><span style="color: #a31515">BusyIndicator.ProgressBarStyle</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;ContentFrame&quot;</span><span style="color: blue">
                      </span><span style="color: red">Source</span><span style="color: blue">=&quot;/Views/Home.xaml&quot;</span><span style="color: blue">&gt;
</span><span style="color: blue">        &lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.ContentLoader</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">loaders</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">loaders</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ContentLoader</span><span style="color: blue">&gt;
</span><span style="color: blue">                    &lt;</span><span style="color: #a31515">xapLoader</span><span style="color: blue">:</span><span style="color: #a31515">XapContentLoader</span><span style="color: blue"> /&gt;
</span><span style="color: blue">                &lt;/</span><span style="color: #a31515">loaders</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ContentLoader</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">loaders</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ErrorContentLoader</span><span style="color: blue">&gt;
                    &lt;</span><span style="color: #a31515">navigationLoader</span><span style="color: blue">:</span><span style="color: #a31515">PageResourceContentLoader </span><span style="color: blue">/&gt;
                &lt;/</span><span style="color: #a31515">loaders</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ErrorContentLoader</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">loaders</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPage </span><span style="color: red">ErrorPageUri</span><span style="color: blue">=&quot;/Views/ErrorPage.xaml&quot; /&gt;
            &lt;/</span><span style="color: #a31515">loaders</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.ContentLoader</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">toolkit</span><span style="color: blue">:</span><span style="color: #a31515">BusyIndicator</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Note that I’ve hidden the BusyIndicator’s default progress bar, and added one to its BusyContent that binds to the XapContentLoader’s progress.&#160; Now, when users navigate to pages and have to wait for them to load, they are presented with the BusyIndicator and a progress bar letting them know how much is left to be downloaded.&#160; The application continues to appear responsive, and users can continue to work with the rest of the application.</p>
<h3>Cross-domain considerations and limiting access</h3>
<p>We’ve now unleashed a lot of power.&#160; Your application can now load pages in <em>any</em> xap that Silverlight can get access to using a WebClient.&#160; If the Frame control you’re using integrates with the browser, users can type any uri into the browser to navigate to, and right now, the XapContentLoader will blindly go and load their code.</p>
<p>This could be a bit of a security issue (I’m no expert, but this one sticks out like a sore thumb).</p>
<p>Suppose domain supersecret.com has a cross-domain policy that allows my domain (and only my domain), davidpoll.com, to access services on it.&#160; My domain is using the XapContentLoader, and can load pages in any xap that WebClient can access.&#160; A developer whose domain is evil.com realizes this, and decides to try to get access to supersecret.com’s services.&#160; He’s able to do this by:</p>
<ul>
<li>Adding a cross-domain policy that allows davidpoll.com to access xaps on evil.com </li>
<li>Pointing the Silverlight application on davidpoll.com to his xap on evil.com (this will work, since WebClient just checks evil.com’s cross-domain policy) </li>
<li>Now that evil.com’s xap has been loaded and is running on davidpoll.com’s application, he can access supersecret.com’s services (since the evil.com’s code is now running on davidpoll.com)! </li>
</ul>
<p>Because of this problem, I’ve disabled cross-domain loading on the XapContentLoader by default.&#160; You can re-enable it, but please be aware of this potential problem.&#160; The <a href="http://www.davidpoll.com/2010/01/01/opening-up-silverlight-4-navigation-authenticationauthorization-in-an-inavigationcontentloader/">AuthContentLoader</a> is a convenient way to restrict access to domains you don’t want users to be able to access just by changing the Uri.&#160; Here, I’ve enabled cross-domain access, but restricted access only to my other domain (this one happens to be my personal website that I don’t update too often <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ):</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">auth</span><span style="color: blue">:</span><span style="color: #a31515">AuthContentLoader</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">auth</span><span style="color: blue">:</span><span style="color: #a31515">AuthContentLoader.ContentLoader</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">xapLoader</span><span style="color: blue">:</span><span style="color: #a31515">XapContentLoader </span><span style="color: red"><strong><em><span style="text-decoration: underline">EnableCrossDomain</span></em></strong></span><span style="color: blue"><strong><em><span style="text-decoration: underline">=&quot;True&quot;</span></em></strong> /&gt;
    &lt;/</span><span style="color: #a31515">auth</span><span style="color: blue">:</span><span style="color: #a31515">AuthContentLoader.ContentLoader</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">auth</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthorizer</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">auth</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule </span><span style="color: red"><strong><em><span style="text-decoration: underline">UriPattern</span></em></strong></span><span style="color: blue"><strong><em><span style="text-decoration: underline">=&quot;pack://((siteoforigin:,,)|(authority:,,)|(http:,,open\.depoll\.com)).*&quot;</span></em></strong>&gt;
            <strong><em><span style="text-decoration: underline">&lt;</span></em></strong></span><strong><em><span style="text-decoration: underline"><span style="color: #a31515">auth</span><span style="color: blue">:</span><span style="color: #a31515">Allow </span><span style="color: red">Users</span></span></em></strong><span style="color: blue"><strong><em><span style="text-decoration: underline">=&quot;*&quot; /&gt;</span></em></strong>
        &lt;/</span><span style="color: #a31515">auth</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">auth</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule </span><span style="color: red"><strong><em><span style="text-decoration: underline">UriPattern</span></em></strong></span><span style="color: blue"><strong><em><span style="text-decoration: underline">=&quot;pack://.+:,,.*&quot;</span></em></strong>&gt;
            <strong><em><span style="text-decoration: underline">&lt;</span></em></strong></span><strong><em><span style="text-decoration: underline"><span style="color: #a31515">auth</span><span style="color: blue">:</span><span style="color: #a31515">Deny </span><span style="color: red">Users</span></span></em></strong><span style="color: blue"><strong><em><span style="text-decoration: underline">=&quot;*&quot; /&gt;</span></em></strong>
        &lt;/</span><span style="color: #a31515">auth</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">auth</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthorizer</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">auth</span><span style="color: blue">:</span><span style="color: #a31515">AuthContentLoader</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a></p>
<p>This allows users to access xaps on my site (open.depoll.com), while denying access to other pack uris.&#160; Coupled with the ErrorContentLoader, a consistent, safe experience can be provided for users.</p>
<h3>MEF and Prism</h3>
<p>At this point, you might be asking yourself why I rolled my own solution to this problem?&#160; MEF and Prism both have very effective implementations for modularization of applications, and you could certainly build very similar ContentLoaders based upon their libraries for loading xaps (in fact, I hope to see folks out there do so! <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ).&#160; Really, the reason I rolled my own libraries for this is twofold:</p>
<ul>
<li>Support for cached assemblies – I wanted to make sure to attempt to solve the shared dependency problem described earlier </li>
<li>Size – it’s important to keep the size of the bootstrapping assemblies small in order to reap the benefits of dynamic loading.&#160; The total size of the libraries required for the XapContentLoader is about 25k compressed.&#160; I’d still like to pare that down, so if folks have ideas, let me know <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </li>
</ul>
<p>If you’ve got ideas for how best to use MEF or Prism with INavigationContentLoader, let me know!&#160; If you’re already using them for modularization and want to integrate them with navigation, this is possible in Silverlight 4 thanks to INavigationContentLoader.</p>
<h3>The goods</h3>
<p>As you know by now if you’ve been following my blog, I never leave you stranded without code and a live sample!&#160; Take a look!</p>
<p><a href="http://www.davidpoll.com/Samples/XapContentLoader/ScratchApplicationTestPage.html" target="_blank"><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="An application using XapContentLoader" border="0" alt="An application using XapContentLoader" src="http://www.davidpoll.com/wp-content/uploads/2010/02/image2.png" width="644" height="434" /></a></p>
<p>Click around using the links on top and see what happens to the Uri in the browser’s address bar.&#160; You’ll note the cross-domain access as well as the use of QueryStrings (which still work, of course!).&#160; Open up <a href="http://www.fiddler2.com/Fiddler2/version.asp">Fiddler</a> or some other tool to verify that xaps and zip files for cached assemblies are only downloaded once thanks to browser caching.&#160; Enjoy it!</p>
<p>Finally, some source code for you:</p>
<li><a href="http://www.davidpoll.com/Samples/XapContentLoader/ScratchApplicationTestPage.html">Live Sample</a> (<a href="http://www.davidpoll.com/Download/SLaB/SLaBv0.3.zip">source &#8212; found in the SLaB v0.3 source under &quot;ScratchApplication&quot;</a>) </li>
<li><a href="http://www.davidpoll.com/Download/SLaB/SLaBv0.3.zip">SLaB v0.3</a> (includes source, a sample app, some tests, and binaries)
<ul>
<li>For the latest version, please check out SLaB on my <a href="http://www.davidpoll.com/downloads-and-samples/#SLaB">Downloads and Samples</a> page. </li>
<li>The v0.3 download of SLaB includes the following changes:
<ul>
<li>Added more extensible UriMapper that replicates the built-in UriMapper&#8217;s behavior but allows UriMappings to be more extensible. </li>
<li>Added UiUtilities, the first of which allows you to execute a function on the UI thread and block the calling thread until it has completed (safe to call even from the UI thread) </li>
<li>Added XapLoader, which downloads a Xap and any &quot;cached assemblies&quot; </li>
<li>Added XapContentLoader, which uses the XapLoader to navigate to pages in downloaded assemblies </li>
<li>Added PackUri utilities so that pack Uris can be used to download and navigate to pages in Xaps </li>
<li>Signed all assemblies (public binaries use a private key, another key is distributed with source) </li>
<li>Added a build task that will generate extmap files for all libraries &#8212; now assembly caching works with SLaB assemblies </li>
<li>Fixed a bug with the AuthLoader where all rules would be run, even if one rule already allowed access </li>
<li>Other minor bugfixes </li>
</ul>
</li>
</ul>
<p>Enjoy, and let me know if you have any questions, thoughts, or ideas!</p>
<p><strong><em>Remember</em></strong>, SLaB is just a collection of the samples and experimental components I’ve been putting together so that they’re all in one place.&#160; I can’t make any guarantees about maintaining them, fixing bugs, not making breaking changes, etc., but you’re more than welcome to try them out, use them, and let them inspire your development (or show you what <em>not</em> to do if you really dislike something I’m doing!) <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
</p>
</p>
</li>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2010/02/01/on-demand-loading-of-assemblies-with-silverlight-navigation-revisited-for-silverlight-4-beta/feed/</wfw:commentRss>
		<slash:comments>73</slash:comments>
		</item>
		<item>
		<title>Silverlight Toolkit November 2009: Activity Control &#8211;&gt; BusyIndicator (a.k.a. Update 3: Displaying background activity in a Silverlight RIA application)</title>
		<link>http://www.davidpoll.com/2009/11/19/silverlight-toolkit-november-2009-activity-control-busyindicator-a-k-a-update-3-displaying-background-activity-in-a-silverlight-ria-application/</link>
		<comments>http://www.davidpoll.com/2009/11/19/silverlight-toolkit-november-2009-activity-control-busyindicator-a-k-a-update-3-displaying-background-activity-in-a-silverlight-ria-application/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 06:14:45 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Activity Control]]></category>
		<category><![CDATA[BusyIndicator]]></category>
		<category><![CDATA[Silverlight 3]]></category>
		<category><![CDATA[Silverlight 4 Beta]]></category>
		<category><![CDATA[Silverlight Toolkit]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2009/11/19/silverlight-toolkit-november-2009-activity-control-busyindicator-a-k-a-update-3-displaying-background-activity-in-a-silverlight-ria-application/</guid>
		<description><![CDATA[Wow!&#160; What a week!&#160; PDC, the Silverlight 4 Beta, and now the November 2009 release of the Silverlight Toolkit!&#160; There’s been a ton of great news and exciting announcements, and now I can share with you that the Activity control, first blogged here, is now a part of the Silverlight Toolkit! Awesome!&#160; What does that [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Wow!&#160; What a week!&#160; <a href="http://www.microsoftpdc.com" target="_blank">PDC</a>, the <a href="http://www.silverlight.net/getstarted/silverlight-4-beta" target="_blank">Silverlight 4 Beta</a>, and now the November 2009 release of the <a href="http://silverlight.codeplex.com/" target="_blank">Silverlight Toolkit</a>!&#160; There’s been a ton of great news and exciting announcements, and now I can share with you that the Activity control, <a href="http://www.davidpoll.com/tag/activity-control/" target="_blank">first blogged here</a>, is now a part of the Silverlight Toolkit!</p>
<h3>Awesome!&#160; What does that mean for the Activity control?</h3>
<p>During this transition, the Activity control underwent a few changes (thanks to my colleagues working on the Toolkit – <a href="http://blogs.msdn.com/delay/" target="_blank">David Anson</a> and <a href="http://www.jeff.wilcox.name" target="_blank">Jeff Wilcox</a>) to make it more generally palatable:</p>
<ul>
<li>The control has been renamed from “Activity” to “BusyIndicator” in order to avoid confusion with the concept of an Activity (sounds a lot like “Task”)</li>
<ul>
<li>Similarly, “IsActive” is now “IsBusy”, and the visual states have been renamed appropriately as well.</li>
</ul>
<li>AutoBind and related properties have been removed once and for all.&#160; They were a performance hog in the original versions, and they really only hit a very, very narrow scenario.&#160; Instead, bind to a property that represents your busyness.</li>
<li>MinDisplayTime has gone away.&#160; If you’re looking to change the minimum display time, you can re-template the control and add a duration to the transition from visible back to hidden.</li>
<li>OverlayBrush and OverlayOpacity have been replaced with a single OverlayStyle property where you can set the color/opacity of the overlay easily.</li>
<li>DisplayAfter now defaults to 0.1s instead of 0.05s</li>
</ul>
<p>Otherwise, the control is basically the same!&#160; Give it a shot!</p>
<p>With this transition, the BusyIndicator control truly becomes accessible to anyone who’s using the Silverlight Toolkit.&#160; You can <a href="http://silverlight.codeplex.com/WorkItem/List.aspx" target="_blank">report bugs through that project on codeplex</a>, and we’ll make sure to keep an eye on any feedback we get from you on the control.</p>
<h3>Great… So where can I find it?</h3>
<p>It’s simple!&#160; Just download the November 2009 Silverlight Toolkit for either Silverlight 3 or Silverlight 4.&#160; There are a few ways to get it:</p>
<ul>
<li><a href="http://silverlight.codeplex.com" target="_blank">Silverlight Toolkit Codeplex Page</a></li>
<li><a href="http://www.jeff.wilcox.name/2009/11/toolkit-webpi/" target="_blank">Web Platform Installer</a></li>
</ul>
<p>The BusyIndicatorControl can be found in the <strong>System.Windows.Controls</strong> namespace in the <strong>System.Windows.Controls.Toolkit.dll</strong> assembly in the toolkit.</p>
<h3></h3>
<h3>And… can I see it in action?</h3>
<p>Yep!&#160; David Anson created some awesome samples in the Toolkit Sample Browser for the BusyIndicator.&#160; I’m a big fan of his work! <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a href="http://silverlight.net/content/samples/sl3/toolkitcontrolsamples/run/default.html" target="_blank"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="BusyIndicator is now in the Silverlight Toolkit sample browser!" border="0" alt="BusyIndicator is now in the Silverlight Toolkit sample browser!" src="http://www.davidpoll.com/Images/Sil.Update3Displayingbackgroundactivityi_138BA/image.png" width="644" height="435" /></a> </p>
<p>I hope you all enjoy using the BusyIndicator control in your applications!&#160; Let me know what you think!</p>
<p>P.S. Thanks to Jeff Wilcox, who <a href="http://www.jeff.wilcox.name/2009/11/busy-indicator-control/" target="_blank">beat me to explaining this change</a> <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> &#160; I’ve been super-busy with PDC, so it was good to have someone start getting the word out early.&#160; Jeff gives a great overview of what the control is meant to do and has lots of resources regarding the Silverlight Toolkit.&#160; Check out his <a href="http://www.jeff.wilcox.name" target="_blank">blog</a>!</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2009/11/19/silverlight-toolkit-november-2009-activity-control-busyindicator-a-k-a-update-3-displaying-background-activity-in-a-silverlight-ria-application/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Silverlight 4 and building business applications (PDC09-CL19)</title>
		<link>http://www.davidpoll.com/2009/11/19/silverlight-4-and-building-business-applications-pdc09-cl19/</link>
		<comments>http://www.davidpoll.com/2009/11/19/silverlight-4-and-building-business-applications-pdc09-cl19/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 17:28:56 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[.NET RIA Services]]></category>
		<category><![CDATA[BusyIndicator]]></category>
		<category><![CDATA[CollectionView]]></category>
		<category><![CDATA[Data Binding]]></category>
		<category><![CDATA[PDC]]></category>
		<category><![CDATA[PDC09]]></category>
		<category><![CDATA[Silverlight 4 Beta]]></category>
		<category><![CDATA[Validation]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>
		<category><![CDATA[WCF RIA Services]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2009/11/19/silverlight-4-and-building-business-applications-pdc09-cl19/</guid>
		<description><![CDATA[Hi everyone!&#160; Wow – yesterday was a big day, with a lot of amazing announcements at PDC ‘09 – especially the announcement that the Silverlight 4 Beta was publicly available.&#160; I was very excited to be given an opportunity to give a talk at PDC this year, and it was a real treat.&#160; My talk [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Hi everyone!&#160; Wow – yesterday was a big day, with a lot of amazing announcements at <a href="http://www.microsoftpdc.com">PDC ‘09</a> – especially the announcement that the <a href="http://www.silverlight.net/getstarted/silverlight-4-beta/">Silverlight 4 Beta was publicly available</a>.&#160; I was very excited to be given an opportunity to give a talk at PDC this year, and it was a real treat.&#160; My talk – <a href="http://microsoftpdc.com/Sessions/CL19">Building Line of Business Applications with Silverlight 4 (PDC09-CL19)</a> – focused on the new features in Silverlight 4 that are particularly useful in business applications, especially those that are data-centric. <em>(Please ignore the abstract given on that page for the talk – it wasn’t updated properly from a change we made to it early on! <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )</em></p>
<p><img style="border-right-width: 0px; margin: 0px 0px 10px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="After the announcement of Silverlight 4, my talk appeared on the big board!" border="0" alt="After the announcement of Silverlight 4, my talk appeared on the big board!" align="right" src="http://www.davidpoll.com/Images/Silverlight4andbuildingbusinessapplicati_82ED/43685563_3.jpg" width="287" height="475" /></p>
<p>The talk covered a wide array of features, but I broke things down into three conceptual categories around data:</p>
<ul>
<li>Data Interactivity (i.e. how do I drill down into my data to find what I’m looking for?) </li>
<li>Data Entry (i.e. how do users add/edit data and what kind of feedback do you give them to minimize mistakes?) </li>
<li>Data Presentation (i.e. how do I communicate data to a user, but also how do I communicate intent for data entry, such as “choose from this list of options” to a user?) </li>
</ul>
<p>The Silverlight 4 features I covered generally fit into these categories:</p>
<ul>
<li>Data Interactivity
<ul>
<li>Data sources window (VS2010) </li>
<li>Selector support (i.e. SelectedValue/SelectedValuePath on ComboBox and related controls) </li>
<li>Binding TargetNullValue </li>
<li>Binding FallbackValue </li>
<li>ICommand support on ButtonBase (i.e. Command and CommandParameter) and Hyperlink </li>
</ul>
</li>
<li>Data Entry
<ul>
<li>Asynchronous validation </li>
<li>Cross-field validation </li>
</ul>
</li>
<li>Data Presentation
<ul>
<li>Binding StringFormat </li>
<li>CollectionViewSource Grouping </li>
<li>Printing and pagination </li>
<li>DataGrid * Columns (*-based column sizing, as with the Grid control) </li>
</ul>
</li>
</ul>
<p>And all of this is just the short list of features I could cover in my 50-minute talk!&#160; There are certainly other business application-friendly features out there, but more importantly, the feature list for Silverlight 4 is just <a href="http://www.silverlight.net/getstarted/silverlight-4-beta/#whatsnew">huge</a>!&#160; The talk also used <a href="http://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx">Visual Studio 2010 Beta 2</a>, which provides an awesome development environment for Silverlight.</p>
<p>I won’t go into too much detail here, but I wanted to share out my powerpoint deck and sample/demo code so that those who were in attendance at the talk can look back for reference, and those that weren’t can see what they were missing.&#160; I don’t know for sure yet, but I think there will be a webcast of the talk online at some point, and I’ll be happy to link to that once it’s available.</p>
<p>So, without further ado, here are the links:</p>
<ul>
<li><a href="http://www.davidpoll.com/Download/CL19_POLL.pptx">PDC ‘09 PPT deck</a> </li>
<li>Issue tracker demo application (<a href="http://www.davidpoll.com/Download/IssueTracker_Final.zip">source</a>) </li>
</ul>
<p>Before I leave you, I’d like to just give a brief overview of the sample application.&#160; The application itself is an issue tracker – allowing you to file bugs/issues, assign them to people, resolve the bugs, etc.&#160; It has 4 functional pages:</p>
<ul>
<li>New Issue
<ul>
<li>Allows users to file a new bug/issue </li>
</ul>
</li>
<li>All Issues
<ul>
<li>Allows users to see a list of all bugs in the database </li>
</ul>
</li>
<li>My Issues
<ul>
<li>Allows users to see un-fixed issues that are assigned to them </li>
</ul>
</li>
<li>Reports
<ul>
<li>Allows users to see a report of all of the issues in the database and print them if he/she so desires </li>
</ul>
</li>
</ul>
<p>The application was built using LINQ-to-SQL and <a href="http://www.silverlight.net/getstarted/riaservices/">WCF RIA Services</a> (formerly .NET RIA Services), which made getting off the ground with real data running on a real database extremely quick and easy.&#160; If you’re still around at PDC, there are a few talks later today on RIA Services by <a href="http://blogs.msdn.com/brada">Brad Abrams</a> and <a href="http://blogs.msdn.com/dinesh.kulkarni/">Dinesh Kulkarni</a> you should check out.</p>
<p>A few things to try in the application (some of which I didn’t go over in the talk):</p>
<ul>
<li>Right-click and change the theme of the application
<ul>
<li>Many thanks to my co-worker <a href="http://www.jebishop.com/">Jesse Bishop</a> for his <a href="http://www.jebishop.com/2009/11/18/implementing-a-contextmenu-in-silverlight-4-beta/">ContextMenu control</a> </li>
<li>This feature uses implicit styles (new in SL4) to change the entire look of the application </li>
</ul>
</li>
<li>Set the priority on a bug to be lower than (i.e. a larger number than) severity and see the validation UI (cross-field validation) </li>
<li>Set the title of an issue to be something wholly contained in another issue’s title to see the validation UI (asynchronously querying the server for “similar” bugs) </li>
<li>Drag and drop a file from your disk into the list of files on a bug (one of the tabs at the bottom) </li>
<li>Print out a set of reports on the reports page (click the “Print” button) </li>
<li>Set a value in the “Tags” field and then change it in the DataGrid under the Attributes tab on a bug, noticing that they stay in sync (thanks to bindings to string indexers) </li>
<li>Use the mouse-wheel almost anywhere and note that it works without any code to make it happen! </li>
<li>Explore the code!&#160; I know there are some bugs in the application and in our beta product, but the hope is to give you an idea of how you can use these features in a business application.&#160; I’m sure there will be lots of content out there about all of these features – but this should help introduce you to them! </li>
</ul>
<p>Well, thanks again everyone who was able to join me for my talk, and to all those who’ve been following me on twitter through this exciting announcement.&#160; Let me know if you have questions or if there’s anything you’d like me to expand on, and I’ll be more than happy to chime in!</p>
<p>&#160;</p>
<p><em>Links to materials repeated here for convenience:</em></p>
<ul>
<li><a href="http://www.davidpoll.com/Download/CL19_POLL.pptx">PDC ‘09 PPT deck</a> </li>
<li>Issue tracker demo application (<a href="http://www.davidpoll.com/Download/IssueTracker_Final.zip">source</a>) </li>
</ul>
<p><strong><em>Update (11/19/2009): </em></strong>Video of the talk is now available here: <a title="http://microsoftpdc.com/Sessions/CL19" href="http://microsoftpdc.com/Sessions/CL19">http://microsoftpdc.com/Sessions/CL19</a></p>
<p><strong><em>Update (11/20/2009): </em></strong>Video of the talk is embedded below:</p>
<p> <object data="data:application/x-silverlight-2," height="337.5" type="application/x-silverlight-2" width="600"><param name="source" value="http://microsoftpdc.com/Skins/PDC09/Styles/players/VideoPlayer2009_03_27.xap" /><param name="initParams" value="m=http://ecn.channel9.msdn.com/o9/pdc09/wmvhigh/CL19.wmv,autostart=false,autohide=true,showembed=true, thumbnail=http://microsoftpdc.com/Skins/PDC09/Styles/images/DefaultPlayerBackground.png, postid=0" /><param name="background" value="#00FFFFFF" /><a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;"> 	 	<img alt="Get Microsoft Silverlight" src="http://go.microsoft.com/fwlink/?LinkId=108181" style="border-style: none" /> 	 	</a> </object>
<p>P.S.&#160; Sorry for the lack of posts recently – I’ve got a bunch of new topics lined up, but it was a pity not to be able to write about Silverlight 4 before it was announced.&#160; Expect another series on Navigation coming soon!</p>
<p>&#160;</p>
<p><em><strong>Update (12/21/2009):</strong> </em>I think I’ve figured out the issue people were having with the downloaded project.</p>
<p>If you’re receiving an error like this when you try to build my project:</p>
<p><a href="http://www.davidpoll.com/wp-content/uploads/2009/12/image.png"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="Error	4	The &quot;ValidateXaml&quot; task failed unexpectedly." border="0" alt="Error	4	The &quot;ValidateXaml&quot; task failed unexpectedly." src="http://www.davidpoll.com/wp-content/uploads/2009/12/image_thumb.png" width="644" height="205" /></a> </p>
<p>This is happening because Windows protects you from downloaded files by default (VS2010 will warn you when you open the project that they come from “untrusted sources.”&#160; Fixing this is pretty straightforward.</p>
<ol>
<li>Download the <a href="http://www.davidpoll.com/Download/IssueTracker_Final.zip">zip</a>.</li>
<li>Right-click the downloaded zip file and choose “Properties”</li>
<li>At the bottom of the “General” tab, there is a “Security” section, saying “This file came from another computer and might be blocked to help protect this computer.”&#160; Click the “Unblock” button.     <br /><a href="http://www.davidpoll.com/wp-content/uploads/2009/12/image1.png"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="Click the &quot;Unblock&quot; button." border="0" alt="Click the &quot;Unblock&quot; button." src="http://www.davidpoll.com/wp-content/uploads/2009/12/image_thumb1.png" width="381" height="519" /></a> </li>
<li>Unzip and open the solution.</li>
<li>Build and run!</li>
</ol>
<p>Sorry it took me so long to figure this one out!&#160; It had me stumped for a while.</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2009/11/19/silverlight-4-and-building-business-applications-pdc09-cl19/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
<enclosure url="http://ecn.channel9.msdn.com/o9/pdc09/wmvhigh/CL19.wmv" length="669448911" type="video/x-ms-wmv" />
		</item>
		<item>
		<title>Update 2: Displaying background activity in a Silverlight RIA application</title>
		<link>http://www.davidpoll.com/2009/09/14/update-2-displaying-background-activity-in-a-silverlight-ria-application/</link>
		<comments>http://www.davidpoll.com/2009/09/14/update-2-displaying-background-activity-in-a-silverlight-ria-application/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 07:45:50 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[.NET RIA Services]]></category>
		<category><![CDATA[Activity Control]]></category>
		<category><![CDATA[BusyIndicator]]></category>
		<category><![CDATA[Silverlight 3]]></category>
		<category><![CDATA[WCF RIA Services]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2009/09/14/update-2-displaying-background-activity-in-a-silverlight-ria-application/</guid>
		<description><![CDATA[Hi folks!&#160; It’s been a little while since I’ve blogged, but fear not, I’m still watching and hoping to blog more in the coming weeks. In the meantime, it’s been brought to my attention by a few people now that there are a few issues with the Activity control, and I wanted to address them. [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Hi folks!&#160; It’s been a little while since I’ve blogged, but fear not, I’m still watching and hoping to blog more in the coming weeks.</p>
<p>In the meantime, it’s been brought to my attention by a few people now that there are a few issues with the Activity control, and I wanted to address them.</p>
<ol>
<li>Performance – A bit of a mea culpa on my part.&#160; I included a feature for the control that I’ve called “AutoBind”, whereby it would watch for changes to the visual tree of its contents and subscribe to any control that has a property whose name matches “ActivityPropertyName”.&#160; By default, this is great when working with .NET RIA Service’s DomainDataSource, since ActivityPropertyName is “IsBusy” by default, but it also turns out to be a hefty amount of work, constantly searching the visual tree and registering/unregistering event handlers.&#160; This wouldn’t be so bad, except that AutoBind defaults to true, meaning even if you’re not using this functionality, the Activity control is doing the work.&#160; Below, you’ll find a new version of the Activity control that amends the situation, making AutoBind default to false.&#160; This is the only change to the control since my last post on the matter, but I’d love to hear if you have thoughts about the control, this feature, or other requests!</li>
<li>.NET RIA Services’ Business Application Template – So, the .NET RIA Services guys included with their <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=76bb3a07-3846-4564-b0c3-27972bcaabce&amp;displaylang=en">July Preview</a> a project template to help you get started with a RIA Services application.&#160; In this template, they included a dll with the Activity control in it.&#160; A few people have noted that it has a slightly different API than they’re used to seeing with the control, which is due to their use of the original version of the control that I posted (its API has changed a bit since then, and a number of bugs were fixed, including some layout issues).&#160; Anyhoo, feel free to pick up the latest version below!</li>
</ol>
<p>So there you have it – just a few changes and things to note.&#160; You can find the control here:</p>
<ul>
<li><a href="http://www.davidpoll.com/Download/ActivityControl9-14.zip">Activity Control</a></li>
<li><a href="http://www.davidpoll.com/Download/ActivityControlDemo9-14.zip">Activity control demo project</a></li>
</ul>
<p>Thanks for all the great feedback since I first posted this control.&#160; As usual, let me know if you have questions or issues!</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2009/09/14/update-2-displaying-background-activity-in-a-silverlight-ria-application/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>On-demand loading of assemblies with Silverlight Navigation</title>
		<link>http://www.davidpoll.com/2009/07/20/on-demand-loading-of-assemblies-with-silverlight-navigation/</link>
		<comments>http://www.davidpoll.com/2009/07/20/on-demand-loading-of-assemblies-with-silverlight-navigation/#comments</comments>
		<pubDate>Mon, 20 Jul 2009 22:01:00 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[BusyIndicator]]></category>
		<category><![CDATA[Dynamic Navigation]]></category>
		<category><![CDATA[Navigation]]></category>
		<category><![CDATA[Silverlight 3]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2009/07/21/on-demand-loading-of-assemblies-with-silverlight-navigation/</guid>
		<description><![CDATA[As those of you who’ve been reading my blog may know, I’ve been spending a bit of time with some enhancements to navigation in Silverlight surrounding the use of dynamically-loaded assemblies.&#160; I’ve still got a bunch of things I’d like to try to implement, but in the meantime I thought I’d share what I’ve got [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>As those of you who’ve been reading my blog may know, I’ve been spending a bit of time with some enhancements to navigation in Silverlight surrounding the use of dynamically-loaded assemblies.&#160; I’ve still got a bunch of things I’d like to try to implement, but in the meantime I thought I’d share what I’ve got so far.</p>
<p>Now that I have a mechanism for navigating to Pages in dynamically-loaded assemblies in Silverlight, the question arises: how can I improve the user and developer experience around partitioning applications in this way?</p>
<p>In particular, this is the flow I’d like to be able to create:</p>
<ul>
<li>Developer knows the set of Pages his user will be able to navigate to, and partitions them into assemblies that he will load at runtime </li>
<li>Furthermore, the developer knows the dependencies those assemblies have on other dynamically-loaded assemblies (e.g. multiple assemblies contain Pages that use DataGrid, but System.Windows.Controls.Data should be shared/downloaded when the first of those assemblies is downloaded) </li>
<li>The user is presented with some sort of navigation UI (e.g. HyperlinkButtons, buttons that call Frame.Navigate(), etc.) </li>
<li>When the user requests a page in an assembly that has not yet been downloaded, it should be automatically downloaded, and navigation with the Frame should only complete once the Page can be loaded. </li>
</ul>
<p>With this on-demand loading behavior, deep-linking into applications with dynamically-loaded assemblies can be re-enabled (you’ll notice if you try to deep-link into my sample from my <a href="http://www.davidpoll.com/?p=92">previous post</a> about dynamically-loaded assemblies, you get an exception, since the assembly hasn’t been loaded yet).</p>
<p>I’m developing some utilities that will make this flow easier to accomplish.&#160; Please note that at this point all of the API, etc. is subject to change, and I’m definitely not making any assurances around bugs, quality, or anything of the sort, but I thought I’d share what I’ve been working on and start getting some feedback from you folks!</p>
<p>Anyhoo, let’s take this step by step:</p>
<p><strong><span style="font-size: medium">Dividing an application into multiple assemblies</span></strong></p>
<p>This is fairly straightforward, and something I’m sure most of you have been doing for a long time.&#160; For our purposes, there are a number of things to consider:</p>
<ul>
<li>Pages in these assemblies that will be dynamically loaded should use the DynamicPage and DynamicPageShim (or some other workaround you may have come up with) described in my <a href="http://www.davidpoll.com/?p=92">earlier post</a> </li>
<li>Any dynamically-loaded assemblies need to be in a place accessibly using the WebRequest APIs in Silverlight.&#160; I usually put them in my ClientBin folder, and I used a post-build task to copy any dlls for those assemblies into the correct folder (feel free to see my Sample project for an example of this) </li>
<li>The libraries I’ve built support loading DLLs as well as XAP and ZIP files with dlls in them. Just using DLLs is probably the easiest way to go, but using ZIP or XAP files will keep the transfer time/size small. </li>
<li>Remember to take careful note of any dependencies between the libraries.&#160; You’ll need to make sure they’re all loaded into your application before attempting to use the assemblies. </li>
</ul>
<p>One thing I might do in the future is (attempt to) make a project template that will create a XAP class library that places the XAP in the ClientBin folder for you.&#160; I’m still experimenting with how to do this, but it’s still worth noting that using XAPs can be problematic if you’re sharing libraries (VS will automatically package shared assemblies into your XAP, so you might end up with copies of System.Windows.Controls.Navigation.dll in 3 or 4 XAPs, and since they’re all packaged up with the rest of the assemblies, you’ll end up downloading the same DLL multiple times.</p>
<p><strong><span style="font-size: medium">Describing how to load assemblies dynamically</span></strong></p>
<p>I’ve created a little utility that I call “DynamicLoader,” which allows you to declare, in XAML, where your dynamic DLLs can be downloaded from and their interdependencies.&#160; In my App.xaml, I specify the various libraries that may be loaded dynamically (incidentally, some of these libraries are also in my XAP, and the loader will use the ones built into the XAP rather than re-downloading them automatically).&#160; I also describe the various interdependencies between my libraries.&#160; Some are unnecessary (because the dependencies are already in the XAP), but I chose to be explicit for some of the more complex ones to remove all doubt.&#160; An example (from my sample project) can be seen below.</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">DynamicLoader </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Key</span><span style="color: blue">=&quot;loader&quot;&gt;
    &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">AssemblyDescription </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;DynamicallyLoadedLibrary&quot;
                              </span><span style="color: red">Location</span><span style="color: blue">=&quot;./DynamicallyLoadedLibrary.dll&quot; /&gt;
    &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">AssemblyDescription </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;DynamicallyLoadedLibraryVB&quot;
                              </span><span style="color: red">Location</span><span style="color: blue">=&quot;./DynamicallyLoadedLibraryVB.dll&quot; /&gt;
    &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">AssemblyDescription </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;LargeDynamicallyLoadedLibrary&quot;
                              </span><span style="color: red">Location</span><span style="color: blue">=&quot;./LargeDynamicallyLoadedLibrary.dll&quot;&gt;
        &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">Dependency </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Controls&quot; /&gt;
        &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">Dependency </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Controls.Data&quot; /&gt;
        &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">Dependency </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Controls.Data.DataForm.Toolkit&quot; /&gt;
        &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">Dependency </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Controls.Data.Input&quot; /&gt;
        &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">Dependency </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Controls.DataVisualization.Toolkit&quot; /&gt;
        &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">Dependency </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Controls.Navigation&quot; /&gt;
        &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">Dependency </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Data&quot; /&gt;
        &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">Dependency </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.ComponentModel.DataAnnotations&quot; /&gt;
    &lt;/</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">AssemblyDescription</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">AssemblyDescription </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Controls&quot;
                              </span><span style="color: red">Location</span><span style="color: blue">=&quot;./System.Windows.Controls.dll&quot; /&gt;
    &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">AssemblyDescription </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Controls.Data&quot;
                              </span><span style="color: red">Location</span><span style="color: blue">=&quot;./System.Windows.Controls.Data.dll&quot;&gt;
        &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">Dependency </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.ComponentModel.DataAnnotations&quot; /&gt;
        &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">Dependency </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Controls.Data.Input&quot; /&gt;
        &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">Dependency </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Data&quot; /&gt;
    &lt;/</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">AssemblyDescription</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">AssemblyDescription </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Controls.Data.DataForm.Toolkit&quot;
                              </span><span style="color: red">Location</span><span style="color: blue">=&quot;./System.Windows.Controls.Data.DataForm.Toolkit.dll&quot;&gt;
        &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">Dependency </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.ComponentModel.DataAnnotations&quot; /&gt;
        &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">Dependency </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Data&quot; /&gt;
    &lt;/</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">AssemblyDescription</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">AssemblyDescription </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Controls.Data.Input&quot;
                              </span><span style="color: red">Location</span><span style="color: blue">=&quot;./System.Windows.Controls.Data.Input.dll&quot;&gt;
        &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">Dependency </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.ComponentModel.DataAnnotations&quot; /&gt;
    &lt;/</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">AssemblyDescription</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">AssemblyDescription </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Controls.DataVisualization.Toolkit&quot;
                              </span><span style="color: red">Location</span><span style="color: blue">=&quot;./System.Windows.Controls.DataVisualization.Toolkit.dll&quot; /&gt;
    &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">AssemblyDescription </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Controls.Navigation&quot;
                              </span><span style="color: red">Location</span><span style="color: blue">=&quot;./System.Windows.Controls.Navigation.dll&quot; /&gt;
    &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">AssemblyDescription </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.Windows.Data&quot;
                              </span><span style="color: red">Location</span><span style="color: blue">=&quot;./System.Windows.Data.dll&quot; /&gt;
    &lt;</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">AssemblyDescription </span><span style="color: red">AssemblyName</span><span style="color: blue">=&quot;System.ComponentModel.DataAnnotations&quot;
                              </span><span style="color: red">Location</span><span style="color: blue">=&quot;System.ComponentModel.DataAnnotations.dll&quot; /&gt;
&lt;/</span><span style="color: #a31515">load</span><span style="color: blue">:</span><span style="color: #a31515">DynamicLoader</span><span style="color: blue">&gt;</span></pre>
<p>The Location specified in each AssemblyDescription is a URI.&#160; In this case, all of my dlls are in my ClientBin directory, so they all begin with “./”, but these could be any URI that can be reached by the Silverlight application.&#160; Furthermore, if you wish to use the new ClientHttp networking stack to do the downloading, you can choose to do so (as part of the AssemblyDescription).</p>
<p>The loader will asynchronously load any requested library (by name), and will only fire Loaded events once all of each assembly’s dependencies have been loaded.&#160; This allows us to know when it’s safe to try to navigate to a Page in a dynamically-loaded assembly.</p>
<p><strong><span style="font-size: medium">Creating Navigation UI</span></strong></p>
<p>Nothing too special to share here.&#160; HyperlinkButtons use the exact same URI scheme as before (for navigating to pages in <a href="http://www.davidpoll.com/2009/07/12/silverlight-3-navigation-navigating-to-pages-in-referenced-assemblies/">referenced</a>/<a href="http://www.davidpoll.com/?p=92">dynamically-loaded</a> assemblies).&#160; Here’s what my XAML for my navigation bar looks like:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">Border </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;LinksBorder&quot; </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">LinksBorderStyle</span><span style="color: blue">}&quot;&gt;
    &lt;</span><span style="color: #a31515">StackPanel </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;LinksStackPanel&quot; </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">LinksStackPanelStyle</span><span style="color: blue">}&quot;&gt;

        &lt;</span><span style="color: #a31515">HyperlinkButton </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;Link1&quot; </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">LinkStyle</span><span style="color: blue">}&quot;
                     </span><span style="color: red">NavigateUri</span><span style="color: blue">=&quot;/Home&quot; </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Content</span><span style="color: blue">=&quot;home&quot;/&gt;

        &lt;</span><span style="color: #a31515">Rectangle </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;Divider1&quot; </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">DividerStyle</span><span style="color: blue">}&quot;/&gt;

        &lt;</span><span style="color: #a31515">HyperlinkButton </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;Link2&quot; </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">LinkStyle</span><span style="color: blue">}&quot;
                     </span><span style="color: red">NavigateUri</span><span style="color: blue">=&quot;/About&quot; </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Content</span><span style="color: blue">=&quot;about&quot;/&gt;

        &lt;</span><span style="color: #a31515">Rectangle </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;Divider2&quot; </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">DividerStyle</span><span style="color: blue">}&quot;/&gt;

        &lt;</span><span style="color: #a31515">HyperlinkButton </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;csharp&quot; </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">LinkStyle</span><span style="color: blue">}&quot; </span><span style="color: red">IsEnabled</span><span style="color: blue">=&quot;True&quot;
                     </span><span style="color: red">NavigateUri</span><span style="color: blue">=&quot;/DynamicallyLoadedLibrary;component/CSDynamicPage.dyn.xaml&quot; </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Content</span><span style="color: blue">=&quot;C# Class Library&quot;/&gt;

        &lt;</span><span style="color: #a31515">Rectangle </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;Divider3&quot; </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">DividerStyle</span><span style="color: blue">}&quot;/&gt;

        &lt;</span><span style="color: #a31515">HyperlinkButton </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;vb&quot; </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">LinkStyle</span><span style="color: blue">}&quot; </span><span style="color: red">IsEnabled</span><span style="color: blue">=&quot;True&quot;
                     </span><span style="color: red">NavigateUri</span><span style="color: blue">=&quot;/DynamicallyLoadedLibraryVB;component/VBDynamicPage.dyn.xaml&quot; </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Content</span><span style="color: blue">=&quot;VB Class Library&quot;/&gt;

        &lt;</span><span style="color: #a31515">Rectangle </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;Divider4&quot; </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">DividerStyle</span><span style="color: blue">}&quot;/&gt;

        &lt;</span><span style="color: #a31515">HyperlinkButton </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;large&quot; </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">LinkStyle</span><span style="color: blue">}&quot; </span><span style="color: red">IsEnabled</span><span style="color: blue">=&quot;True&quot;
                     </span><span style="color: red">NavigateUri</span><span style="color: blue">=&quot;/LargeDynamicallyLoadedLibrary;component/LargeDynamicPage.dyn.xaml&quot; </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Content</span><span style="color: blue">=&quot;Large Class Library&quot;/&gt;
    &lt;/</span><span style="color: #a31515">StackPanel</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">Border</span><span style="color: blue">&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Again, nothing too scary here – the XAML remains identical to its form without the dynamically-loaded libraries.</p>
<p><strong><span style="font-size: medium">Adding on-demand navigation</span></strong></p>
<p>The other important piece of this puzzle is a Frame control that uses the loader to ensure that dynamically-loaded libraries are loaded into the AppDomain before attempting to navigate to pages within those libraries.&#160; I’ve provided a derived Frame class (DynamicNavigation.Utilities.Controls.Frame) that does precisely this.&#160; As with my DynamicPage class, you should expect a few quirks, since the Frame class from which it derives doesn’t have any virtual methods.&#160; Don’t cast my Frame to a System.Windows.Controls.Frame if you don’t want to get a bunch of extra events for Loading, Loaded, etc.&#160; Also, since I couldn’t replace the NavigationService, if you subscribe to events on that service, you’ll see a large number of extra events being raised.&#160; Neither of these eccentricities should hamper functionality, but you may see some unexpected activity if you watch those events!</p>
<p>My Frame class takes an DynamicLoader and delegates all loading of dynamic libraries to it.&#160; Here’s what my XAML declaration of the Frame looks like (plus or minus some extraneous attributes):</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">dnav</span><span style="color: blue">:</span><span style="color: #a31515">Frame </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">ContentFrameStyle</span><span style="color: blue">}&quot;
            </span><span style="color: red">DynamicLoader</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">loader</span><span style="color: blue">}&quot;
            </span><span style="color: red">Source</span><span style="color: blue">=&quot;/Home&quot;&gt;
    &lt;</span><span style="color: #a31515">dnav</span><span style="color: blue">:</span><span style="color: #a31515">Frame.UriMapper</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapper</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapping </span><span style="color: red">Uri</span><span style="color: blue">=&quot;&quot; </span><span style="color: red">MappedUri</span><span style="color: blue">=&quot;/Views/Home.xaml&quot;/&gt;
            &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapping </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/{a};component/{p}&quot; </span><span style="color: red">MappedUri</span><span style="color: blue">=&quot;/{a};component/{p}&quot; /&gt;
            &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapping </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/{pageName}&quot; </span><span style="color: red">MappedUri</span><span style="color: blue">=&quot;/Views/{pageName}.xaml&quot;/&gt;
        &lt;/</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapper</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">dnav</span><span style="color: blue">:</span><span style="color: #a31515">Frame.UriMapper</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">dnav</span><span style="color: blue">:</span><span style="color: #a31515">Frame</span><span style="color: blue">&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>And that’s it!&#160; With my custom Frame class, it take <strong>*zero*</strong> code to get dynamic loading up and running – only XAML is necessary.&#160; Attach an Activity control to the loader, and you’re hot to trot!</p>
<p><strong><span style="font-size: medium">In Conclusion</span></strong></p>
<p>Well, there you have it!&#160; I’d like to remind folks that none of the APIs here are intended to be concrete, and I make no guarantees of quality – I’m just trying to demonstrate how it can be done, and if the interest is there, I’ll keep investing some time in exploring this.&#160; I’ve got a bunch of ideas for where I can go from here, things I’d like to change/improve, and I look forward to playing some more with these prototypes.</p>
<p>Without further ado, here are the links I’m sure you’re all waiting for:</p>
<ul>
<li><a href="http://www.davidpoll.com/Download/DynamicNavigation.zip">DynamicNavigation libraries</a> (for your consumption) </li>
<li><a href="http://www.davidpoll.com/Samples/OnDemandDownload/DynamicNavigationApplicationTestPage.html">Live Sample</a> </li>
<li><a href="http://www.davidpoll.com/Samples/Download/OnDemandNavigationSample.zip">Sample Source</a> </li>
</ul>
<p><strong><span style="font-size: medium">What’s next?</span></strong></p>
<p>Well, I’ve got a lot of ideas, and I’d love to hear some from you all.&#160; Here are some of mine (not making any promises – I’m just experimenting with these):</p>
<ul>
<li>Cache to IsoStore – downloaded libraries could be stored in Isolated Storage and loaded from there if they’re already on the machine </li>
<li>Install – When the application is taken out of browser, automatically download the assemblies to Isolated Storage and load from there, allowing the entire application to be run offline </li>
<li>URI scheme/custom loading – I’d love to be able to just specify the whole deal in a URI to a page, such as “pack://http:,,www.davidpoll.com,Samples,ClientBin,MyLibrary.dll;component/Page2.dyn.xaml” and not need the big manifest with assembly name/location mappings and dependencies. </li>
<li>Dependencies for particular URIs – allows the Frame control to pre-load assemblies before a particular page is loaded, even if the page is a local one (thanks, Austin, for this idea!) </li>
</ul>
<p>Anyway, I’ve got a thousand other ideas racing through my mind right now, but those are just a few.&#160; What do you think?&#160; Is there anything you dislike about my approach or anything you particularly like?&#160; Speak up!</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2009/07/20/on-demand-loading-of-assemblies-with-silverlight-navigation/feed/</wfw:commentRss>
		<slash:comments>49</slash:comments>
		</item>
		<item>
		<title>Silverlight 3 Navigation: Navigating to Pages in referenced assemblies</title>
		<link>http://www.davidpoll.com/2009/07/12/silverlight-3-navigation-navigating-to-pages-in-referenced-assemblies/</link>
		<comments>http://www.davidpoll.com/2009/07/12/silverlight-3-navigation-navigating-to-pages-in-referenced-assemblies/#comments</comments>
		<pubDate>Sun, 12 Jul 2009 08:58:18 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[BusyIndicator]]></category>
		<category><![CDATA[Dynamic Navigation]]></category>
		<category><![CDATA[Navigation]]></category>
		<category><![CDATA[Silverlight 3]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/?p=88</guid>
		<description><![CDATA[At long last, Silverlight 3 has arrived!&#160; That, in and of itself, is worth a thousand blog posts, but since there’s a plethora of folks out there doing precisely that as I type, I’ll start right out with some content on one of the new features of Silverlight 3 – Navigation. In this post, I’ll [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>At long last, <a href="http://silverlight.net/GetStarted/" target="_blank">Silverlight 3</a> has arrived!&#160; That, in and of itself, is worth a thousand blog posts, but since there’s a plethora of folks out there doing precisely that as I type, I’ll start right out with some content on one of the <a href="http://silverlight.net/getstarted/silverlight3/default.aspx" target="_blank">new features</a> of Silverlight 3 – Navigation.</p>
<p>In this post, I’ll look at some basic navigation functionality in Silverlight 3.&#160; Silverlight 3 navigation is based on navigating a Frame control to a particular Page control.&#160; On top of allowing non-linear navigation throughout your Silverlight application, the Frame control will integrate with your browser’s history and address bar, allowing you to provide deep-links to Pages within your application and provide a more web-like experience within Silverlight applications.</p>
<p>Using Pages and Navigation in this way allows you to structure your application much like you would a web page, with various pages providing differing functionality.&#160; Like web pages, Silverlight 3 navigation allows you to pass data through query strings, perform fragment navigation, and so on – great topics for another post <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Basic navigation to pages in your main (application) project is simple – HyperlinkButtons can target a Frame, and specify the path to the Page’s XAML file, like so:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Source</span><span style="color: blue">=&quot;/Views/Home.xaml&quot;</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame</span><span style="color: blue">&gt;</span><span style="color: blue">
&lt;</span><span style="color: #a31515">StackPanel</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">HyperlinkButton </span><span style="color: red">NavigateUri</span><span style="color: blue">=&quot;/Views/Home.xaml&quot; </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Content</span><span style="color: blue">=&quot;home&quot;/&gt;
</span><span style="color: blue">    &lt;</span><span style="color: #a31515">HyperlinkButton </span><span style="color: red">NavigateUri</span><span style="color: blue">=&quot;/Views/About.xaml&quot; </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Content</span><span style="color: blue">=&quot;about&quot;/&gt;
&lt;/</span><span style="color: #a31515">StackPanel</span><span style="color: blue">&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>In this case, my Pages are “Home” and “About”, located in a Views folder within my Silverlight Application project.&#160; Clicking on the links results in changes to the address bar in my web browser, as you can see in the image below.&#160; The path in the hyperlink is displayed after the hash mark (#) in the URL.&#160; I could send someone this link to bring them right back to the specified page in my application.</p>
<p><a href="http://www.davidpoll.com/Samples/MultiAssemblyNavigation/TestPage.html#/Views/About.xaml"><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="Address bar after navigating" border="0" alt="Address bar after navigating" src="http://davidpoll.com/Images/Silverlight3NavigationNavigatingtoPagesi_19C1/image.png" width="604" height="84" /></a>This navigation functionality is very valuable in and of itself, but what happens if I want to put my pages in a separate assembly, ripe for reuse in other applications?&#160; You’ll notice that the URIs for the Pages were relative to the application project (i.e. “/Views/Home.xaml” represents “&lt;ApplicationProject&gt;/Views/Home.xaml”).&#160; This actually comes from the short form of the <a href="http://msdn.microsoft.com/en-us/library/aa970069.aspx" target="_blank">pack URI syntax in WPF</a> (note: the full syntax is not supported in Silverlight, just a narrow subset).&#160; If you want to access Pages in referenced assemblies, you can do so using the same “short” syntax: “/&lt;ReferencedAssemblyName&gt;;component/&lt;PathToPage&gt;/&lt;PageName&gt;.xaml”</p>
<p>With this syntax, I can place (and reference) pages in a class library that will be referenced by my Silverlight application, allowing me to create a structure like the one in the image below (a simplified example, I know, but it does illustrate the point!).</p>
<p><a href="http://davidpoll.com/Images/Silverlight3NavigationNavigatingtoPagesi_19C1/image_3.png"><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="Solution structure showing /Pages/PageInLibrary.xaml in a class library called PageClassLibrary" border="0" alt="Solution structure showing /Pages/PageInLibrary.xaml in a class library called PageClassLibrary" src="http://davidpoll.com/Images/Silverlight3NavigationNavigatingtoPagesi_19C1/image_thumb.png" width="288" height="362" /></a>For this project structure, my hyperlinks look like this:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Source</span><span style="color: blue">=&quot;/Views/Home.xaml&quot;</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame</span><span style="color: blue">&gt;
</span><span style="color: blue">&lt;</span><span style="color: #a31515">StackPanel </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;LinksStackPanel&quot;</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">HyperlinkButton </span><span style="color: red">NavigateUri</span><span style="color: blue">=&quot;/Views/Home.xaml&quot; </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Content</span><span style="color: blue">=&quot;home&quot;/&gt;</span><span style="color: blue">
    &lt;</span><span style="color: #a31515">HyperlinkButton </span><span style="color: red">NavigateUri</span><span style="color: blue">=&quot;/Views/About.xaml&quot; </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Content</span><span style="color: blue">=&quot;about&quot;/&gt;</span><span style="color: blue">
    &lt;</span><span style="color: #a31515">HyperlinkButton </span><span style="color: red">NavigateUri</span><span style="color: blue">=&quot;/PageClassLibrary;component/Pages/PageInLibrary.xaml&quot; </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Content</span><span style="color: blue">=&quot;page in a class library&quot;/&gt;
&lt;/</span><span style="color: #a31515">StackPanel</span><span style="color: blue">&gt;</span></pre>
<p>Upon running and clicking on the “page in a class library” link, you’ll notice that the address bar shows a rather long and ugly URI:</p>
<p><a href="http://www.davidpoll.com/Samples/MultiAssemblyNavigation/TestPage.html#/PageClassLibrary;component/Pages/PageInLibrary.xaml"><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="http://www.davidpoll.com/Samples/MultiAssemblyNavigation/TestPage.html#/PageClassLibrary;component/Pages/PageInLibrary.xaml" border="0" alt="http://www.davidpoll.com/Samples/MultiAssemblyNavigation/TestPage.html#/PageClassLibrary;component/Pages/PageInLibrary.xaml" src="http://davidpoll.com/Images/Silverlight3NavigationNavigatingtoPagesi_19C1/image_4.png" width="604" height="74" /></a></p>
<p>Thankfully, we’ve supplied a great feature for the Frame control that helps you deal with ungainly URIs – the UriMapper.&#160; UriMappers allow you to write code that takes a URI as input and produces a different URI as output.&#160; The output URI will be used to locate the page, while the input URI is what the user will see.&#160; In the SDK, we’ve supplied a default UriMapper that allows you to use some basic pattern matching to map URIs and keep your deep-links nice and tidy.</p>
<p>In my case, I’d be quite happy if I could get rid of the “/PageClassLibrary;component&quot; that I had to add to my URI to reference Pages in a class library altogether.&#160; Instead, I’d like my URI to look like this: “/Pages/PageInLibrary.xaml”.&#160; To accomplish this, I add a UriMapper to my Frame:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame </span><span style="color: red">Source</span><span style="color: blue">=&quot;/Views/Home.xaml&quot;</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.UriMapper</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapper</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapping </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Pages/{path}&quot; </span><span style="color: red">MappedUri</span><span style="color: blue">=&quot;/PageClassLibrary;component/Pages/{path}&quot; /&gt;
        &lt;/</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapper</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.UriMapper</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame</span><span style="color: blue">&gt;</span><span style="color: blue">
</span><span style="color: blue">&lt;</span><span style="color: #a31515">StackPanel</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">HyperlinkButton</span><span style="color: blue"> </span><span style="color: red">NavigateUri</span><span style="color: blue">=&quot;/Views/Home.xaml&quot; </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Content</span><span style="color: blue">=&quot;home&quot;/&gt;</span><span style="color: blue">
    &lt;</span><span style="color: #a31515">HyperlinkButton</span><span style="color: blue"> </span><span style="color: red">NavigateUri</span><span style="color: blue">=&quot;/Views/About.xaml&quot; </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Content</span><span style="color: blue">=&quot;about&quot;/&gt;</span><span style="color: blue">
    &lt;</span><span style="color: #a31515">HyperlinkButton </span><span style="color: red">NavigateUri</span><span style="color: blue">=&quot;/PageClassLibrary;component/Pages/PageInLibrary.xaml&quot; </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Content</span><span style="color: blue">=&quot;page in a class library&quot;/&gt;</span><span style="color: blue">
    &lt;</span><span style="color: #a31515">HyperlinkButton </span><span style="color: red">NavigateUri</span><span style="color: blue">=&quot;/Pages/PageInLibrary.xaml&quot; </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Content</span><span style="color: blue">=&quot;(mapped URI) page in a class library&quot;/&gt;
&lt;/</span><span style="color: #a31515">StackPanel</span><span style="color: blue">&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Now, users who navigate to the page are greeted with this, much “prettier” URL:</p>
<p><a href="http://www.davidpoll.com/Samples/MultiAssemblyNavigation/TestPage.html#/Pages/PageInLibrary.xaml"><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="http://www.davidpoll.com/Samples/MultiAssemblyNavigation/TestPage.html#/Pages/PageInLibrary.xaml" border="0" alt="http://www.davidpoll.com/Samples/MultiAssemblyNavigation/TestPage.html#/Pages/PageInLibrary.xaml" src="http://davidpoll.com/Images/Silverlight3NavigationNavigatingtoPagesi_19C1/image_5.png" width="604" height="86" /></a></p>
<p>And there you have it!&#160; Dividing your pages across multiple assemblies doesn’t have to degrade user experience, and once you’re familiar with the style of URI that the navigation framework expects for such pages, it’s no more complex than standard navigation within your Silverlight application.</p>
<p><strong><em>One last thought…</em></strong></p>
<p>Before I leave you, I think it’s important to point something out: the Silverlight 3 SDK ships with a project template for Navigation for Visual Studio.&#160; This template makes it really easy to get started with a styleable, Navigation-enabled Silverlight application, and does quite a lot for you, including specifying some default UriMappings:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">ContentFrameStyle</span><span style="color: blue">}&quot;
                  </span><span style="color: red">Source</span><span style="color: blue">=&quot;/Home&quot; </span><span style="color: red">Navigated</span><span style="color: blue">=&quot;ContentFrame_Navigated&quot; </span><span style="color: red">NavigationFailed</span><span style="color: blue">=&quot;ContentFrame_NavigationFailed&quot;&gt;
    &lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.UriMapper</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapper</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapping </span><span style="color: red">Uri</span><span style="color: blue">=&quot;&quot; </span><span style="color: red">MappedUri</span><span style="color: blue">=&quot;/Views/Home.xaml&quot;/&gt;
        &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapping </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/{pageName}&quot; </span><span style="color: red">MappedUri</span><span style="color: blue">=&quot;/Views/{pageName}.xaml&quot;/&gt;
      &lt;/</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapper</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.UriMapper</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame</span><span style="color: blue">&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>This is great – it makes the common case of having Pages within your “Views” folder in your application project really clean, allowing developers to reference “/Home” instead of “/Views/Home.xaml”.&#160; However, if you look closely at the UriMappings, you’ll notice that “/{pageName}” will match our “/&lt;AssemblyName&gt;;component” syntax, mapping it to something else entirely, and preventing any attempts to link directly to such URIs.</p>
<p>There are a number of ways to address this issue, depending on your desired URI scheme, such as:</p>
<ul>
<li>Delete the UriMappings entirely and go back to the full paths for all of the hyperlinks </li>
<li>Modify the existing UriMappings so that the “catch-all” doesn’t match the desired syntax </li>
<li>Add UriMappings for each referenced library <strong><em>before</em></strong> the catch-all mapping, like so: </li>
</ul>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">ContentFrameStyle</span><span style="color: blue">}&quot;
                  </span><span style="color: red">Source</span><span style="color: blue">=&quot;/Home&quot; </span><span style="color: red">Navigated</span><span style="color: blue">=&quot;ContentFrame_Navigated&quot; </span><span style="color: red">NavigationFailed</span><span style="color: blue">=&quot;ContentFrame_NavigationFailed&quot;&gt;
    &lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.UriMapper</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapper</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapping </span><span style="color: red">Uri</span><span style="color: blue">=&quot;&quot; </span><span style="color: red">MappedUri</span><span style="color: blue">=&quot;/Views/Home.xaml&quot;/&gt;
<strong><em>        &lt;</em></strong></span><strong><em><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapping </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Pages/{path}&quot; </span><span style="color: red">MappedUri</span></em></strong><span style="color: blue"><strong><em>=&quot;/PageClassLibrary;component/Pages/{path}&quot; /&gt;</em></strong>
        &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapping </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/{pageName}&quot; </span><span style="color: red">MappedUri</span><span style="color: blue">=&quot;/Views/{pageName}.xaml&quot;/&gt;
      &lt;/</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapper</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.UriMapper</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame</span><span style="color: blue">&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<ul>
<li>Add a UriMapping to restore the original syntax <strong><em>before</em></strong> the catch-all mapping, like so: </li>
</ul>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;ContentFrame&quot; </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">ContentFrameStyle</span><span style="color: blue">}&quot;
                  </span><span style="color: red">Source</span><span style="color: blue">=&quot;/Home&quot; </span><span style="color: red">Navigated</span><span style="color: blue">=&quot;ContentFrame_Navigated&quot; </span><span style="color: red">NavigationFailed</span><span style="color: blue">=&quot;ContentFrame_NavigationFailed&quot;&gt;
    &lt;</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.UriMapper</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapper</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapping </span><span style="color: red">Uri</span><span style="color: blue">=&quot;&quot; </span><span style="color: red">MappedUri</span><span style="color: blue">=&quot;/Views/Home.xaml&quot;/&gt;
<strong><em>        &lt;</em></strong></span><strong><em><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapping </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/{assemblyName};component/{path}&quot; </span><span style="color: red">MappedUri</span></em></strong><span style="color: blue"><strong><em>=&quot;/{assemblyName};component/{path}&quot; /&gt;</em></strong>
        &lt;</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapping </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/{pageName}&quot; </span><span style="color: red">MappedUri</span><span style="color: blue">=&quot;/Views/{pageName}.xaml&quot;/&gt;
      &lt;/</span><span style="color: #a31515">uriMapper</span><span style="color: blue">:</span><span style="color: #a31515">UriMapper</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame.UriMapper</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">navigation</span><span style="color: blue">:</span><span style="color: #a31515">Frame</span><span style="color: blue">&gt;</span></pre>
<p>This list is certainly not exhaustive, but some combination of these options is likely to help you re-enable navigation to Pages in referenced assemblies.</p>
<p>If you’re still having trouble getting this to work, let me know, and I’ll try to help you troubleshoot!</p>
<p><strong><em>Last, but not least…</em></strong></p>
<p>You thought I might leave you without source and a link to the sample, didn’t you?!&#160; Well, guess I showed you!&#160; Oh, wait, I haven’t linked them yet.&#160; Uhhh… pretend I didn’t say that <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<ul>
<li><a href="http://www.davidpoll.com/Samples/MultiAssemblyNavigation/TestPage.html" target="_blank">Sample</a> </li>
<li><a href="http://www.davidpoll.com/Download/MultiAssemblyNavigation.zip">Source code</a> </li>
</ul>
<p>More posts will come now that Silverlight 3 is out!&#160; I’ve been waiting with bated breath!&#160; Thankfully, you folks aren’t around to suggest I use a mint <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong><em>P.S.</em></strong>&#160; Now that Silverlight 3 <em>is</em> out, I’ve updated all of my samples/source to work with <a href="http://silverlight.net/GetStarted/">Silverlight 3</a>, the <a href="http://silverlight.codeplex.com/">July 2009 Silverlight Toolkit</a>, and <a href="http://silverlight.net/forums/t/108916.aspx">.NET RIA Services July 2009 CTP</a>.&#160; You’ll find my Konami Code control and Activity control should both work out-of-the-box with Silverlight 3 RTM, and the rest only needed minor updates.&#160; If folks are curious about my experiences updating those projects, let me know and I’ll do a short post.</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2009/07/12/silverlight-3-navigation-navigating-to-pages-in-referenced-assemblies/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Update: Displaying background activity in a Silverlight RIA application</title>
		<link>http://www.davidpoll.com/2009/06/11/update-displaying-background-activity-in-a-silverlight-ria-application/</link>
		<comments>http://www.davidpoll.com/2009/06/11/update-displaying-background-activity-in-a-silverlight-ria-application/#comments</comments>
		<pubDate>Thu, 11 Jun 2009 19:59:10 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[.NET RIA Services]]></category>
		<category><![CDATA[Activity Control]]></category>
		<category><![CDATA[BusyIndicator]]></category>
		<category><![CDATA[Navigation]]></category>
		<category><![CDATA[Silverlight 3 Beta]]></category>
		<category><![CDATA[WCF RIA Services]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/?p=73</guid>
		<description><![CDATA[Well, it’s been a while since I first posted on this, but the feedback was incredible, and I got some great suggestions.&#160; As a result, I’ve updated the Activity control and (finally) have a running sample on the web!&#160; The fundamental idea of the control has remained the same, as well as the mechanisms by [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Well, it’s been a while since I <a href="http://www.davidpoll.com/?p=4" target="_blank">first posted</a> on this, but the feedback was incredible, and I got some great suggestions.&#160; As a result, I’ve updated the Activity control and (finally) have a running sample on the web!&#160; The fundamental idea of the control has remained the same, as well as the mechanisms by which it can work.&#160; It’s still a prototype, but a very useful one at that!</p>
<p>To see the Activity control in action, take a look here: <a href="http://www.davidpoll.com/Samples/ActivityControlDemo/ActivitySampleTestPage.aspx" target="_blank">Activity Control Demo</a></p>
<p>The demo requires the Silverlight 3 beta to be installed on your machine, which can be found here: <a title="http://silverlight.net/getstarted/silverlight3/default.aspx" href="http://silverlight.net/getstarted/silverlight3/default.aspx">http://silverlight.net/getstarted/silverlight3/default.aspx</a></p>
<p>The demo application shows two examples of using the Activity control to display async/background activity (click the images for deep-links into the Silverlight application):</p>
<ul>
<li>With <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=76bb3a07-3846-4564-b0c3-27972bcaabce&amp;displaylang=en" target="_blank">.NET RIA Services</a> and the DomainDataSource, the Activity control uses element-to-element binding to indicate to the user that data is being loaded or submitted.&#160; The demo page is running live on my server using the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=06616212-0356-46A0-8DA2-EEBC53A68034&amp;displaylang=en" target="_blank">Northwind sample database</a>.&#160; Those of you who think you can play some dirty tricks by overwriting the data on my server (yes, I provided insert/update/delete functionality) – any attempts to do so will be quickly foiled, since the server will accept the requests, but ignore them! <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  </li>
</ul>
<p><a href="http://www.davidpoll.com/Samples/ActivityControlDemo/ActivitySampleTestPage.aspx#/RiaServicesActivity" target="_blank"><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=".NET RIA Services with the Activity Control" border="0" alt=".NET RIA Services with the Activity Control" src="http://www.davidpoll.com/wp-content/uploads/2009/06/image.png" width="604" height="329" /></a></p>
<ul>
<li>Any background activity might warrant using the activity control.&#160; The second example I’ve provided uses the activity control while I use a simple statistical method of approximating PI (yes, very geeky).&#160; It takes millions of iterations to get a mediocre approximation of PI (I know, I’m not using an efficient method, but it does do a lot of work!).&#160; Here, I’ve augmented the Activity control to allow the work to be stopped/cancelled: </li>
</ul>
<p><a href="http://www.davidpoll.com/Samples/ActivityControlDemo/ActivitySampleTestPage.aspx#/HeavyAsyncWork" target="_blank"><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="Calculating PI with background activity" border="0" alt="Calculating PI with background activity" src="http://www.davidpoll.com/wp-content/uploads/2009/06/image1.png" width="604" height="329" /></a></p>
<p>&#160;</p>
<p>So by now I’m sure you’re asking: “What’s changed?”&#160; Well, let me tell you!</p>
<ul>
<li>Thanks to feedback from a variety of folks, I’ve removed the all-encompassing template that included the pop-up window.&#160; That’s now baked into the control template.&#160; If you’d like to change it, you can use the <a href="http://www.microsoft.com/expression/try-it/blendpreview.aspx">Blend 3 Preview</a> to re-template the control.&#160; In its place, I’ve added:
<ul>
<li>A style for the progress bar.&#160; If you’d like to hide it, use a style to collapse the progress bar. </li>
<li>A means for setting “ActiveContent”.&#160; The Activity control works sort of like a HeaderedContentControl.&#160; You now have ActiveContent and ActiveContentTemplate, which allow you to define in XAML what should appear above the progress bar.&#160; You can put any content you like here, and it’s how I added the cancel button in my PI calculation example.&#160; This is also great because it allows you to easily change the text from “Loading…” to whatever you prefer simply be setting the ActiveContent property to the string of your choice! </li>
</ul>
</li>
<li>The default template for the ActivityControl now sets IsHitTestVisible and IsEnabled to false on its content immediately when IsActive becomes true.&#160; In my old prototype, this only happened when the Activity UI became visible, which meant users could continue to interact with the content while it was busy – a potentially dangerous combination if the user’s interactions can be overriden by the asynchronous work (such as editing values in a DataGrid when the data is being reloaded).&#160; This was from a suggestion by Luke Tigaris in the comments on my last post.&#160; Let me know what you think! </li>
<li>You can now call ResetActivity() on the control to force it to honor the visibility of the control immediately rather than enforcing the display delay and minimum display time.&#160; This way, if a user cancels the background work, you can force the Activity UI to be hidden immediately. </li>
</ul>
<p>&#160;</p>
<p>Anyhoo, let me know what you think of the changes!&#160; I’ve gotten lots of great feedback on the control so far, and I’m sure folks will come up with more as time goes on.</p>
<ul>
<li>You can download the source for the control here: <a href="http://www.davidpoll.com/Download/ActivityControl6-11.zip">Activity Control Source</a> </li>
<li>You can also download the source for the demo here: <a href="http://www.davidpoll.com/Download/ActivityControlDemo.zip">Activity Control Demo</a> </li>
</ul>
<p>For both of these, you’ll need the <a href="http://silverlight.net/getstarted/silverlight3/default.aspx">Silverlight 3 Beta</a>.&#160; The Demo application is built using <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=76bb3a07-3846-4564-b0c3-27972bcaabce&amp;displaylang=en" target="_blank">.NET RIA Services</a>.</p>
<p>P.S.&#160; Big thanks again to <a href="http://blogs.msdn.com/corrinab/">Corrina</a> for providing the <a href="http://blogs.msdn.com/brada/archive/2009/03/31/silverlight-3-navigation-application-template-extra-themes-posted.aspx">beautiful theme</a> I used in my application.</p>
<p>P.P.S.&#160; Isn’t navigation and deep-linking in the Silverlight 3 Beta cool?&#160; That’s how I made those images link directly to the corresponding pages of my demo application.&#160; I may post more on this in the future.&#160; In the meantime, take a look at the code to see just how little it took to accomplish that! (hint: MainPage.xaml in the Silverlight Navigation Application project template that’s included with the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=11dc7151-dbd6-4e39-878f-5081863cbb5d&amp;displaylang=en">Silverlight 3 Beta Tools for Visual Studio</a> has pretty much everything that’s required)</p>
<p><strong><em>Update 9/14/2009 – </em></strong>I’ve made a small update to the Activity control to fix a performance issue.&#160; You can find it <a href="http://www.davidpoll.com/2009/09/14/update-2-displaying-background-activity-in-a-silverlight-ria-application/">here</a>.</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2009/06/11/update-displaying-background-activity-in-a-silverlight-ria-application/feed/</wfw:commentRss>
		<slash:comments>40</slash:comments>
		</item>
		<item>
		<title>Displaying background activity in a Silverlight RIA application</title>
		<link>http://www.davidpoll.com/2009/03/19/displaying-background-activity-in-a-silverlight-ria-application/</link>
		<comments>http://www.davidpoll.com/2009/03/19/displaying-background-activity-in-a-silverlight-ria-application/#comments</comments>
		<pubDate>Thu, 19 Mar 2009 21:32:08 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[.NET RIA Services]]></category>
		<category><![CDATA[Activity Control]]></category>
		<category><![CDATA[BusyIndicator]]></category>
		<category><![CDATA[WCF RIA Services]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Well, I told you there would be exciting news at MIX!&#160; After months of working on Silverlight 3 Beta 1, it’s finally available for you to try!&#160; Also coming live for MIX is the “.NET RIA Services” March 2009 Preview, which will assist in building multi-tiered applications and provides end-to-end support for things like data [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Well, I told you there would be exciting news at MIX!&#160; After months of working on <a href="http://silverlight.net/getstarted/silverlight3/default.aspx">Silverlight 3 Beta 1</a>, it’s finally available for you to try!&#160; Also coming live for MIX is the <a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=76bb3a07-3846-4564-b0c3-27972bcaabce">“.NET RIA Services” March 2009 Preview,</a> which will assist in building multi-tiered applications and provides end-to-end support for things like data validation, authentication, and roles, as well as data access.</p>
<p>With the Silverlight 3 beta, you can build really rich user experiences for the web.&#160; For the beta, we’ve added a number of controls and features to enable rich experiences when working with data (e.g. an DataForm, DataPager, ErrorSummary, an updated DataGrid, etc.), and the .NET RIA Services preview makes it much easier to bring the data on your servers down to your Silverlight client.</p>
<p>All of this presents a fairly common problem: what should you do with your UI while data is being loaded or work is being done in the background?&#160; If the amount of work done or data to load is small and completes quickly, it would probably make sense to leave the experience uninterrupted for the user.&#160; For larger amounts of work, however, leaving the user with an unresponsive UI or worse with a responsive UI that doesn’t work properly because data is in the midst of being reloaded is less than ideal.</p>
<p>Imagine, for example, that you’re using a DataGrid whose data takes 3 seconds to load (without taking any explicit steps to show activity).&#160; When your user first loads his application, he sees this:</p>
<img class="size-full wp-image-26  " title="Startup loading without any indicators" alt="image_21" src="http://www.davidpoll.com/wp-content/uploads/2009/03/image_21.png" width="576" height="401" />
<p>Not a terribly appealing user experience.&#160; Is the data loading?&#160; What is the user allowed to do with the app right now?&#160; One could show a progress bar somewhere on the screen, but how do you tell the user not to touch the DataGrid until the data is fully loaded?</p>
<p>In the above application, the data is paginated in order to keep the load sizes small and thus speed up the browsing experience.&#160; As a result, moving from page to page may cause load operations to happen as well.&#160; At this point, it is clear that something is strange with the user experience during a page change.&#160; The user would see something like this:</p>
<img class="size-full wp-image-27  " title="Pages changing without activity UI" alt="image_41" src="http://www.davidpoll.com/wp-content/uploads/2009/03/image_41.png" width="576" height="401" />
<p>Even though the data in the DataGrid is the previous page’s data, everything is still interactive.&#160; I can navigate from item to item and attempt to make changes, but in a few seconds everything will be wiped out when the data finishes loading.</p>
<p>There are a number of options for dealing with this:</p>
<ul>
<li>Progress bar </li>
<li>Enable/disable controls </li>
<li>Show/hide controls </li>
<li>Combinations of these </li>
</ul>
<p>I’ve been playing around with a slightly different idea: an “Activity” control.&#160; This is a control that displays activity (when appropriate) over its content.&#160; During active periods, it adds an overlay to its wrapped controls, graying them out, disabling them, and displaying a progress indicator, like so:</p>
<img class="size-full wp-image-28   " title="Using the Activity control" alt="image_61" src="http://www.davidpoll.com/wp-content/uploads/2009/03/image_61.png" width="576" height="397" />
<p>This way, the user knows which controls he can interact with, and he is also given some additional information (“Loading…” in this case) about why the application is busy.</p>
<p>The control I’m experimenting with itself is pretty straightforward.&#160; Some of its more important features:</p>
<ul>
<li>IsActive property – this can be bound to a boolean value that represents activity.&#160; With .NET RIA Services’ DomainDataSource, this is the “IsBusy” property. </li>
<li>DisplayAfter property – this allows you to set a minimum amount of “active” time before the activity UI appears.&#160; This way, tiny bouts of activity don’t interrupt your user’s workflow. </li>
<li>MinDisplayTime property – this allows you to set a minimum amount of time to display the activity UI.&#160; This way, users have enough time to digest why their screen changed, and the activity UI won’t just flash on and off the screen. </li>
<li>AutoBind/ActivityPropertyName – if AutoBind is set to true (which is the default), the control will search its content for controls that have a property with the name specified (“IsBusy” by default), and will automatically hook itself up to display activity whenever any of its children are busy.&#160; If no such children are found, the control will just use its IsActive property. </li>
<li>ActiveContentTemplate property – allows you to set what is actually displayed (and defaults to what you see above!) </li>
</ul>
<p>With this combination of features, the control makes it easy to add activity UI to your application.&#160; In particular, it works pretty well with the DomainDataSource for .NET RIA Services, since it’s really easy to use ElementName binding to bind IsActive to the IsBusy property on the DDS.&#160; Furthermore, if the DDS is actually inside of the activity control, it will automatically pick up the DDS’s activity:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">activity</span><span style="color: blue">:</span><span style="color: #a31515">Activity</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">Grid</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">Grid.ColumnDefinitions</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">ColumnDefinition </span><span style="color: red">Width</span><span style="color: blue">=&quot;2*&quot; /&gt;
            &lt;</span><span style="color: #a31515">ColumnDefinition </span><span style="color: red">Width</span><span style="color: blue">=&quot;*&quot; /&gt;
        &lt;/</span><span style="color: #a31515">Grid.ColumnDefinitions</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">riaControls</span><span style="color: blue">:</span><span style="color: #a31515">DomainDataSource </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;northwindData&quot;
                              </span><span style="color: red">LoadMethodName</span><span style="color: blue">=&quot;LoadProducts&quot;
                              </span><span style="color: red">LoadSize</span><span style="color: blue">=&quot;20&quot;
                              </span><span style="color: red">AutoLoad</span><span style="color: blue">=&quot;True&quot;&gt;
            &lt;</span><span style="color: #a31515">riaControls</span><span style="color: blue">:</span><span style="color: #a31515">DomainDataSource.DomainContext</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">northwind</span><span style="color: blue">:</span><span style="color: #a31515">NorthwindDomainContext </span><span style="color: blue">/&gt;
            &lt;/</span><span style="color: #a31515">riaControls</span><span style="color: blue">:</span><span style="color: #a31515">DomainDataSource.DomainContext</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">riaControls</span><span style="color: blue">:</span><span style="color: #a31515">DomainDataSource</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">data</span><span style="color: blue">:</span><span style="color: #a31515">DataGrid </span><span style="color: red">ItemsSource</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Data</span><span style="color: blue">, </span><span style="color: red">ElementName</span><span style="color: blue">=northwindData}&quot;
                       </span><span style="color: red">CanUserSortColumns</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">HasChanges</span><span style="color: blue">, </span><span style="color: red">ElementName</span><span style="color: blue">=northwindData, </span><span style="color: red">Converter</span><span style="color: blue">={</span><span style="color: #a31515">StaticResource </span><span style="color: red">boolConverter</span><span style="color: blue">}}&quot;&gt;
        &lt;/</span><span style="color: #a31515">data</span><span style="color: blue">:</span><span style="color: #a31515">DataGrid</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">dataControls</span><span style="color: blue">:</span><span style="color: #a31515">DataForm </span><span style="color: red">Grid.Column</span><span style="color: blue">=&quot;1&quot;
                               </span><span style="color: red">ItemsSource</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Data</span><span style="color: blue">, </span><span style="color: red">ElementName</span><span style="color: blue">=northwindData}&quot;&gt;
        &lt;/</span><span style="color: #a31515">dataControls</span><span style="color: blue">:</span><span style="color: #a31515">DataForm</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">Grid</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">activity</span><span style="color: blue">:</span><span style="color: #a31515">Activity</span><span style="color: blue">&gt;</span></pre>
<p>Otherwise, it’s a simple matter of using ElementName binding to wire up your activity UI:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">activity</span><span style="color: blue">:</span><span style="color: #a31515">Activity </span><span style="color: red">IsActive</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">IsBusy</span><span style="color: blue">, </span><span style="color: red">ElementName</span><span style="color: blue">=northwindData}&quot;&gt;
    &lt;</span><span style="color: #a31515">Grid</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">Grid.ColumnDefinitions</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">ColumnDefinition </span><span style="color: red">Width</span><span style="color: blue">=&quot;2*&quot; /&gt;
            &lt;</span><span style="color: #a31515">ColumnDefinition </span><span style="color: red">Width</span><span style="color: blue">=&quot;*&quot; /&gt;
        &lt;/</span><span style="color: #a31515">Grid.ColumnDefinitions</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">data</span><span style="color: blue">:</span><span style="color: #a31515">DataGrid </span><span style="color: red">ItemsSource</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Data</span><span style="color: blue">, </span><span style="color: red">ElementName</span><span style="color: blue">=northwindData}&quot;
                       </span><span style="color: red">CanUserSortColumns</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">HasChanges</span><span style="color: blue">, </span><span style="color: red">ElementName</span><span style="color: blue">=northwindData, </span><span style="color: red">Converter</span><span style="color: blue">={</span><span style="color: #a31515">StaticResource </span><span style="color: red">boolConverter</span><span style="color: blue">}}&quot;&gt;
        &lt;/</span><span style="color: #a31515">data</span><span style="color: blue">:</span><span style="color: #a31515">DataGrid</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">dataControls</span><span style="color: blue">:</span><span style="color: #a31515">DataForm </span><span style="color: red">Grid.Column</span><span style="color: blue">=&quot;1&quot;
                               </span><span style="color: red">ItemsSource</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Data</span><span style="color: blue">, </span><span style="color: red">ElementName</span><span style="color: blue">=northwindData}&quot;&gt;
        &lt;/</span><span style="color: #a31515">dataControls</span><span style="color: blue">:</span><span style="color: #a31515">DataForm</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">Grid</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">activity</span><span style="color: blue">:</span><span style="color: #a31515">Activity</span><span style="color: blue">&gt;</span></pre>
<p>With this control, it’s easy to have multiple controls all show activity at the same time (either by wrapping them all with the Activity control or by binding activity controls to the same value), and the “busy” experience can be consistent across the app.</p>
<p>This is just a simple prototype control, but I’d love to hear what you think!&#160; Is there something important that’s missing?&#160; Are there other user experience deficiencies you see (either when using SL3 for RIA applications generally or with the .NET RIA Services preview)?</p>
<p>In the meantime, if you’d like to play with my prototype/source, you can find it below.&#160; This code is provided under the <a href="http://www.microsoft.com/opensource/licenses.mspx#Ms-PL">Microsoft Public License</a> and is also provided &quot;as is&quot;, without warranty of any kind.</p>
<ul>
<li><a href="http://www.davidpoll.com/samples/download/ActivityControl.zip">Activity Control</a> (built on SL3 beta 1) </li>
<li><a href="http://www.davidpoll.com/samples/download/ActivitySample.zip">Activity control demo project, shown above</a> (requires SL3 beta 1 and .NET RIA Services) </li>
</ul>
<p>Enjoy!</p>
<p>&#160;</p>
<p><strong><em>Update 6/11/2009 – </em></strong>A new version of the control is available <a href="http://www.davidpoll.com/?p=73" target="_blank">here</a>.</p>
<p><strong><em>Update 7/11/2009 – </em></strong>Samples updated for Silverlight 3!</p>
<p><strong><em>Update 9/14/2009 – </em></strong>I’ve made a small update to the Activity control to fix a performance issue.&#160; You can find it <a href="http://www.davidpoll.com/2009/09/14/update-2-displaying-background-activity-in-a-silverlight-ria-application/">here</a>.</p>
<p>P.S. Thanks to <a href="http://blogs.msdn.com/corrinab/">CorrinaB</a> for helping me snazz up the UI!</p>
<p><img alt="" src="http://blogs.msdn.com/aggbug.aspx?PostID=9491183" width="1" height="1" /></p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2009/03/19/displaying-background-activity-in-a-silverlight-ria-application/feed/</wfw:commentRss>
		<slash:comments>58</slash:comments>
		</item>
	</channel>
</rss>

