<?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; Silverlight</title>
	<atom:link href="http://www.davidpoll.com/category/silverlight/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>Quickly building a trial mode for a Windows Phone application</title>
		<link>http://www.davidpoll.com/2011/01/26/quickly-building-a-trial-mode-for-a-windows-phone-application/</link>
		<comments>http://www.davidpoll.com/2011/01/26/quickly-building-a-trial-mode-for-a-windows-phone-application/#comments</comments>
		<pubDate>Thu, 27 Jan 2011 07:24:14 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone]]></category>
		<category><![CDATA[Applications]]></category>
		<category><![CDATA[Holiday Countdown]]></category>
		<category><![CDATA[Pitch Perfect]]></category>
		<category><![CDATA[Silverlight and Beyond (SLaB)]]></category>
		<category><![CDATA[Tag Master]]></category>
		<category><![CDATA[Windows Phone 7]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2011/01/26/quickly-building-a-trial-mode-for-a-windows-phone-application/</guid>
		<description><![CDATA[Wow – long time no blog!  Over the last few months, I took a bit of a break from blogging, but fear not – I’ve been a busy bee.  Since I last blogged, a lot has changed for me.  In particular, I decided to return to my home state of California.  While I’m still with [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Wow – long time no blog!  Over the last few months, I took a bit of a break from blogging, but fear not – I’ve been a busy bee.  Since I last blogged, a lot has changed for me.  In particular, I decided to return to my home state of California.  While I’m still with Microsoft (in the Bay Area), I’m no longer with the Silverlight team.  I’m not done with Silverlight yet, though!  I’ve continued working on various additions to my <a href="http://www.davidpoll.com/downloads-and-samples/#SLaB" target="_blank">SLaB</a> library, expanding its scope from utilities for Silverlight on the desktop to Silverlight for Windows Phone.  I did most of this work in the course of building a variety of apps for Windows Phone for fun, curiosity, and utility.  If you’re interested, head over to the <a href="http://www.davidpoll.com/applications/" target="_blank">Applications</a> section of my website.  There, you’ll see what I’ve been working on: apps for singers, <a href="http://www.barbershop.org" target="_blank">barbershoppers</a>, and everyone else!</p>
<p>Early on, I started porting various tools from SLaB over to Windows Phone, including many of my utility classes and my XamlSerializer.  I also ported the <a href="http://www.davidpoll.com/tag/busyindicator/" target="_blank">BusyIndicator</a> (formerly the Activity control, now in the desktop toolkit), making use of Jeff Wilcox’s <a href="http://www.jeff.wilcox.name/2010/08/performanceprogressbar/" target="_blank">PerformanceProgressBar</a>.  There are a bunch of other goodies in there too, one of which I’ll discuss in this post.</p>
<h2>Trials and Tribulations</h2>
<p>As I began building my first Windows Phone applications (<a href="http://www.davidpoll.com/applications/pitch-perfect/" target="_blank">Pitch Perfect</a> and <a href="http://www.davidpoll.com/applications/tag-master/" target="_blank">Tag Master</a>), I decided early on that I wanted to include a free trial that would give people a taste of my apps while showing them “just how sweet life could be” if they were to make the purchase.  Doing a little research on the topic quickly led me to the <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.marketplace.licenseinformation.istrial(VS.92).aspx" target="_blank">LicenseInformation.IsTrial()</a> API.  <a href="http://msdn.microsoft.com/en-us/library/ff967558(v=VS.92).aspx#Best_Practices" target="_blank">Best practices around this API</a>, however, suggest that it shouldn’t be called too frequently, as “a typical call takes approximately 60 milliseconds or more,” and that the license state should be cached if you plan to call it frequently.  Well, I honestly didn’t know how frequently I would be calling the API, and it didn’t seem like caching a Boolean value would be a costly or difficult task to accomplish, so I went ahead and abstracted it out with a utility class (which you can find in SLaB if you’re interested).</p>
<pre class="code"><span style="color: blue;">public static class </span><span style="color: #2b91af;">PhoneUtilities
</span>{
    <span style="color: blue;">private static bool</span>? _IsTrial;

<span style="color: gray;">    </span><span style="color: blue;">public static bool </span>IsTrial
    {
        <span style="color: blue;">get
        </span>{
            <span style="color: blue;">if </span>(_IsTrial.HasValue)
                <span style="color: blue;">return </span>_IsTrial.Value;
            <span style="color: blue;">var </span>license = <span style="color: blue;">new </span><span style="color: #2b91af;">LicenseInformation</span>();
            _IsTrial = license.IsTrial();
            <span style="color: blue;">return </span>_IsTrial.Value;
        }
    }
}</pre>
<p>The next problem I encountered was around testing any trial-only code in my application.  There’s not a simple, built-in way to do this using the LicenseInformation API, so I went ahead and added a SimulateTrialMode static property that causes the IsTrial property to return true when it’s set.  Using this API to test your trial mode is pretty straightforward.  I found it most convenient to add a build configuration to my projects which I called “Release Trial” (and also a “Debug Trial” that was modeled after the Debug build configuration) that #defined TRIAL.  This way, by adding the following code to my Application constructor, I could toggle between building the trial and full versions of my applications easily:</p>
<pre class="code"><span style="color: blue;">public </span>App()
{
<span style="color: blue;">#if </span>TRIAL
    <span style="color: gray;">PhoneUtilities.SimulateTrialMode = true;
</span><span style="color: blue;">#endif
    </span><span style="color: green;">// ... boiler-plate initialization code</span>
}</pre>
<h2>Look, but don’t touch!</h2>
<p>With these APIs in place, I felt confident that I could work on producing a good user experience around my trial modes.  The question, however, was what it should look like.  Fundamentally, I wanted to show users what they were missing by not purchasing the app, and give them quick access should they wish to make a purchase decision.  Thus, the concept I chose to develop was to obscure (with a semi-opaque overlay) the part of the UI that is not enabled during a trial and provide a link to the marketplace page for the apps in its place.</p>
<p>As I envisioned it, an app that looked like this when purchased:</p>
<p><a href="http://www.davidpoll.com/wp-content/uploads/2011/01/ByKeySignature.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="ByKeySignature" src="http://www.davidpoll.com/wp-content/uploads/2011/01/ByKeySignature_thumb.png" border="0" alt="ByKeySignature" width="292" height="484" /></a><a href="http://www.davidpoll.com/wp-content/uploads/2011/01/PitchPipeMode.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="PitchPipeMode" src="http://www.davidpoll.com/wp-content/uploads/2011/01/PitchPipeMode_thumb.png" border="0" alt="PitchPipeMode" width="292" height="484" /></a></p>
<p>Might look like this in trial mode:</p>
<p><a href="http://www.davidpoll.com/wp-content/uploads/2011/01/ByKeySignatureTrial.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="ByKeySignatureTrial" src="http://www.davidpoll.com/wp-content/uploads/2011/01/ByKeySignatureTrial_thumb.png" border="0" alt="ByKeySignatureTrial" width="292" height="484" /></a><a href="http://www.davidpoll.com/wp-content/uploads/2011/01/PitchPipeModeTrial.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="PitchPipeModeTrial" src="http://www.davidpoll.com/wp-content/uploads/2011/01/PitchPipeModeTrial_thumb.png" border="0" alt="PitchPipeModeTrial" width="292" height="484" /></a></p>
<p>Well, if you read my blog, you know I’m not satisfied if it’s not easy to do this in XAML, so you won’t be surprised to find out that I went about creating a control that I could use precisely for this purpose.  My first instinct was to take the same approach as I originally took with the BusyIndicator control – after all, this is just a control that, based on some condition, displays an overlay and some specialized UI over its content!  Instead of using a property that could be bound to a value, however, this control would simply read IsTrial to determine its behavior.</p>
<p>The result: a TrialBlocker control in which you can wrap your controls for instant trial functionality!</p>
<p>Using the control is just like using the BusyIndicator – it’s a ContentControl, and under normal circumstances (i.e. non-trial mode), it does nothing.  To produce the blocked-out radio button as I did in the images above, your XAML might look like this:</p>
<pre class="code"><span style="color: blue;">&lt;</span><span style="color: #a31515;">slabControls</span><span style="color: blue;">:</span><span style="color: #a31515;">TrialBlocker</span><span style="color: blue;">&gt;
    &lt;</span><span style="color: #a31515;">RadioButton </span><span style="color: red;">GroupName</span><span style="color: blue;">="PitchRange"
                 </span><span style="color: red;">Content</span><span style="color: blue;">="From F to F"
                 </span><span style="color: red;">IsChecked</span><span style="color: blue;">="{</span><span style="color: #a31515;">Binding </span><span style="color: red;">IsFromFToF</span><span style="color: blue;">, </span><span style="color: red;">Mode</span><span style="color: blue;">=TwoWay}" /&gt;
&lt;/</span><span style="color: #a31515;">slabControls</span><span style="color: blue;">:</span><span style="color: #a31515;">TrialBlocker</span><span style="color: blue;">&gt;
</span></pre>
<p>You can also replace the visuals used when the application is in trial mode by setting the TrialContent and TrialContentTemplate properties.  If your TrialContent is text and you use the default TrialContentTemplate, the TrialBlocker will display the text as a hyperlink back to your application’s details in the marketplace.  You can customize the content further (as I did at the bottom of the bottom-right image to produce the “Trial” link that only shows up in Trial mode) by replacing the template or using a UI element as the TrialContent. Within the content or template, a hyperlink with a Uri of “marketplace:///” will automatically link to your app’s marketplace details (using the same INavigate magic I described long ago in <a href="http://www.davidpoll.com/2009/09/20/relative-hyperlinks-with-silverlight-navigation/" target="_blank">this post</a>).</p>
<p>Thus, XAML like this:</p>
<pre class="code"><span style="color: blue;">&lt;</span><span style="color: #a31515;">slabControls</span><span style="color: blue;">:</span><span style="color: #a31515;">TrialBlocker </span><span style="color: red;">HorizontalAlignment</span><span style="color: blue;">="Center"
                            </span><span style="color: red;">TrialContentTemplate</span><span style="color: blue;">="{</span><span style="color: #a31515;">x</span><span style="color: blue;">:</span><span style="color: #a31515;">Null</span><span style="color: blue;">}"&gt;
    &lt;</span><span style="color: #a31515;">slabControls</span><span style="color: blue;">:</span><span style="color: #a31515;">TrialBlocker.TrialContent</span><span style="color: blue;">&gt;
        &lt;</span><span style="color: #a31515;">StackPanel </span><span style="color: red;">Orientation</span><span style="color: blue;">="Horizontal"&gt;
            &lt;</span><span style="color: #a31515;">HyperlinkButton </span><span style="color: red;">Content</span><span style="color: blue;">="Trial"
                                </span><span style="color: red;">Margin</span><span style="color: blue;">="-12,0"
                                </span><span style="color: red;">FontSize</span><span style="color: blue;">="{</span><span style="color: #a31515;">StaticResource </span><span style="color: red;">PhoneFontSizeSmall</span><span style="color: blue;">}"
                                </span><span style="color: red;">NavigateUri</span><span style="color: blue;">="marketplace:///" /&gt;
            &lt;</span><span style="color: #a31515;">TextBlock </span><span style="color: red;">Text</span><span style="color: blue;">=" " /&gt;
        &lt;/</span><span style="color: #a31515;">StackPanel</span><span style="color: blue;">&gt;
    &lt;/</span><span style="color: #a31515;">slabControls</span><span style="color: blue;">:</span><span style="color: #a31515;">TrialBlocker.TrialContent</span><span style="color: blue;">&gt;
&lt;/</span><span style="color: #a31515;">slabControls</span><span style="color: blue;">:</span><span style="color: #a31515;">TrialBlocker</span><span style="color: blue;">&gt;
</span></pre>
<p>Can be used to produce a “Trial” link like this:</p>
<p><a href="http://www.davidpoll.com/wp-content/uploads/2011/01/PitchPipeModeTrial1.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px; border: 0px;" title="PitchPipeModeTrial" src="http://www.davidpoll.com/wp-content/uploads/2011/01/PitchPipeModeTrial_thumb1.png" border="0" alt="PitchPipeModeTrial" width="244" height="78" /></a></p>
<p>And that’s it!  It’s a straightforward mechanism, but it does the job of producing the UI I had imagined without too much difficulty.  If you think it would be useful to you, by all means, feel free to use it in your applications, too!</p>
<h2>How about the bits?</h2>
<p>True to form, I would never leave you without some code – you can grab it on my <a href="http://www.davidpoll.com/downloads-and-samples/#SLaB" target="_blank">Downloads and Samples</a> page.  I recently uploaded SLaB v0.11 (yes, that’s zero-point-eleven – got a problem with that? <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />   My releases go to eleven!), which is full of a bunch of goodies for mobile that I’ll try to blog about soon.  As always, I make no promises about quality or support for the libraries – they’re just there as an example/tool for you to use if you’re so inclined!  In the meantime, here’s a summary of what’s new since I last blogged:</p>
<ul>
<li><a href="http://www.davidpoll.com/Download/SLaB/SLaBv0.11.zip" target="_blank">SLaB v0.11</a> (includes source and binaries I’ve accumulated by blogging)
<ul>
<li>For the latest version, please check out SLaB on my <a href="http://www.davidpoll.com/downloads-and-samples/#SLaB" target="_blank">Downloads and Samples</a> page</li>
<li>The v0.10 version of SLaB contained the following changes:
<ul>
<li>Ported various components (e.g. XamlSerializer, etc.) to work on Windows Phone 7</li>
<li>Added BusyIndicator for Windows Phone 7</li>
<li>Added ContinuousButton for Windows Phone 7, allowing a bound value to be true while the button is being held down by the user</li>
<li>Added the DelayCreateContentControl for Windows Phone 7, which delays creation of its content until it has been loaded</li>
<li>Added the DelayLoadItemsControl for Windows Phone 7, which fires an event when scrolling nears the end of the vertical space so that more content can be loaded</li>
<li>Added the DetailsLayout for Windows Phone 7, which makes creating a 2-column table of headers and content easier</li>
<li>Added the MarketplaceNavigator for Windows Phone 7, which makes it easy to create HyperlinkButtons that point to marketplace content</li>
<li>Added the TrialBlocker control and PhoneUtilities static methods for Windows Phone 7, which make blocking functionality for trial applications easy and testable</li>
<li>Improved progress indication for network downloads</li>
<li>Other minor bugfixes</li>
</ul>
</li>
<li>The v0.11 version of SLaB contained the following changes:
<ul>
<li>Added the Tombstoner utilty class and a variety of helpers for Windows Phone 7, which make tombstoning of UI state simple and XAML-friendly</li>
<li>Added the SequenceGrid panel for Windows Phone 7, which lays out its children in a grid (with a fixed number of columns) in the order they are added</li>
<li>Other minor bugfixes</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>A quick note about barbershop (pun intended <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )</h2>
<p>In case you were wondering what my “<a href="http://www.davidpoll.com/applications/tag-master/" target="_blank">Tag Master</a>” app is all about, I’ll share with you a tidbit from my personal life.  I’m a barbershopper – it’s a <a href="http://en.wikipedia.org/wiki/Barbershop_music" target="_blank">style of a cappella singing</a> I grew up hearing my father perform, and fell in love with after attending my first rehearsal with a <a href="http://www.nwsound.org/" target="_blank">chorus in the Seattle area</a> when I first joined Microsoft full-time.  If you’ve never heard of it, do a quick search (web and Youtube) for “Barbershop quartet” or “Barbershop chorus” – I think you’ll be pleasantly surprised!  It’s an amazing hobby.  If you’re curious, do yourself a favor and <a href="http://www.barbershop.org/sing/find-a-chorus.html" target="_blank">find a local chapter</a>!</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2011/01/26/quickly-building-a-trial-mode-for-a-windows-phone-application/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>To XAML, with love (an experiment with XAML Serialization in Silverlight)</title>
		<link>http://www.davidpoll.com/2010/07/25/to-xaml-with-love-an-experiment-with-xaml-serialization-in-silverlight/</link>
		<comments>http://www.davidpoll.com/2010/07/25/to-xaml-with-love-an-experiment-with-xaml-serialization-in-silverlight/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 11:05:27 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Silverlight 4]]></category>
		<category><![CDATA[Silverlight and Beyond (SLaB)]]></category>
		<category><![CDATA[XAML]]></category>
		<category><![CDATA[XamlSerializer]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2010/07/25/to-xaml-with-love-an-experiment-with-xaml-serialization-in-silverlight/</guid>
		<description><![CDATA[I’m a big fan of XAML.  It provides a nice, declarative, toolable way of defining UI, encourages separation of UI logic and application logic, and is flexible enough to allow an impressive amount of expressiveness.  In addition to being a way to describe a user interface, XAML can be used as a serialization format for [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>I’m a big fan of XAML.  It provides a nice, declarative, toolable way of defining UI, encourages separation of UI logic and application logic, and is flexible enough to allow an impressive amount of expressiveness.  In addition to being a way to describe a user interface, XAML can be used as a serialization format for arbitrary CLR objects.  A little over a month ago, as I was building out a prototype of an idea I had for a blog post for another time, I found myself looking for a way to quickly and easily serialize some data out into Isolated Storage.  I looked at a few options, such as the XML and JSON serializers in the Silverlight SDK.  Both of these work well for serialization of data, but as I was looking at them, I noticed something that failed to meet my requirements for the task at hand: these libraries are both quite large and would need to be packaged into my XAPs.  System.Xml.Serialization.dll is 314 kb, and System.Runtime.Serialization.Json.dll is 138 kb (uncompressed).  Under many circumstances in large applications, taking such dependencies might be fine, but I was looking for something small that would be acceptable to package into a quick-to-load bootstrapping application.</p>
<p>As a result, I thought I’d spend some time looking for another option.  It occurred to me that in WPF, I might’ve used the XamlWriter for precisely this purpose: to serialize my objects out into text.  As I thought about my options for serialization, taking assembly size into account, I found myself wondering if XAML was a good choice.  After all, Silverlight has a reader (<a href="http://msdn.microsoft.com/en-us/library/ms613427(v=VS.95).aspx" target="_blank">XamlReader</a>) built into the runtime, so I wouldn’t have to build one myself.  Perhaps that would save me the size I was looking for.  Furthermore, in Silverlight 4, the XAML parser got a major overhaul that helped ensure more consistent support of the XAML language, so I felt confident that I could produce a <strong><em>flexible XAML serializer</em></strong>.</p>
<p>With that in mind, I started writing.  At first, I was just hoping to build out some basic serialization into XAML – enough to suit my needs for what I was working on.  But unfortunately, once I start trying to solve a problem, I can’t leave it half-complete!  Just like that, I was hooked on the challenge of seeing how complete of a XAML serializer I could build (which helps explain my blogging absence for the last month <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ).</p>
<p>Honestly, I expected to find a large number of issues – limitations of Silverlight that would keep me from collecting enough information to serialize to XAML properly.  The reality, however, was that I could actually get <strong><em>really</em></strong> close to full fidelity.</p>
<p>In the process, I learned a lot about XAML, Silverlight, and myself (a journey of self-discovery, so to speak <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ).  In this post, I’ll share my results (happily included for your consumption and experimentation in my latest build of <a href="http://www.davidpoll.com/downloads-and-samples/#SLaB" target="_blank">SLaB</a>) as well as some of what I learned.  As usual, I make no promises around support or correctness in all cases.  This is sample code for your edification.  That said, if you do find an issue, please let me know, and I’ll see if I can figure out what’s going on!</p>
<h2>POCO, oh, POCO, wherefore art thou?</h2>
<p>I started out just trying to serialize POCOs (<strong><em><span style="text-decoration: underline;">P</span></em></strong>lain <strong><em><span style="text-decoration: underline;">o</span></em></strong>l’ <strong><em><span style="text-decoration: underline;">C</span></em></strong>LR <strong><em><span style="text-decoration: underline;">O</span></em></strong>bjects).  On the surface, this is pretty straightforward – walk the object graph being serialized, writing objects and property values out using the XmlWriter.  Simple, right?  Well, there’s actually a lot going on here:</p>
<ul>
<li>Walk the object graph using reflection</li>
<li>Decide whether properties are serializable (i.e. is the property read-only?  If so, is it a collection type?)</li>
<li>Retrieve <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.typeconverter(VS.95).aspx" target="_blank">TypeConverters</a> from both properties and property types (based on the <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.typeconverterattribute(v=VS.95).aspx" target="_blank">TypeConverterAttribute</a>)</li>
<li>Determine whether to set properties as attributes (&lt;Foo Bar=”Baz” /&gt;) or elements (&lt;Foo&gt;&lt;Foo.Bar&gt;&lt;Baz /&gt;&lt;/Foo.Bar&gt;&lt;/Foo&gt;)</li>
<li>Retrieve and honor <a href="http://msdn.microsoft.com/en-us/library/system.windows.markup.contentpropertyattribute(VS.95).aspx" target="_blank">ContentPropertyAttributes</a> (So that if “Bar” is the ContentProperty of Foo, the example above is serialized as &lt;Foo&gt;&lt;Baz /&gt;&lt;/Foo&gt;)</li>
<li>Determine whether properties should/should not be serialized based on the <a href="http://blogs.msdn.com/b/mikehillberg/archive/2006/09/16/xamlwriter.aspx" target="_blank">“ShouldSerializeXXXXX” method</a> and the <a href="http://msdn.microsoft.com/en-us/library/2cws2s9d(v=VS.95).aspx" target="_blank">DefaultValueAttribute</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms749011.aspx" target="_blank">Discover attached properties</a> and repeat all of the above</li>
<li>Manage xml namespace definitions (e.g. xmlns:foo=”clr-namespace:MyAssembly.Foo;assembly=MyAssembly”) and scope</li>
<li>Discover/respect <a href="http://msdn.microsoft.com/en-us/library/system.windows.markup.xmlnsdefinitionattribute(VS.95).aspx" target="_blank">XmlnsDefintion</a> and <a href="http://msdn.microsoft.com/en-us/library/system.windows.markup.xmlnsprefixattribute(VS.95).aspx" target="_blank">XmlnsPrefix</a> attributes</li>
<li>Understand serialization of <a href="http://msdn.microsoft.com/en-us/library/dd638655(VS.95).aspx#native_text_syntaxes" target="_blank">built-in types</a> (e.g. Uri, string, double, int, bool, enums etc.)</li>
<li>Serialize null values (using “{x:Null}”)</li>
<li>Serialize collections</li>
<li>Serialize dictionaries (and make use of “x:Key”)</li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms744986.aspx" target="_blank">Properly escape strings</a> (e.g. “{Hello, world!}” needs to get serialized as “{}{Hello World!}”)</li>
<li>Properly handle string whitespace (turning on xml:space=”preserve” at the appropriate times)</li>
<li>Avoid cycles in the object graph (I simply ignore the property if it would cause a cycle – sorry, I’m not a miracle worker!)</li>
<li>Be performant!</li>
</ul>
<p>Nothing to it, right?  Phew, I’m tired just writing all those down!  Who knew there was so much to that XAML stuff? (answer: <a href="http://blogs.windowsclient.net/rob_relyea/archive/tags/Xaml/default.aspx" target="_blank">Rob Relyea</a>)</p>
<p>Anyhow, here’s the end result of this labor of love:</p>
<p><a href="http://www.davidpoll.com/Samples/SLaB/#pack://siteoforigin:,,UtilitiesContent.xap/UtilitiesContent;component/XamlSerializerDemo.xaml" target="_blank"><img class="wlDisabledImage" style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="POCO Serialization demo" src="http://www.davidpoll.com/wp-content/uploads/2010/07/image.png" border="0" alt="POCO Serialization demo" width="644" height="431" /></a></p>
<p>Try changing some of the bound values (against a couple of simple test POCOs I wrote).  You’ll notice that the XAML gets printed without an issue.  XamlReader.Load() works just fine on this text, and could be used to clone objects or otherwise save them.</p>
<p>For posterity, here’s a quick sample of the XAML produced in the sample above:</p>
<pre class="code"><span style="color: blue;">&lt;</span><span style="color: #a31515;">util</span><span style="color: blue;">:</span><span style="color: red;">NestedObject xmlns</span><span style="color: blue;">:</span><span style="color: red;">x</span><span style="color: blue;">="http://schemas.microsoft.com/winfx/2006/xaml"
                   </span><span style="color: red;">BoolValue</span><span style="color: blue;">="True"
                   </span><span style="color: red;">DoubleValue</span><span style="color: blue;">="1.23450005054474"
                   </span><span style="color: red;">IntValue</span><span style="color: blue;">="12345"
                   </span><span style="color: red;">StringValue</span><span style="color: blue;">="Hello, world!"
                   </span><span style="color: red;">UriValue</span><span style="color: blue;">="http://www.davidpoll.com/"
                   </span><span style="color: red;">util</span><span style="color: blue;">:</span><span style="color: red;">AttachedProps.AttachedObject</span><span style="color: blue;">="Cool, huh?"
                   </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">util</span><span style="color: blue;">="clr-namespace:</span><span style="color: red;">UtilitiesContent</span><span style="color: blue;">;assembly=UtilitiesContent"&gt;
    &lt;</span><span style="color: #a31515;">util</span><span style="color: blue;">:</span><span style="color: red;">NestedObject</span><span style="color: #a31515;">.</span><span style="color: red;">DictValue</span><span style="color: blue;">&gt;
        &lt;</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">String </span><span style="color: red;">x</span><span style="color: blue;">:</span><span style="color: red;">Key</span><span style="color: blue;">="Hello"
                                </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">System_mscorlib</span><span style="color: blue;">="clr-namespace:System;assembly=mscorlib"&gt;</span><span style="color: #a31515;">Bonjour</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">String</span><span style="color: blue;">&gt;
        &lt;</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">String </span><span style="color: red;">x</span><span style="color: blue;">:</span><span style="color: red;">Key</span><span style="color: blue;">="Goodbye"
                                </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">System_mscorlib</span><span style="color: blue;">="clr-namespace:System;assembly=mscorlib"&gt;</span><span style="color: #a31515;">Au Revoir</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">String</span><span style="color: blue;">&gt;
    &lt;/</span><span style="color: #a31515;">util</span><span style="color: blue;">:</span><span style="color: red;">NestedObject</span><span style="color: #a31515;">.</span><span style="color: red;">DictValue</span><span style="color: blue;">&gt;
    &lt;</span><span style="color: #a31515;">util</span><span style="color: blue;">:</span><span style="color: red;">NestedObject</span><span style="color: #a31515;">.</span><span style="color: red;">ListValue</span><span style="color: blue;">&gt;
        &lt;</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32 </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">System_mscorlib</span><span style="color: blue;">="clr-namespace:System;assembly=mscorlib"&gt;</span><span style="color: #a31515;">1</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;
        &lt;</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32 </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">System_mscorlib</span><span style="color: blue;">="clr-namespace:System;assembly=mscorlib"&gt;</span><span style="color: #a31515;">2</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;
        &lt;</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32 </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">System_mscorlib</span><span style="color: blue;">="clr-namespace:System;assembly=mscorlib"&gt;</span><span style="color: #a31515;">3</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;
        &lt;</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32 </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">System_mscorlib</span><span style="color: blue;">="clr-namespace:System;assembly=mscorlib"&gt;</span><span style="color: #a31515;">4</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;
    &lt;/</span><span style="color: #a31515;">util</span><span style="color: blue;">:</span><span style="color: red;">NestedObject</span><span style="color: #a31515;">.</span><span style="color: red;">ListValue</span><span style="color: blue;">&gt;
    &lt;</span><span style="color: #a31515;">util</span><span style="color: blue;">:</span><span style="color: red;">NestedObject</span><span style="color: #a31515;">.</span><span style="color: red;">OtherObject</span><span style="color: blue;">&gt;
        &lt;</span><span style="color: #a31515;">util</span><span style="color: blue;">:</span><span style="color: red;">Person Age</span><span style="color: blue;">="22"
                     </span><span style="color: red;">FirstName</span><span style="color: blue;">="David"
                     </span><span style="color: red;">LastName</span><span style="color: blue;">="Poll" /&gt;
    &lt;/</span><span style="color: #a31515;">util</span><span style="color: blue;">:</span><span style="color: red;">NestedObject</span><span style="color: #a31515;">.</span><span style="color: red;">OtherObject</span><span style="color: blue;">&gt;
&lt;/</span><span style="color: #a31515;">util</span><span style="color: blue;">:</span><span style="color: red;">NestedObject</span><span style="color: blue;">&gt;
</span></pre>
<p>Nifty, right?  I thought so too.</p>
<p>And here’s the code it took to produce that XAML from my objects:</p>
<pre class="code"><span style="color: #2b91af;">XamlSerializer </span>xs = <span style="color: blue;">new </span><span style="color: #2b91af;">XamlSerializer</span>();
xs.DiscoverAttachedProperties(<span style="color: blue;">typeof</span>(<span style="color: #2b91af;">AttachedProps</span>));
<span style="color: blue;">string </span>text = xs.Serialize(<span style="color: blue;">this</span>.nestedObject);</pre>
<p>It’s pretty simple: create a XamlSerializer, discover relevant attached properties (you can do this per-property by handing it MethodInfo for the getter/setter, per-type, or per-assembly.  Note: the more of these you have, the more expensive it will be to serialize each object, since the serializer has to test each object for a value from each attached property that could possibly apply to it), and then serialize!</p>
<p>Turning this back into an object is as simple as:</p>
<pre class="code"><span style="color: #2b91af;">XamlReader</span>.Load(text);</pre>
<p>The grand total for the size of this assembly: 36 kb uncompressed.  Bigger than I had originally hoped, but still small enough (16 KB compressed) to work for the scenario I had in mind, I think.  Regardless, it’s a far cry from the two serialization assemblies – both &gt;100 KB uncompressed (which, incidentally, is not to knock them – they are probably much more rigorous than I am in ensuring correctness, performance, and supporting more than what XAML directly supports).</p>
<h3>Did you hit any Silverlight roadblocks?</h3>
<p>Nope.  For POCO serialization, I didn’t really hit any significant limitations or bugs in Silverlight.  The biggest  potential limiting factor is the lack of internal reflection, but since XAML only supports the public interfaces on objects, this didn’t up being an issue for what I was hoping to do.</p>
<h2>UI must make a pact… we must bring salvation back…</h2>
<p>Well, I couldn’t stop with just being able to serialize POCOs.  My first instinct after getting the XamlSerializer (basically) working was to try it on a Button and see what happens.  This is useful for serializing out user content (e.g. drawn paths, rich text, etc.), so it’s a nice functionality to have around.  I crossed my fingers, fixed some bugs, and gave it a shot… and failed.  Turns out it’s not so simple.  First of all, the UI stack in Silverlight has a number of controls with complex properties that on any other control would use a custom TypeConverter (and their WPF equivalents do indeed have these TypeConverters).  In Silverlight, however, many of these controls are native to the runtime, and are thus missing public managed TypeConverters that the XamlSerializer could look for when serializing.  Second, there are <strong><em>literally a million</em></strong> (ok, ok, not literally, that would be crazy – but it’s still a lot, alright?!) properties on every Silverlight control, and they probably shouldn’t all be serialized out.  I ought to be looking for DependencyProperties and checking to see if they’re set.  Finally, there are some types that just have to be treated specially: bindings, styles, and templates come to mind immediately.  With this in mind, I set about deriving from my XamlSerializer and creating a “UiXamlSerializer” that augments its functionality and handles these UI nuances.  Here’s what it does:</p>
<ul>
<li>Understand the concept of <a href="http://msdn.microsoft.com/en-us/library/cc221408(VS.95).aspx">DependencyProperties</a> (attached and regular), and check to see if their values are set before serializing</li>
<li>Discover the built-in attached properties (e.g. Grid.Row and Grid.Column, which should “just work” with this serializer).</li>
<li>Handle TypeConversion for properties/types that have native TypeConverters
<ul>
<li>A few in particular are a bit sticky: TargetType on <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.controltemplate.targettype(VS.95).aspx">ControlTemplate</a> and <a href="http://msdn.microsoft.com/en-us/library/system.windows.style.targettype(VS.95).aspx">Style</a> both need awareness of xml namespaces, as do Style <a href="http://msdn.microsoft.com/en-us/library/system.windows.setter.property(VS.95).aspx">Setters</a> (for setting attached properties and finding the names of the DependencyProperties they target)</li>
</ul>
</li>
<li>Reconstitute templates: ControlTemplate, DataTemplate, and ItemsPanelTemplate</li>
<li>Opportunistically detect references to items in Resources, and reference them using the “{StaticResource}&#8221; markup extension</li>
<li>Reconstitute bindings (use ReadLocalValue() on a DependencyProperty to get the BindingExpression, then serialize the binding instead of the value) – this is a behavior you can disable if you don’t want it</li>
<li>Recognize content inside of Blocks (i.e. rich text), and avoid rich XML formatting (this is mixed content – elements and direct content – and mustn’t have extra line-breaks or spaces in the XML when serialized)</li>
<li>Avoid a few built-in pitfalls (for example, some controls have properties where one <em>or</em> the other should be serialized, e.g. ListBox.SelectedItem, ListBox.SelectedItems, and ListBox.SelectedIndex)</li>
</ul>
<p>Again, this is a fair amount of work, and it definitely goes a little farther than XamlWriter in WPF did (e.g. trying to serialize Bindings and StaticResources), but I wanted to see how close to full-fidelity I could get here.  Really, the only big item I couldn’t find a way to serialize were TemplateBindings.  Unfortunately, while you can get a TemplateBindingExpression from a property that’s been TemplateBound, I could find no way to get back to the name of the property to which it’s actually bound.  However, “{Binding RelativeSource={RelativeSource TemplatedParent}}” serializes just fine <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>The result of all of this is something that comes pretty close to doing what you want, serializing custom SDK, Toolkit, and custom controls just as happily as it serializes built-in controls.  Take a look at a simple demo:</p>
<p><a href="http://www.davidpoll.com/Samples/SLaB/#pack://siteoforigin:,,UtilitiesContent.xap/UtilitiesContent;component/UiXamlSerializerDemo.xaml" target="_blank"><img class="wlDisabledImage" style="display: inline; border-width: 0px;" title="UI Xaml Serialization Demo" src="http://www.davidpoll.com/wp-content/uploads/2010/07/image1.png" border="0" alt="UI Xaml Serialization Demo" width="644" height="431" /></a></p>
<p>Try selecting different items in the TreeView or ListBox, checking/unchecking the box, etc., and note how the serialized XAML keeps up with the changes you’ve made to the UI through your interactions.</p>
<p>The XAML used to produce the UI on the left-hand side of the screen is as follows:</p>
<pre class="code"><span style="color: blue;">&lt;</span><span style="color: #a31515;">Grid </span><span style="color: red;">x</span><span style="color: blue;">:</span><span style="color: red;">Name</span><span style="color: blue;">="gridToSerialize"
        </span><span style="color: red;">Grid.Column</span><span style="color: blue;">="0"&gt;
    &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeView </span><span style="color: red;">x</span><span style="color: blue;">:</span><span style="color: red;">Name</span><span style="color: blue;">="treeView1"
                    </span><span style="color: red;">Margin</span><span style="color: blue;">="4"&gt;
        &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 0 - Item 0 (TreeView items)"
                            </span><span style="color: red;">IsExpanded</span><span style="color: blue;">="True"&gt;
            &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 1 - Item 0"
                                </span><span style="color: red;">IsExpanded</span><span style="color: blue;">="True"&gt;
                &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 2 - Item 0"&gt;&lt;/</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem</span><span style="color: blue;">&gt;
                &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 2 - Item 1"&gt;&lt;/</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem</span><span style="color: blue;">&gt;
                &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 2 - Item 2"&gt;&lt;/</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem</span><span style="color: blue;">&gt;
            &lt;/</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem</span><span style="color: blue;">&gt;
            &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 1 - Item 1"&gt;&lt;/</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem</span><span style="color: blue;">&gt;
            &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 1 - Item 2"&gt;&lt;/</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem</span><span style="color: blue;">&gt;
        &lt;/</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem</span><span style="color: blue;">&gt;
        &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 0 - Item 1 (Basic Controls)"
                            </span><span style="color: red;">IsExpanded</span><span style="color: blue;">="True"&gt;
            &lt;</span><span style="color: #a31515;">Button </span><span style="color: red;">MinWidth</span><span style="color: blue;">="75"
                    </span><span style="color: red;">MinHeight</span><span style="color: blue;">="23"&gt;</span><span style="color: #a31515;">Click!</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">Button</span><span style="color: blue;">&gt;
            &lt;</span><span style="color: #a31515;">CheckBox </span><span style="color: red;">IsChecked</span><span style="color: blue;">="True"&gt;</span><span style="color: #a31515;">Check this out!</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">CheckBox</span><span style="color: blue;">&gt;
            &lt;</span><span style="color: #a31515;">ComboBox </span><span style="color: red;">SelectedIndex</span><span style="color: blue;">="0"&gt;
                &lt;</span><span style="color: #a31515;">ComboBoxItem</span><span style="color: blue;">&gt;</span><span style="color: #a31515;">Combo box item 0</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">ComboBoxItem</span><span style="color: blue;">&gt;
                &lt;</span><span style="color: #a31515;">ComboBoxItem</span><span style="color: blue;">&gt;</span><span style="color: #a31515;">Combo box item 1</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">ComboBoxItem</span><span style="color: blue;">&gt;
                &lt;</span><span style="color: #a31515;">ComboBoxItem</span><span style="color: blue;">&gt;</span><span style="color: #a31515;">Combo box item 2</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">ComboBoxItem</span><span style="color: blue;">&gt;
                &lt;</span><span style="color: #a31515;">ComboBoxItem</span><span style="color: blue;">&gt;</span><span style="color: #a31515;">Combo box item 3</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">ComboBoxItem</span><span style="color: blue;">&gt;
            &lt;/</span><span style="color: #a31515;">ComboBox</span><span style="color: blue;">&gt;
            &lt;</span><span style="color: #a31515;">ProgressBar </span><span style="color: red;">IsIndeterminate</span><span style="color: blue;">="True"
                            </span><span style="color: red;">MinWidth</span><span style="color: blue;">="100"
                            </span><span style="color: red;">MinHeight</span><span style="color: blue;">="23" /&gt;
            &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">DatePicker </span><span style="color: red;">Height</span><span style="color: blue;">="23"
                            </span><span style="color: red;">HorizontalAlignment</span><span style="color: blue;">="Left"
                            </span><span style="color: red;">x</span><span style="color: blue;">:</span><span style="color: red;">Name</span><span style="color: blue;">="datePicker1"
                            </span><span style="color: red;">SelectedDate</span><span style="color: blue;">="7/23/2010"
                            </span><span style="color: red;">Width</span><span style="color: blue;">="120" /&gt;
        &lt;/</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem</span><span style="color: blue;">&gt;
        &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 0 - Item 2 (Layout, Binding, Templates, &amp;amp; Attached Properties)"
                            </span><span style="color: red;">IsExpanded</span><span style="color: blue;">="True"&gt;
            &lt;</span><span style="color: #a31515;">Grid </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">sys</span><span style="color: blue;">="clr-namespace:System;assembly=mscorlib"&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: blue;">/&gt;
                    &lt;</span><span style="color: #a31515;">RowDefinition </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;">ListBox </span><span style="color: red;">Grid.Row</span><span style="color: blue;">="0"&gt;
                    &lt;</span><span style="color: #a31515;">ListBox.ItemTemplate</span><span style="color: blue;">&gt;
                        &lt;</span><span style="color: #a31515;">DataTemplate</span><span style="color: blue;">&gt;
                            &lt;</span><span style="color: #a31515;">StackPanel </span><span style="color: red;">Orientation</span><span style="color: blue;">="Horizontal"&gt;
                                &lt;</span><span style="color: #a31515;">TextBlock </span><span style="color: red;">Text</span><span style="color: blue;">="{</span><span style="color: #a31515;">Binding </span><span style="color: red;">StringFormat</span><span style="color: blue;">='Value = {0}'}" /&gt;
                                &lt;</span><span style="color: #a31515;">Slider </span><span style="color: red;">MinWidth</span><span style="color: blue;">="100"
                                        </span><span style="color: red;">IsEnabled</span><span style="color: blue;">="False"
                                        </span><span style="color: red;">Value</span><span style="color: blue;">="{</span><span style="color: #a31515;">Binding</span><span style="color: blue;">}"
                                        </span><span style="color: red;">Maximum</span><span style="color: blue;">="50"
                                        </span><span style="color: red;">Minimum</span><span style="color: blue;">="0" /&gt;
                            &lt;/</span><span style="color: #a31515;">StackPanel</span><span style="color: blue;">&gt;
                        &lt;/</span><span style="color: #a31515;">DataTemplate</span><span style="color: blue;">&gt;
                    &lt;/</span><span style="color: #a31515;">ListBox.ItemTemplate</span><span style="color: blue;">&gt;
                    &lt;</span><span style="color: #a31515;">ListBox.ItemsPanel</span><span style="color: blue;">&gt;
                        &lt;</span><span style="color: #a31515;">ItemsPanelTemplate</span><span style="color: blue;">&gt;
                            &lt;</span><span style="color: #a31515;">VirtualizingStackPanel </span><span style="color: blue;">/&gt;
                        &lt;/</span><span style="color: #a31515;">ItemsPanelTemplate</span><span style="color: blue;">&gt;
                    &lt;/</span><span style="color: #a31515;">ListBox.ItemsPanel</span><span style="color: blue;">&gt;
                    &lt;</span><span style="color: #a31515;">sys</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;</span><span style="color: #a31515;">10</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">sys</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;
                    &lt;</span><span style="color: #a31515;">sys</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;</span><span style="color: #a31515;">20</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">sys</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;
                    &lt;</span><span style="color: #a31515;">sys</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;</span><span style="color: #a31515;">30</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">sys</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;
                    &lt;</span><span style="color: #a31515;">sys</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;</span><span style="color: #a31515;">40</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">sys</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;
                    &lt;</span><span style="color: #a31515;">sys</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;</span><span style="color: #a31515;">50</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">sys</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;
                &lt;/</span><span style="color: #a31515;">ListBox</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: red;">Grid.Row</span><span style="color: blue;">="1"
                                        </span><span style="color: red;">IsBusy</span><span style="color: blue;">="True" /&gt;
            &lt;/</span><span style="color: #a31515;">Grid</span><span style="color: blue;">&gt;
        &lt;/</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem</span><span style="color: blue;">&gt;
        &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 0 - Item 3"&gt;&lt;/</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem</span><span style="color: blue;">&gt;
    &lt;/</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeView</span><span style="color: blue;">&gt;
&lt;/</span><span style="color: #a31515;">Grid</span><span style="color: blue;">&gt;
</span></pre>
<p>Serializing this out using the UiXamlSerializer produces the following XAML:</p>
<pre class="code"><span style="color: blue;">&lt;</span><span style="color: #a31515;">Grid </span><span style="color: red;">xmlns</span><span style="color: blue;">="http://schemas.microsoft.com/client/2007"
        </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">x</span><span style="color: blue;">="http://schemas.microsoft.com/winfx/2006/xaml"
        </span><span style="color: red;">x</span><span style="color: blue;">:</span><span style="color: red;">Name</span><span style="color: blue;">="gridToSerialize"
        </span><span style="color: red;">Grid.Column</span><span style="color: blue;">="0"&gt;
    &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeView </span><span style="color: red;">x</span><span style="color: blue;">:</span><span style="color: red;">Name</span><span style="color: blue;">="treeView1"
                    </span><span style="color: red;">Margin</span><span style="color: blue;">="4,4,4,4"
                    </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">sdk</span><span style="color: blue;">="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"&gt;
        &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 0 - Item 0 (TreeView items)"
                            </span><span style="color: red;">IsExpanded</span><span style="color: blue;">="True"&gt;
            &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 1 - Item 0"
                                </span><span style="color: red;">IsExpanded</span><span style="color: blue;">="True"&gt;
                &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 2 - Item 0" /&gt;
                &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 2 - Item 1" /&gt;
                &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 2 - Item 2" /&gt;
            &lt;/</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem</span><span style="color: blue;">&gt;
            &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 1 - Item 1" /&gt;
            &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 1 - Item 2" /&gt;
        &lt;/</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem</span><span style="color: blue;">&gt;
        &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 0 - Item 1 (Basic Controls)"
                            </span><span style="color: red;">IsExpanded</span><span style="color: blue;">="True"&gt;
            &lt;</span><span style="color: #a31515;">Button </span><span style="color: red;">Content</span><span style="color: blue;">="Click!"
                    </span><span style="color: red;">MinHeight</span><span style="color: blue;">="23"
                    </span><span style="color: red;">MinWidth</span><span style="color: blue;">="75" /&gt;
            &lt;</span><span style="color: #a31515;">CheckBox </span><span style="color: red;">Content</span><span style="color: blue;">="Check this out!"&gt;
                &lt;</span><span style="color: #a31515;">CheckBox.IsChecked</span><span style="color: blue;">&gt;
                    &lt;</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Boolean </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">System_mscorlib</span><span style="color: blue;">="clr-namespace:System;assembly=mscorlib"&gt;</span><span style="color: #a31515;">True</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Boolean</span><span style="color: blue;">&gt;
                &lt;/</span><span style="color: #a31515;">CheckBox.IsChecked</span><span style="color: blue;">&gt;
            &lt;/</span><span style="color: #a31515;">CheckBox</span><span style="color: blue;">&gt;
            &lt;</span><span style="color: #a31515;">ComboBox </span><span style="color: red;">IsDropDownOpen</span><span style="color: blue;">="False"
                        </span><span style="color: red;">SelectedIndex</span><span style="color: blue;">="0"&gt;
                &lt;</span><span style="color: #a31515;">ComboBoxItem </span><span style="color: red;">Content</span><span style="color: blue;">="Combo box item 0"
                                </span><span style="color: red;">IsSelected</span><span style="color: blue;">="True" /&gt;
                &lt;</span><span style="color: #a31515;">ComboBoxItem </span><span style="color: red;">Content</span><span style="color: blue;">="Combo box item 1" /&gt;
                &lt;</span><span style="color: #a31515;">ComboBoxItem </span><span style="color: red;">Content</span><span style="color: blue;">="Combo box item 2" /&gt;
                &lt;</span><span style="color: #a31515;">ComboBoxItem </span><span style="color: red;">Content</span><span style="color: blue;">="Combo box item 3" /&gt;
            &lt;/</span><span style="color: #a31515;">ComboBox</span><span style="color: blue;">&gt;
            &lt;</span><span style="color: #a31515;">ProgressBar </span><span style="color: red;">IsIndeterminate</span><span style="color: blue;">="True"
                            </span><span style="color: red;">MinHeight</span><span style="color: blue;">="23"
                            </span><span style="color: red;">MinWidth</span><span style="color: blue;">="100" /&gt;
            &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">DatePicker </span><span style="color: red;">x</span><span style="color: blue;">:</span><span style="color: red;">Name</span><span style="color: blue;">="datePicker1"
                            </span><span style="color: red;">DisplayDate</span><span style="color: blue;">="7/25/2010"
                            </span><span style="color: red;">FirstDayOfWeek</span><span style="color: blue;">="Sunday"
                            </span><span style="color: red;">Height</span><span style="color: blue;">="23"
                            </span><span style="color: red;">HorizontalAlignment</span><span style="color: blue;">="Left"
                            </span><span style="color: red;">SelectedDate</span><span style="color: blue;">="7/23/2010"
                            </span><span style="color: red;">Text</span><span style="color: blue;">="7/23/2010"
                            </span><span style="color: red;">Width</span><span style="color: blue;">="120" /&gt;
        &lt;/</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem</span><span style="color: blue;">&gt;
        &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 0 - Item 2 (Layout, Binding, Templates, &amp;amp; Attached Properties)"
                            </span><span style="color: red;">IsExpanded</span><span style="color: blue;">="True"&gt;
            &lt;</span><span style="color: #a31515;">Grid</span><span style="color: blue;">&gt;
                &lt;</span><span style="color: #a31515;">ListBox </span><span style="color: red;">Grid.Row</span><span style="color: blue;">="0"&gt;
                    &lt;</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32 </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">System_mscorlib</span><span style="color: blue;">="clr-namespace:System;assembly=mscorlib"&gt;</span><span style="color: #a31515;">10</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;
                    &lt;</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32 </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">System_mscorlib</span><span style="color: blue;">="clr-namespace:System;assembly=mscorlib"&gt;</span><span style="color: #a31515;">20</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;
                    &lt;</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32 </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">System_mscorlib</span><span style="color: blue;">="clr-namespace:System;assembly=mscorlib"&gt;</span><span style="color: #a31515;">30</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;
                    &lt;</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32 </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">System_mscorlib</span><span style="color: blue;">="clr-namespace:System;assembly=mscorlib"&gt;</span><span style="color: #a31515;">40</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;
                    &lt;</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32 </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">System_mscorlib</span><span style="color: blue;">="clr-namespace:System;assembly=mscorlib"&gt;</span><span style="color: #a31515;">50</span><span style="color: blue;">&lt;/</span><span style="color: #a31515;">System_mscorlib</span><span style="color: blue;">:</span><span style="color: #a31515;">Int32</span><span style="color: blue;">&gt;
                    &lt;</span><span style="color: #a31515;">ListBox.ItemsPanel</span><span style="color: blue;">&gt;
                        &lt;</span><span style="color: #a31515;">ItemsPanelTemplate</span><span style="color: blue;">&gt;
                            &lt;</span><span style="color: #a31515;">VirtualizingStackPanel </span><span style="color: red;">CanHorizontallyScroll</span><span style="color: blue;">="False"
                                                    </span><span style="color: red;">CanVerticallyScroll</span><span style="color: blue;">="False"
                                                    </span><span style="color: red;">ScrollOwner</span><span style="color: blue;">="{</span><span style="color: #a31515;">x</span><span style="color: blue;">:</span><span style="color: #a31515;">Null</span><span style="color: blue;">}" /&gt;
                        &lt;/</span><span style="color: #a31515;">ItemsPanelTemplate</span><span style="color: blue;">&gt;
                    &lt;/</span><span style="color: #a31515;">ListBox.ItemsPanel</span><span style="color: blue;">&gt;
                    &lt;</span><span style="color: #a31515;">ListBox.ItemTemplate</span><span style="color: blue;">&gt;
                        &lt;</span><span style="color: #a31515;">DataTemplate</span><span style="color: blue;">&gt;
                            &lt;</span><span style="color: #a31515;">StackPanel </span><span style="color: red;">Orientation</span><span style="color: blue;">="Horizontal"&gt;
                                &lt;</span><span style="color: #a31515;">TextBlock </span><span style="color: red;">FontSource</span><span style="color: blue;">="{</span><span style="color: #a31515;">x</span><span style="color: blue;">:</span><span style="color: #a31515;">Null</span><span style="color: blue;">}"&gt;
                                    &lt;</span><span style="color: #a31515;">TextBlock.Text</span><span style="color: blue;">&gt;
                                        &lt;</span><span style="color: #a31515;">Binding </span><span style="color: red;">Path</span><span style="color: blue;">=""
                                                 </span><span style="color: red;">StringFormat</span><span style="color: blue;">="Value = {0}" /&gt;
                                    &lt;/</span><span style="color: #a31515;">TextBlock.Text</span><span style="color: blue;">&gt;
                                &lt;/</span><span style="color: #a31515;">TextBlock</span><span style="color: blue;">&gt;
                                &lt;</span><span style="color: #a31515;">Slider </span><span style="color: red;">IsEnabled</span><span style="color: blue;">="False"
                                        </span><span style="color: red;">Maximum</span><span style="color: blue;">="50"
                                        </span><span style="color: red;">Minimum</span><span style="color: blue;">="0"
                                        </span><span style="color: red;">MinWidth</span><span style="color: blue;">="100"&gt;
                                    &lt;</span><span style="color: #a31515;">Slider.Value</span><span style="color: blue;">&gt;
                                        &lt;</span><span style="color: #a31515;">Binding </span><span style="color: red;">Path</span><span style="color: blue;">="" /&gt;
                                    &lt;/</span><span style="color: #a31515;">Slider.Value</span><span style="color: blue;">&gt;
                                &lt;/</span><span style="color: #a31515;">Slider</span><span style="color: blue;">&gt;
                            &lt;/</span><span style="color: #a31515;">StackPanel</span><span style="color: blue;">&gt;
                        &lt;/</span><span style="color: #a31515;">DataTemplate</span><span style="color: blue;">&gt;
                    &lt;/</span><span style="color: #a31515;">ListBox.ItemTemplate</span><span style="color: blue;">&gt;
                &lt;/</span><span style="color: #a31515;">ListBox</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: red;">IsBusy</span><span style="color: blue;">="True"
                                        </span><span style="color: red;">Grid.Row</span><span style="color: blue;">="1"
                                        </span><span style="color: red;">xmlns</span><span style="color: blue;">:</span><span style="color: red;">toolkit</span><span style="color: blue;">="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit" /&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: blue;">/&gt;
                    &lt;</span><span style="color: #a31515;">RowDefinition </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;">Grid</span><span style="color: blue;">&gt;
        &lt;/</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem</span><span style="color: blue;">&gt;
        &lt;</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeViewItem </span><span style="color: red;">Header</span><span style="color: blue;">="Level 0 - Item 3" /&gt;
    &lt;/</span><span style="color: #a31515;">sdk</span><span style="color: blue;">:</span><span style="color: #a31515;">TreeView</span><span style="color: blue;">&gt;
&lt;/</span><span style="color: #a31515;">Grid</span><span style="color: blue;">&gt;
</span></pre>
<p>There are a few things to notice here:</p>
<ul>
<li>The DataTemplate for ListBox.ItemTemplate was serialized out and includes bindings for each of the items</li>
<li>Bindings are not serialized using the curly brace syntax (e.g. “{Binding Foo}”).  This is because they may (rarely) have properties attached to them, which requires that they be in object-element form</li>
<li>CheckBox.IsChecked got serialized the “long way” (object-element syntax).  Why?  Well, CheckBox.IsChecked isn’t of type bool, it’s a Nullable&lt;bool&gt;.  Because of this, it’s not a built-in type, and I serialize it out just like any other object (since I can’t determine the TypeConverter for it on a property level).  There is a built-in NullableBoolConverter TypeConverter, but it doesn’t support ConvertTo (to turn the bool back into a string) and wasn’t necessary to make this scenario work, so I decided to avoid bloating my code with a special case for this.</li>
<li>Path geometries do serialize using the UiXamlSerializer.  In Silverlight 4, we made the PathGeometry’s ToString() return the <a href="http://msdn.microsoft.com/en-us/library/cc189041(VS.95).aspx">path mini-language</a>, so making this work was actually fairly straightforward.</li>
</ul>
<p>Once again, doing this serialization is quite straightforward.  Here’s the code:</p>
<pre class="code"><span style="color: #2b91af;">UiXamlSerializer </span>uxs = <span style="color: blue;">new </span><span style="color: #2b91af;">UiXamlSerializer</span>();
<span style="color: blue;">string </span>text = uxs.Serialize(<span style="color: blue;">this</span>.gridToSerialize);</pre>
<p>Cool, right?</p>
<p>In order to keep the POCO XAML serialization assembly small, I chose to put this serializer in its own assembly, deriving from XamlSerializer and overriding a large set of virtuals in order to add understanding of these concepts to the serializer.  Getting UI XAML serialization adds a 26 kb assembly (uncompressed) on top of the 36 kb assembly for the base type.</p>
<h3>Lucy in the sky…</h3>
<p>Ok, so having a UiXamlSerializer is pretty cool, but what can it do?  Well, the first scenario that comes to mind for me is the serialization of rich text.  Silverlight 4 added the <a href="http://msdn.microsoft.com/en-us/library/ee681613(VS.95).aspx">RichTextBox</a> as a core control.  This control is great – it allows editing of rich text with a large variety of inline content, formatting, etc.  It also allows you to insert <a href="http://msdn.microsoft.com/en-us/library/ee681613(VS.95).aspx#inline_images_or_other_elements">InlineUIContainers</a> that support arbitrary content.  This is the only way to get images into your rich text.  RichTextBox does have a “<a href="http://msdn.microsoft.com/en-us/library/ee681613(VS.95).aspx#xaml">Xaml</a>” property, but this property is strictly limited to serializing out Paragraphs, Runs, LineBreaks, Spans, Bolds, Hyperlinks, Underlines, and Italics.  As a result, using this to serialize your rich text loses any images your users might have added to their rich text.  In order to save this data, you had to serialize this manually from the RichTextBox.Blocks property.</p>
<p>With the UiXamlSerializer, doing this is much simpler.  I’ve got a quick demo of this that gets a little “trippy”.  It’s a RichTextBox in which you can format text, add images, and even add other RichTextBoxes (visual recursion?  scary thought <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ).  Clicking the button on the page will serialize the content out into XAML using the UiXamlSerializer, read it using XamlReader.Load(), then copy those freshly-cloned elements into the RichTextEditor on the right side of the screen.  Give it a shot!</p>
<p><a href="http://www.davidpoll.com/Samples/SLaB/#pack://siteoforigin:,,UtilitiesContent.xap/UtilitiesContent;component/RichTextSerializationDemo.xaml" target="_blank"><img class="wlDisabledImage" style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="Rich Text Serialization Demo" src="http://www.davidpoll.com/wp-content/uploads/2010/07/image2.png" border="0" alt="Rich Text Serialization Demo" width="644" height="417" /></a></p>
<p>The code to do this is slightly more complex, simply because the RichTextBox.Blocks property can’t be serialized directly (its type has no public constructor).  Instead, I copy the elements to my own collection type that is XAML-friendly (remember, generic types aren’t supported in XAML in Silverlight), then copy them back after deserializing.  Otherwise, it’s pretty straightforward:</p>
<pre class="code"><span style="color: #2b91af;">UiXamlSerializer </span>uxs = <span style="color: blue;">new </span><span style="color: #2b91af;">UiXamlSerializer</span>();
<span style="color: #2b91af;">ObservableObjectCollection </span>ooc = <span style="color: blue;">new </span><span style="color: #2b91af;">ObservableObjectCollection</span>();
<span style="color: blue;">foreach </span>(<span style="color: #2b91af;">Block </span>b <span style="color: blue;">in </span>rteLeft.RichTextBox.Blocks)
    ooc.Add(b);
<span style="color: blue;">string </span>xaml = uxs.Serialize(ooc);
<span style="color: blue;">this</span>.xamlTb.Text = xaml;
<span style="color: #2b91af;">ObservableObjectCollection </span>bc = (<span style="color: #2b91af;">ObservableObjectCollection</span>)<span style="color: #2b91af;">XamlReader</span>.Load(xaml);
rteRight.RichTextBox.Blocks.Clear();
<span style="color: blue;">foreach </span>(<span style="color: #2b91af;">Block </span>b <span style="color: blue;">in </span>bc)
    rteRight.RichTextBox.Blocks.Add(b);</pre>
<p>Et voila!  Simple RichTextBox content serialization!</p>
<h3>Any Silverlight roadblocks this time?</h3>
<p>Actually, there were only a few (fewer than I expected) painful things to overcome in Silverlight to make UI XAML serialization work:</p>
<ul>
<li>Templates… Unfortunately, the only way to get the Template content in Silverlight is to expand the templates out.  As a result, I have to handle each type of template specially.  DataTemplates are easy: LoadContent() and then serialize the content into the DataTemplate element.  ControlTemplates are reasonably simple as well: create an instance of the control, apply the template, and serialize the visual child of the control.  ItemsPanelTemplates are a little more difficult: create an ItemsControl, apply the template, put the ItemsControl in a popup to force its template to expand, search its visual children for the ItemsPresenter, and serialize the ItemsPresenter’s visual child.  Confusing, but doable.  Unfortunately, all of these require actually expanding the template, creating all of objects in its visual tree.  It’s not ideal, but it works.</li>
<li>TypeConverters… I hope I got all of these, but I’m sure there are some that I’ve missed.  I think the primary scenarios all work, though.  Let me know if you encounter an issue and I’ll see if there’s anything I can do to fix it.</li>
<li>ShouldSerialize… In WPF, there are a number of ShouldSerializeProperty methods hidden from intellisense and the object browser.  These tell the XamlWriter whether a particular property should be serialized (e.g. should I serialize SelectedItem, SelectedItems, or SelectedIndex on a ListBox?)  I’ve tried to hit the worst offenders here, but again, I’m sure I’ve missed some.</li>
</ul>
<p>The following issues were insurmountable, but I made a best effort:</p>
<ul>
<li>TemplateBindings… they just can’t be reconstituted once they’ve been created.  There’s no way to get the property that is the Source of the TemplateBinding back after it’s been created.</li>
<li>DependencyProperties… Since you can’t get their names, I have to rely on the reflected field name of the DependencyProperty.  I make the (usually safe) assumption that this field will be public, static, and named &lt;PropertyName&gt;Property in both the regular and attached property cases.  If I don’t find these fields, I treat the property as a CLR property rather than a DependencyProperty.</li>
<li>Bindings…  Everything’s good when trying to rebuild these except that the PropertyPath doesn’t expose enough information to safely rebuild the Binding’s path.  In particular, if the Binding has an attached property within its path, it uses the “(ns:Foo.Bar)” syntax.  Since I don’t know what “ns:” means after the binding was originally parsed, I can’t be 100% sure what the attached property really is.  In this case, the UiXamlSerializer searches its known attached properties for a class named “Foo” with an attached property called “Bar”.  If it finds multiple attached properties that match this, the result is indeterminate.  In other words, please don’t create a class called “Grid” with an attached property called “Row” and bind to that property – you’re asking for trouble.  If you call it “MyGrid”, though, you’re golden <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>Weirdness… I can probably work around these, but now and then you’ll encounter some little quirks or bugs in Silverlight’s XAML parsing.  It’s much less unpredictable in Silverlight 4 than Silverlight 3, but there are still one or two issues.  For example, if you explicitly set a control’s Cursor property to null in code, all is well.  Unfortunately, doing the same explicitly in XAML throws.  Luckily, it’s rare to set this property’s value to null in code, since its default value is null anyway (and if the DependencyProperty remains unset, the serializer won’t write it out, and everybody’s happy).  I haven’t special-cased this for now, but you get the picture <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</li>
</ul>
<h2>Zippity Doo Dah…</h2>
<p>One place where I learned a lot from this experience was in dealing with performance in Silverlight.  It can be a sticky area, and I definitely had my fair share of performance problems when I made my first pass on implementing this.</p>
<p>Honestly, I had never actually profiled a Silverlight application before trying this.  It had rarely been an issue for me with the things I was writing.  But then I wrote the UiXamlSerializer, and when I tried to Serialize about 60 lines of XAML it took about 1.2 seconds.  Simple profiling revealed a poor coding choice I had made that increased the complexity of my serialization by a factor of O(n^2) – oops!  Now, serializing the same content (after warming up the serializer, which now does some aggressive caching) takes about 120 milliseconds – just a little longer than WPF’s XamlWriter takes for the same content: 80 milliseconds (also after warmup).  That said, my “warmup” takes about 1/3 of the time of XamlWriter’s (I suspect I’m doing less – I think XamlWriter actually searches all loaded assemblies for attached properties – I do it explicitly for desired attached properties).  Not too shabby, right?  With more effort, I could probably improve on that some more, but I was pretty happy with the improvement <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>The best resource I found for learning to profile a Silverlight application was <a href="http://blogs.msdn.com/b/mgoldin/" target="_blank">Maxim Goldin’s blog</a>.  He <a href="http://blogs.msdn.com/b/mgoldin/archive/2010/06/01/vs2010-sliverlight-4-profiling-from-visual-studio-ui.aspx" target="_blank">lays it out quite clearly</a>.  Thanks, Maxim!</p>
<p>Here are some of the big things I learned from profiling and implementing performance improvements:</p>
<ul>
<li>Reflection is <strong><em><span style="text-decoration: underline;">expensive</span></em></strong>.  I knew this going in, but I didn’t realize how much of an impact it would have.  I cut my run-times nearly in half just by caching any attributes, PropertyInfos, and MethodInfos I happened to find along the way.  It’s a fairly easy step to take for a big win.  GetCustomAttributes() was the biggest offender for me.  These can’t change at runtime anyway, so they’re safe to cache.  I just kept dictionaries associating them with Types, PropertyInfos, and MethodInfos whenever I could.</li>
<li>LCG (Lightweight Code Generation) is awesome.  I managed to shave off a good 30-40% of my time by turning PropertyInfo.GetValue() and MethodInfo.Invoke() calls into pure IL which I could invoke directly.  Granted, this project is very heavy on reflection, so I probably got more of a benefit here than most apps would, but I was really surprised by just how much of a difference it makes.  It’s important to cache the generated IL here, since the initial generation is actually more costly than reflection, but if you’re repeatedly checking the same property’s value over and over on different objects (e.g. “Background” on any control), this makes a big difference in aggregate.  Furthermore, subsequent serializations (e.g. calling Serialize() 50 times on 50 different objects of the same type) are significantly faster.</li>
<li>LINQ expressions make LCG easy!  Wow &#8212; I was stunned by just how simple it was to do my lightweight code generation.  Here’s an example of the code it took to generate a delegate (Func&lt;object, object&gt; in this case) for an attached property getter (this.Getter is the MethodInfo for the attached property, and this.GetterFunc is the cached generated delegate):</li>
</ul>
<pre class="code"><span style="color: blue;">var </span>param = <span style="color: #2b91af;">Expression</span>.Parameter(<span style="color: blue;">typeof</span>(<span style="color: blue;">object</span>));
<span style="color: blue;">var </span>cast = <span style="color: #2b91af;">Expression</span>.Convert(param, <span style="color: blue;">this</span>.TargetType);
<span style="color: blue;">var </span>call = <span style="color: #2b91af;">Expression</span>.Call(<span style="color: blue;">null</span>, <span style="color: blue;">this</span>.Getter, cast);
<span style="color: blue;">var </span>finalCast = <span style="color: #2b91af;">Expression</span>.Convert(call, <span style="color: blue;">typeof</span>(<span style="color: blue;">object</span>));
<span style="color: blue;">var </span>lambda = <span style="color: #2b91af;">Expression</span>.Lambda&lt;<span style="color: #2b91af;">Func</span>&lt;<span style="color: blue;">object</span>, <span style="color: blue;">object</span>&gt;&gt;(finalCast, param);
<span style="color: blue;">this</span>.GetterFunc = lambda.Compile();</pre>
<ul>
<li>Cache often.  It probably goes without saying, but assuming you’ve already got algorithmic complexity down, look for places to cache things rather than performing new calculations.  Something to watch out for: expensive lookups.  I found that my aggressive caching in Dictionaries led to a new potential performance issue – the Dictionary lookups.  A few times, I needed to go through and optimize the Equals() and GetHashCode() implementations for my dictionary keys.  For Types, this was no problem for me, but PropertyInfos are more complex (they don’t have an Equals() implementation, so I had to write one myself).</li>
<li>Caching has an impact on assembly size.  The IL metadata from additional fields and code for caching added at least 4-5 KB to my assemblies.  It had a significant impact on performance, though.  It’s a trade-off one must consider when making these types of improvements.  In my case, the gains were so great that it was really a no-brainer.  As I was looking at smaller optimizations, however, I began to consider this issue carefully.</li>
<li>Watch out for Exceptions.  First chance exceptions make this serializer run fairly slowly when the debugger is attached, and they&#8217;re happening constantly because some attached properties target any DependencyObject, but throw for all but a few types.  As a result, almost every UIElement being serialized hits a first chance exception.  I spent some time clearing them out of my own code, and it definitely improved performance both with and without the debugger attached.  It&#8217;s an unavoidable issue sometimes (in this case because I&#8217;m running someone else&#8217;s code blindly for property getters), but minimize using exceptions for control flow whenever possible.</li>
<li>Finally, LINQ to Objects is really cool and makes for some very clean code.  Watch out for its performance pitfalls, though.  One example: once you create a query, iterating over the resulting IEnumerable re-runs the query each time.  If you’re doing any more complex calls within those queries (e.g. selecting the value of a property via reflection, performing string comparisons, or determining if the property can be written to XAML), watch out for this.  “let” and ToArray() are your friends in this case.</li>
</ul>
<h2>I heard it through the grapevine…</h2>
<p>Before I conclude this post, I just want to take a moment to acknowledge some folks who tried this long before I ever got my hands on it.  Having a XamlWriter equivalent in Silverlight is a request I’ve seen over and over, and others have tried it before me.  My hope was to overcome some of their drawbacks and really have something general-purpose.  I think, for the most part, I’ve accomplished that.  Regardless, check out these – they may do the trick even better than I do!</p>
<ul>
<li><a href="http://weblogs.asp.net/mehrantoosi/archive/2008/03/03/silverlight-s-xamlwriter.aspx">http://weblogs.asp.net/mehrantoosi/archive/2008/03/03/silverlight-s-xamlwriter.aspx</a></li>
<li><a href="http://projectsilverlight.blogspot.com/2009/10/silverlight-3-xamlwriter-v04.html">http://projectsilverlight.blogspot.com/2009/10/silverlight-3-xamlwriter-v04.html</a></li>
<li><a href="http://silverlightcontrib.codeplex.com/sourcecontrol/changeset/view/49151?projectName=silverlightcontrib#602856">http://silverlightcontrib.codeplex.com/sourcecontrol/changeset/view/49151?projectName=silverlightcontrib#602856</a></li>
</ul>
<p>All of these folks have done great work and deserve recognition for it.  I may have missed some – these were just from a preliminary search.</p>
<h2>I got plenty o’ plenty…</h2>
<p>You know I would never leave you without code and links to the live sample!  Last night, I updated SLaB to v0.9 (uh oh, I’m running out of numbers, but I’m not sure I want to have a “v1.0”… any suggestions?) and updated the live sample to include XamlSerializer demos.</p>
<p>I’ve also updated my <a href="http://www.davidpoll.com/Samples/SLaB" target="_blank">SLaB sample</a> to be installable!  Yup, it uses Transparent Platform Extensions and can run out of browser.  How?  That’s my RemoteControl (which uses my XapLoader) at work.  I’ll eventually blog about it specifically, but there’s more work I’d like to do there <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>With that said, here’s a summary of the links and access to the source!</p>
<ul>
<li><a href="http://www.davidpoll.com/Samples/SLaB/#/Views/SitemapPage.xaml?sitemapname=XamlSitemap" target="_blank">Live Sample</a> (<a href="http://www.davidpoll.com/Download/SLaB/SLaBv0.9.zip">source — found in the SLaB v0.9 source under &#8220;UtilitiesContent&#8221;</a>)</li>
<li><a href="http://www.davidpoll.com/Download/SLaB/SLaBv0.9.zip">SLaB v0.9</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.9 download of SLaB includes the following changes:
<ul>
<li>Added XamlSerializer and UiXamlSerializer for producing Xaml from POCOs or UI/DependencyObjects</li>
<li>Updated MEFContentLoader to include <a href="http://codebetter.com/blogs/glenn.block/default.aspx" target="_blank">Glenn Block&#8217;s</a> changes from his talk, supporting MEF&#8217;s Xap loading (sorry for the long delay on this – didn’t realize those changes had been made until someone brought it up to me!)</li>
<li>Fixed a bug with PackUriParser that caused navigations between pages within the same assembly (using full pack Uris) not to update the browser&#8217;s address bar as users moved from page to page.</li>
<li>Other minor bugfixes</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>As always, I love hearing what you have to say.  This is something I primarily do in my “copious” amounts of free time (yes, the quotes indicate my sarcasm) because I really enjoy working on/with Silverlight and seeing how far I can push it/myself.  I also like keeping my developer side alive and well by spending some quality time coding (have to break that Program Manager stereotype <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ).  I&#8217;m always surprised by how 6 PM suddenly turns into 4 AM when I’m working on something like this.  Anyhow, if there’s something you’d like to see or have a question about, speak up!  I’ll try to get back to you when I can, but I reserve the right to work on things I’m intrigued by! <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2010/07/25/to-xaml-with-love-an-experiment-with-xaml-serialization-in-silverlight/feed/</wfw:commentRss>
		<slash:comments>38</slash:comments>
		</item>
		<item>
		<title>Taking Microsoft Silverlight 4 Applications Beyond the Browser (TechEd WEB313)</title>
		<link>http://www.davidpoll.com/2010/06/10/taking-microsoft-silverlight-4-applications-beyond-the-browser-teched-web313/</link>
		<comments>http://www.davidpoll.com/2010/06/10/taking-microsoft-silverlight-4-applications-beyond-the-browser-teched-web313/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 07:06:51 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Out-of-browser]]></category>
		<category><![CDATA[Silverlight 4]]></category>
		<category><![CDATA[TechEd]]></category>
		<category><![CDATA[TechEd North America 2010]]></category>
		<category><![CDATA[Trusted Applications]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2010/06/10/taking-microsoft-silverlight-4-applications-beyond-the-browser-teched-web313/</guid>
		<description><![CDATA[It’s been quite a week here in New Orleans for TechEd North America.  I’m especially glad to see Silverlight fans showing up in force, asking questions at our booth and attending breakout sessions.  On Wednesday, I had the distinct pleasure of giving a talk at this great conference, and it was a real treat getting [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>It’s been quite a week here in New Orleans for <a href="http://northamerica.msteched.com/" target="_blank">TechEd North America</a>.  I’m especially glad to see Silverlight fans showing up in force, asking questions at our booth and attending breakout sessions.  On Wednesday, I had the distinct pleasure of giving a talk at this great conference, and it was a real treat getting to share some great content with you.  I’d like to thank all of you who attended for coming!  My talk – Taking Microsoft Silverlight 4 Applications Beyond the Browser – took a look at the features we’ve added for out-of-browser Silverlight applications with Silverlight 4.  I went over a fair amount of material, which I promised to make available on my blog, so I’ve provided the info below.</p>
<p>My talk covered a variety of features that were new to Silverlight 4 out-of-browser applications and allow you to build rich, sticky, immersive user experiences:</p>
<ul>
<li>Features available to all out-of-browser applications:
<ul>
<li>WebBrowser control, WebBrowserBrush, and how to use these together to deliver rich experiences that incorporate HTML and other content into your out-of-browser Silverlight applications</li>
<li>Out-of-browser window customization</li>
<li>Notification Windows (a.k.a. “Toast”)</li>
<li>Offline DRM media playback</li>
<li>Silent install/uninstall</li>
<li>“Emulate” execution (for running an out-of-browser application without having to install it)</li>
</ul>
</li>
<li>Features available to <strong><em>trusted</em></strong> out-of-browser applications:
<ul>
<li>Relaxation of sandbox speed bumps</li>
<li>File system access</li>
<li>Custom window chromes</li>
<li>Native interoperability through COM automation</li>
<li>XAP signing</li>
</ul>
</li>
</ul>
<p>Four simple applications were demonstrated during the talk:</p>
<ul>
<li>A basic WebBrowser application that explored the types of content the WebBrowser control can display and showed how to allow your Silverlight and HTML content to interact with each other</li>
<li>BrowserFlow, which showed how limitations of using a “windowed” WebBrowser control can be worked around using the WebBrowserBrush</li>
<li>“TrustedApp” (ignore the name <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ), which was a media application that took advantage of window customization and notification windows to provide an immersive user experience</li>
<li>An image editing application, which used a custom window chrome, file system access, and COM automation in order to provide a rich user experience that worked with local data and interoperated with PowerPoint</li>
</ul>
<p>The source for all of these demo applications can be found <a href="http://www.davidpoll.com/Download/WEB313 TechEd Materials.zip" target="_blank">here</a>.</p>
<p>You can also find the PowerPoint deck <a href="http://www.davidpoll.com/Download/WEB313_Poll.pptx" target="_blank">here</a>.</p>
<p>A big thanks to <a href="http://blogs.msdn.com/b/jstegman/" target="_blank">Joe Stegman</a> and <a href="http://nerddawg.blogspot.com/" target="_blank">Ashish Shetty</a> for their heavy inspiration for the content of the talk.  Make sure to check out their blogs!</p>
<p>Thanks again for coming out to show your interest in Silverlight out-of-browser applications!</p>
<p><strong><em>You can see the talk by going to the link below or using the Silverlight player embedded in this post:</em></strong></p>
<ul>
<li><a href="http://www.msteched.com/2010/NorthAmerica/WEB313" target="_blank">Taking Microsoft Silverlight 4 Applications Beyond the Browser (TechEd North America 2010 &#8212; WEB313)</a></li>
</ul>
<p><object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="645" height="365"><param name="source" value="http://www.msteched.com/ClientBin/players/VideoPlayer2009_03_27.xap" /><param name="initParams" value="m=http://ecn.channel9.msdn.com/o9/te/NorthAmerica/2010/wmv/WEB313.wmv,autostart=false,autohide=true,showembed=true, thumbnail=http://www.msteched.com/Skins/TechEdOnline/Styles/images/DefaultPlayerBackground.png, postid=0" /><param name="background" value="#00FFFFFF" /><a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;"><br />
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/><br />
</a><br />
</object></p>
<p><strong><em>Resources repeated here for convencience:</em></strong></p>
<ul>
<li><a href="http://www.davidpoll.com/Download/WEB313_Poll.pptx" target="_blank">PowerPoint deck</a></li>
<li><a href="http://www.davidpoll.com/Download/WEB313 TechEd Materials.zip" target="_blank">Demo source code</a></li>
</ul>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2010/06/10/taking-microsoft-silverlight-4-applications-beyond-the-browser-teched-web313/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
<enclosure url="http://ecn.channel9.msdn.com/o9/te/NorthAmerica/2010/wmv/WEB313.wmv" length="77428988" type="video/x-ms-wmv" />
		</item>
		<item>
		<title>Common Navigation UI and Authorization-driven Sitemaps</title>
		<link>http://www.davidpoll.com/2010/05/10/common-navigation-ui-and-authorization-driven-sitemaps/</link>
		<comments>http://www.davidpoll.com/2010/05/10/common-navigation-ui-and-authorization-driven-sitemaps/#comments</comments>
		<pubDate>Mon, 10 May 2010 22:00:36 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Authorization]]></category>
		<category><![CDATA[Controls]]></category>
		<category><![CDATA[Navigation]]></category>
		<category><![CDATA[Silverlight 4]]></category>
		<category><![CDATA[Silverlight and Beyond (SLaB)]]></category>
		<category><![CDATA[Sitemap]]></category>
		<category><![CDATA[WCF RIA Services]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2010/05/10/common-navigation-ui-and-authorization-driven-sitemaps/</guid>
		<description><![CDATA[Navigation-driven Silverlight applications tend to share some common pieces of UI.&#160; Traditionally, this has required sprinkling HyperlinkButtons throughout the application’s XAML.&#160; For ASP.NET a number of controls intended to drive navigation exist.&#160; These controls are driven by a sitemap, integrate well with authorization and roles (through sitemap trimming), and provide common user experiences around hierarchical [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Navigation-driven Silverlight applications tend to share some common pieces of UI.&#160; Traditionally, this has required sprinkling HyperlinkButtons throughout the application’s XAML.&#160; For ASP.NET a <a href="http://msdn.microsoft.com/en-us/library/e468hxky.aspx#SiteNavigationControls" target="_blank">number of controls intended to drive navigation exist</a>.&#160; These controls are driven by a sitemap, integrate well with authorization and roles (through sitemap trimming), and provide common user experiences around hierarchical application structures such as a TreeView-based list of hyperlinks and Breadcrumbs or navigation paths.&#160; These controls provide the user with context as to where in the application/site they currently are as well as where within the application they can go.</p>
<p>In this post, I’ll introduce a few controls that attempt to mimic this behavior in a Navigation-driven Silverlight application.&#160; I have added these controls to <a href="http://www.davidpoll.com/downloads-and-samples/#SLaB" target="_blank">SLaB</a>, and you’re welcome to use and modify them – or use them as examples for your own development – as you see fit.&#160; The controls are:</p>
<ul>
<li>TreeViewNavigator – a control which represents a sitemap as a TreeView </li>
</ul>
<p align="center"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="A TreeView Sitemap." border="0" alt="A TreeView Sitemap." src="http://www.davidpoll.com/wp-content/uploads/2010/05/image.png" width="316" height="516" /> </p>
<ul>
<li>BreadCrumbNavigator – a control which represents your current location within the sitemap’s link hierarchy and allows navigation back up the hierarchy as well as to siblings of any node within the hierarchy </li>
</ul>
<p align="center"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="A BreadCrumb sitemap." border="0" alt="A BreadCrumb sitemap." src="http://www.davidpoll.com/wp-content/uploads/2010/05/image1.png" width="453" height="30" /> </p>
<p>If you’ve been following the evolution of my sample projects, you may have noticed some navigation UI that’s not built into the default navigation application template and has controls that look like the ones I’ve described above.&#160; Surprise, surprise! <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> &#160; You can see this in action <a href="http://www.davidpoll.com/Samples/SLaB/" target="_blank">here</a>.</p>
<h3>How does this type of UI work?</h3>
<p>At its core, these controls have the same common set of functionality:</p>
<ul>
<li>Rendering UI based on a sitemap </li>
<li>Keeping UI synchronized with the current page within the application </li>
<li>Trimming the sitemap based upon the roles the current user belongs to and the metadata in the sitemap </li>
</ul>
<p>The goal of these controls is to allow the navigation structure of an application to be exposed to a user in a declarative fashion, much as one can do using <a href="http://msdn.microsoft.com/en-us/library/yy2ykkab.aspx" target="_blank">ASP.NET sitemaps</a>.&#160; The API for the controls above uses Sitemaps that can be specified in XAML, but follow the same general structure as in ASP.NET.</p>
<p>For example, the sitemaps displayed above are produced by the following XAML:</p>
<pre class="code">    <span style="color: blue">&lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">Sitemap </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Key</span><span style="color: blue">=&quot;Sitemap&quot;
                  </span><span style="color: red">Title</span><span style="color: blue">=&quot;DavidPoll.com&quot;
                  </span><span style="color: red">Description</span><span style="color: blue">=&quot;My homepage.  Check it out and see what it's all about!&quot;&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                          </span><span style="color: red">Title</span><span style="color: blue">=&quot;Home&quot;
                          </span><span style="color: red">Description</span><span style="color: blue">=&quot;The home page.&quot;
                          </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/Home.xaml&quot; /&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;SLaB Features&quot;
                          </span><span style="color: red">Description</span><span style="color: blue">=&quot;Demonstrations of Silverlight and Beyond features.&quot;&gt;
            &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Navigation&quot;&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Local Pages&quot;&gt;
<strong><em>                    &lt;</em></strong></span><strong><em><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span></em></strong><strong><em><span style="color: blue">=&quot;ContentFrame&quot;
                                      </span><span style="color: red">Title</span></em></strong><strong><em><span style="color: blue">=&quot;About&quot;
                                      </span><span style="color: red">Description</span></em></strong><strong><em><span style="color: blue">=&quot;The about page.&quot;
                                      </span><span style="color: red">Roles</span></em></strong><strong><em><span style="color: blue">=&quot;Foo&quot;
                                      </span><span style="color: red">Uri</span></em></strong><span style="color: blue"><strong><em>=&quot;/Views/About.xaml&quot; /&gt;</em></strong>
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                      </span><span style="color: red">Title</span><span style="color: blue">=&quot;A broken link&quot;
                                      </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/NonExistent.xaml&quot; /&gt;
                &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;On-Demand Xaps&quot;
                                  </span><span style="color: red">Description</span><span style="color: blue">=&quot;Pages in Xaps that will be loaded on-demand.&quot;
                                  </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                  </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/SitemapPage.xaml?sitemapname=OnDemandSitemap&quot;&gt;
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;This Domain&quot;&gt;
                        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                          </span><span style="color: red">Title</span><span style="color: blue">=&quot;Page in a big xap&quot;
                                          </span><span style="color: red">Uri</span><span style="color: blue">=&quot;pack://siteoforigin:,,SecondaryXap.xap/SecondaryXap;component/Page1.xaml&quot; /&gt;
                        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                          </span><span style="color: red">Title</span><span style="color: blue">=&quot;Awesome Page&quot;
                                          </span><span style="color: red">Uri</span><span style="color: blue">=&quot;pack://siteoforigin:,,TernaryXap.xap/TernaryXap;component/AwesomePage.xaml&quot; /&gt;
                        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                          </span><span style="color: red">Title</span><span style="color: blue">=&quot;Penguins (mapped Uri + metadata)&quot;
                                          </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/remote/TernaryXap/AwesomePage.xaml?Site=http://www.davidpoll.com&amp;amp;First Name=David&amp;amp;Last Name=Poll&amp;amp;Title=Penguins!&amp;amp;Please rate...&quot; /&gt;
                    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Cross-Domain&quot;&gt;
                        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                          </span><span style="color: red">Title</span><span style="color: blue">=&quot;http://open.depoll.com Page&quot;
                                          </span><span style="color: red">Uri</span><span style="color: blue">=&quot;pack://http:,,open.depoll.com,SimpleApplication,SimpleApplication.xap/SimpleApplication;component/Depoll.xaml?Source=http://open.depoll.com&amp;amp;File=wildlife.wmv&quot; /&gt;
                    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
                &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Printing&quot;
                                  </span><span style="color: red">Description</span><span style="color: blue">=&quot;Pages that demonstrate printing utilities that simplify pagination of data and printing of complex data sets.&quot;
                                  </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                  </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/SitemapPage.xaml?sitemapname=PrintingSitemap&quot;&gt;
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Collection Printing (DataGrid)&quot;
                                      </span><span style="color: red">Uri</span><span style="color: blue">=&quot;pack://siteoforigin:,,ScratchPrintingProject.xap/ScratchPrintingProject;component/PrintingPage.xaml&quot;
                                      </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; /&gt;
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Collection Printing (Template-based)&quot;
                                      </span><span style="color: red">Uri</span><span style="color: blue">=&quot;pack://siteoforigin:,,ScratchPrintingProject.xap/ScratchPrintingProject;component/ItemTemplatePrinting.xaml&quot;
                                      </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; /&gt;
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Pre-defined page printing (Template-based)&quot;
                                      </span><span style="color: red">Uri</span><span style="color: blue">=&quot;pack://siteoforigin:,,ScratchPrintingProject.xap/ScratchPrintingProject;component/PredefinedPages.xaml&quot;
                                      </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot; /&gt;
                &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Useful XAML Tools&quot;&gt;
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                      </span><span style="color: red">Title</span><span style="color: blue">=&quot;Demo (simple QueryString)&quot;
                                      </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/ObservableDictionaryDemo.xaml?a=b&amp;amp;c=d&amp;amp;e=f&amp;amp;g=h&quot; /&gt;
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;ContentFrame&quot;
                                      </span><span style="color: red">Title</span><span style="color: blue">=&quot;Demo (more complex QueryString)&quot;
                                      </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/ObservableDictionaryDemo.xaml?a=b&amp;amp;Name=David Eitan Poll&amp;amp;Url=http://www.davidpoll.com&amp;amp;No Value&amp;amp;Order=Dictionary&quot; /&gt;
                &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
            &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;DavidPoll.com&quot;&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;_blank&quot;
                                  </span><span style="color: red">Title</span><span style="color: blue">=&quot;Home Page&quot;
                                  </span><span style="color: red">Uri</span><span style="color: blue">=&quot;http://www.davidpoll.com&quot; /&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;_blank&quot;
                                  </span><span style="color: red">Title</span><span style="color: blue">=&quot;Navigation Posts&quot;
                                  </span><span style="color: red">Uri</span><span style="color: blue">=&quot;http://www.davidpoll.com/tag/navigation/&quot; /&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;_blank&quot;
                                  </span><span style="color: red">Title</span><span style="color: blue">=&quot;SLaB Posts&quot;
                                  </span><span style="color: red">Uri</span><span style="color: blue">=&quot;http://www.davidpoll.com/tag/silverlight-and-beyond-slab/&quot; /&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;_blank&quot;
                                  </span><span style="color: red">Title</span><span style="color: blue">=&quot;SLaB Download Page&quot;
                                  </span><span style="color: red">Uri</span><span style="color: blue">=&quot;http://www.davidpoll.com/downloads-and-samples/#SLaB&quot; /&gt;
            &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">Sitemap</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>You’ll note that the “About” link in the Sitemap above (bold/italic above) is missing from the TreeView.&#160; This is because the sitemaps do principal-based trimming of the sitemaps, ensuring that users only see the links they’re authorized to see.&#160; </p>
<p>In addition, the controls above stay in sync with the current page the user is viewing.</p>
<p>To get all of this functionality, there are three primary properties to set on the navigation controls (which derive from the Navigator abstract base class for this common functionality):</p>
<ul>
<li>Sitemap – usually, this is set to a Sitemap that is defined in resources somewhere, and may be shared across multiple navigation controls. </li>
<li>CurrentSource – if the navigation control needs to stay in sync with the user’s current location (which is not always the case – e.g. on Error/404-ish pages), bind it to the CurrentSource of the Frame that it will be navigating </li>
<li>Principal – if the navigation control should trim the sitemap based upon the User’s authorization, bind the Principal to be that of the current user.&#160; In the case of RIA Services, this can be done through the WebContext </li>
</ul>
<p>Ultimately, using these controls just requires some simple XAML.&#160; For the TreeViewNavigator:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">TreeViewNavigator </span><span style="color: red">CurrentSource</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">ElementName</span><span style="color: blue">=ContentFrame, </span><span style="color: red">Path</span><span style="color: blue">=CurrentSource}&quot;
                        </span><span style="color: red">Principal</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">User</span><span style="color: blue">, </span><span style="color: red">Source</span><span style="color: blue">={</span><span style="color: #a31515">StaticResource </span><span style="color: red">WebContext</span><span style="color: blue">}}&quot;
                        </span><span style="color: red">Sitemap</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">Sitemap</span><span style="color: blue">}&quot; /&gt;
</span></pre>
<p>And for the BreadCrumbNavigator:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">BreadCrumbNavigator </span><span style="color: red">CurrentSource</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">CurrentSource</span><span style="color: blue">, </span><span style="color: red">ElementName</span><span style="color: blue">=ContentFrame}&quot;
                          </span><span style="color: red">Principal</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">User</span><span style="color: blue">, </span><span style="color: red">Source</span><span style="color: blue">={</span><span style="color: #a31515">StaticResource </span><span style="color: red">WebContext</span><span style="color: blue">}}&quot;
                          </span><span style="color: red">Sitemap</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">Sitemap</span><span style="color: blue">}&quot; /&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h3>What can I customize?</h3>
<p>These controls are made to work with any ISitemap, which is, at its core, a container for a collection of ISitemapNodes.&#160; You can provide custom implementations of these, customizing your sitemaps to your heart’s content!&#160; For example, you might make sitemaps and sitemap nodes which:</p>
<ul>
<li>Retrieve their data from an ASP.NET xml-based sitemap file </li>
<li>Authorize users for access to nodes based upon more than just roles </li>
<li>Check authorization based on metadata on the page type itself, or by using a NavigationAuthorizer from the AuthContentLoader library </li>
<li>Import one sitemap into another (I’ve actually provided an implementation of this in SLaB so that sitemaps and sub-sitemaps can be used) </li>
</ul>
<p>Furthermore, the controls themselves are look-less, and you should be able to completely re-template them, customizing how hyperlinks are displayed, how much of the tree is expanded, and so on.&#160; If there’s something I’m missing, let me know!</p>
<h3>So, can I see it in action?</h3>
<p>Of course!&#160; You know I never leave you without a demo!&#160; In fact, today I’ve got two for you!</p>
<p>First, the <a href="http://www.davidpoll.com/Samples/SLaB/" target="_blank">SLaB demo application</a> itself uses these controls.&#160; Click around and see how things behave.&#160; You’ll notice the controls are the centerpiece of the navigation UI, but also make appearances throughout the application, <a href="http://www.davidpoll.com/Samples/SLaB/#/Views/SitemapPage.xaml?sitemapname=PrintingSitemap" target="_blank">such as on “category pages”</a> that list only the links within a particular section of the site, and on <a href="http://www.davidpoll.com/Samples/SLaB/#/Views/NonExistent.xaml" target="_blank">error pages</a> within the application, making it easier for users to get back to useful locations within the application.</p>
<p>The second demo application is meant to show role-driven sitemap trimming.&#160; It uses <a href="http://www.silverlight.net/getstarted/riaservices/" target="_blank">WCF RIA Services</a> to drive authentication and authorization, and shows and hides parts of the sitemap based upon the roles the user belongs to.&#160; You can log in using the following credentials:</p>
<p><strong>User</strong>: Test</p>
<p><strong>Password</strong>: _Testing</p>
<p>Experiment with the application and what happens to the navigation controls as you log in and log out.&#160; This also uses the AuthContentLoader from SLaB to perform additional authorization before actually loading any page.</p>
<p><a href="http://www.davidpoll.com/Samples/SitemapBusinessApplication/ScratchBusinessApplicationTestPage.html#/Views/Home.xaml" 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="Authorization-driven navigation controls" border="0" alt="Authorization-driven navigation controls" src="http://www.davidpoll.com/wp-content/uploads/2010/05/image2.png" width="644" height="432" /></a>&#160;</p>
<p>The XAML for the sitemap in the application above shows how access can be restricted and how trimming takes effect:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">Sitemap </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Key</span><span style="color: blue">=&quot;Sitemap&quot;
                </span><span style="color: red">Title</span><span style="color: blue">=&quot;Scratch Business Application&quot;
                </span><span style="color: red">Description</span><span style="color: blue">=&quot;A sample RIA Services Business application that uses SLaB to represent its navigation and do authorization.&quot;&gt;
    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Home&quot;
                        </span><span style="color: red">Description</span><span style="color: blue">=&quot;The home page for the application&quot;
                        </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/Home.xaml&quot; /&gt;
    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Broken Link&quot;
                        </span><span style="color: red">Description</span><span style="color: blue">=&quot;A broken link&quot;
                        </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/NonExistentPage.xaml&quot; /&gt;
    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Protected Pages (Non-Trimmed)&quot;
                        </span><span style="color: red">Description</span><span style="color: blue">=&quot;Pages protected by authorization&quot;&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;About&quot;
                            </span><span style="color: red">Description</span><span style="color: blue">=&quot;The About page for the application&quot;
                            </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/About.xaml&quot; /&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Page for registered users&quot;
                            </span><span style="color: red">Description</span><span style="color: blue">=&quot;A page that can only be visited by registered users&quot;
                            </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/RegisteredUsersPage.xaml&quot; /&gt;
    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Protected Pages (Trimmed)&quot;
                        </span><span style="color: red">Roles</span><span style="color: blue">=&quot;Registered Users&quot;
                        </span><span style="color: red">Description</span><span style="color: blue">=&quot;Pages protected by authorization&quot;&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;About&quot;
                            </span><span style="color: red">Description</span><span style="color: blue">=&quot;The About page for the application&quot;
                            </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/About.xaml?trimmed&quot; /&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Page for registered users&quot;
                            </span><span style="color: red">Description</span><span style="color: blue">=&quot;A page that can only be visited by registered users&quot;
                            </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/RegisteredUsersPage.xaml?trimmed&quot; /&gt;
    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Protected Pages (Leaf nodes trimmed)&quot;
                        </span><span style="color: red">Description</span><span style="color: blue">=&quot;Pages protected by authorization&quot;&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;About&quot;
                            </span><span style="color: red">Roles</span><span style="color: blue">=&quot;Registered Users&quot;
                            </span><span style="color: red">Description</span><span style="color: blue">=&quot;The About page for the application&quot;
                            </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/About.xaml?leaftrimmed&quot; /&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;Page for registered users&quot;
                            </span><span style="color: red">Roles</span><span style="color: blue">=&quot;Registered Users&quot;
                            </span><span style="color: red">Description</span><span style="color: blue">=&quot;A page that can only be visited by registered users&quot;
                            </span><span style="color: red">Uri</span><span style="color: blue">=&quot;/Views/RegisteredUsersPage.xaml?leaftrimmed&quot; /&gt;
    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">SitemapNode </span><span style="color: red">Title</span><span style="color: blue">=&quot;DavidPoll.com&quot;
                        </span><span style="color: red">Description</span><span style="color: blue">=&quot;David Poll's homepage&quot;
                        </span><span style="color: red">Uri</span><span style="color: blue">=&quot;http://www.davidpoll.com&quot;
                        </span><span style="color: red">TargetName</span><span style="color: blue">=&quot;_blank&quot; /&gt;
&lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">Sitemap</span><span style="color: blue">&gt;
</span></pre>
<h3>Cool… but where are the bits?</h3>
<p>Well, the good news is that you can get all of these controls in my Silverlight and Beyond (SLaB) libraries!&#160; Give them a shot and let me know what you think.&#160; What’s missing from these controls?&#160; What other pieces of user experience are you looking for?&#160; Are the behaviors of the TreeViewNavigator and BreadCrumbNavigator correct for your scenarios and desired UX?</p>
<p>With that said, here’s a summary of the links and access to the source!</p>
<li><a href="http://www.davidpoll.com/Samples/SLaB/">Live Sample</a> (<a href="http://www.davidpoll.com/Download/SLaB/SLaBv0.5.zip">source &#8212; found in the SLaB v0.7 source under &quot;ScratchApplication&quot;</a>) </li>
<li><a href="http://www.davidpoll.com/Samples/SitemapBusinessApplication/ScratchBusinessApplicationTestPage.html" target="_blank">Live Sample using RIA Services for AuthN/AuthX</a> (<a href="http://www.davidpoll.com/Samples/Download/SitemapBusinessApplication.zip" target="_blank">source</a>)&#160;
<p><a href="http://www.davidpoll.com/Download/SLaB/SLaBv0.7.zip">SLaB v0.7</a> (includes source, a sample app, some tests, and binaries) </p>
<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.7 download of SLaB includes the following changes:
<ul>
<li>Added TryImportResourceDictionary that allows XAML resource dictionaries to be imported but fail quietly (so that if not all dependencies for a control are met, other controls in the library (that share the same generic.xaml) can still be used. </li>
<li>Added XamlDependencyAttribute, which ensures that Xaml-only assembly dependencies can be declared and appear as dependencies in the assembly metadata. </li>
<li>Other minor bugfixes </li>
</ul>
</li>
<li>In the interim (since my last post with SLaB), I also produced the v0.6 version, which had the following changes:
<ul>
<li>Made CollectionPrinter work for controls like DataGrid when they auto-generate columns for generic collections (based on the type in IEnumerable&lt;T&gt;) </li>
<li>Added a utility method that allows you to get the MethodInfo for an arbitrary method, including private ones (from anywhere that the method is accessible) </li>
<li>Other minor bugfixes </li>
</ul>
</li>
</ul>
<p>As always, I’d love to know what you think!</p>
</p>
</li>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2010/05/10/common-navigation-ui-and-authorization-driven-sitemaps/feed/</wfw:commentRss>
		<slash:comments>39</slash:comments>
		</item>
		<item>
		<title>Samples updated and code in comments</title>
		<link>http://www.davidpoll.com/2010/04/25/samples-updated-and-code-in-comments/</link>
		<comments>http://www.davidpoll.com/2010/04/25/samples-updated-and-code-in-comments/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 03:47:42 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Off-Topic]]></category>
		<category><![CDATA[Silverlight 4]]></category>
		<category><![CDATA[Silverlight 4 Beta]]></category>
		<category><![CDATA[Silverlight 4 RC]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2010/04/25/samples-updated-and-code-in-comments/</guid>
		<description><![CDATA[Hi folks!&#160; Just a super-quick note: in the last week, I’ve updated most of my old samples (it should be everything except for the one from my PDC talk – that one is a fair amount more work due to breaking changes in RIA Services since the Silverlight 4 Beta) that were build on the [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Hi folks!&#160; Just a super-quick note: in the last week, I’ve updated most of my old samples (it should be everything except for the one from my PDC talk – that one is a fair amount more work due to breaking changes in RIA Services since the Silverlight 4 Beta) that were build on the Silverlight 4 Beta and RC.</p>
<p>In addition, if you are commenting on a post here and need to post some code (in particular XAML), take note that my commenting system automatically strips out XML tags, so XAML’s a no-go.&#160; I’ve just added a plugin for my blog that allows you to use a “[code][/code]” tag to mark a section of your comment as code, and it will be monospace-formatted with XML tags converted for display.&#160; Hopefully this will clear up some issues people have had with commenting in the past!</p>
<p>Enjoy the rest of your weekend!</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2010/04/25/samples-updated-and-code-in-comments/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A &#8220;refreshing&#8221; Authentication/Authorization experience with Silverlight 4</title>
		<link>http://www.davidpoll.com/2010/04/25/a-refreshing-authenticationauthorization-experience-with-silverlight-4/</link>
		<comments>http://www.davidpoll.com/2010/04/25/a-refreshing-authenticationauthorization-experience-with-silverlight-4/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 03:35:28 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[ContentLoader]]></category>
		<category><![CDATA[Navigation]]></category>
		<category><![CDATA[Silverlight 4]]></category>
		<category><![CDATA[Silverlight and Beyond (SLaB)]]></category>
		<category><![CDATA[WCF RIA Services]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2010/04/25/a-refreshing-authenticationauthorization-experience-with-silverlight-4/</guid>
		<description><![CDATA[At the beginning of the year, as part of a series of posts about the INavigationContentLoader extensibility point in Silverlight 4, I described a way to use a content loader to do authorization before allowing a user to navigate to a page.&#160; With the content loader, you can either throw an exception when an unauthorized [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>At the beginning of the year, as part of a series of posts about the INavigationContentLoader extensibility point in Silverlight 4, <a href="http://www.davidpoll.com/2010/01/01/opening-up-silverlight-4-navigation-authenticationauthorization-in-an-inavigationcontentloader/">I described a way to use a content loader to do authorization before allowing a user to navigate to a page</a>.&#160; With the content loader, you can either throw an exception when an unauthorized user tries to reach a protected Page, redirect your users to another Page, or return a different page (e.g. a Login page) in its stead.&#160; This makes for a fairly nice experience for your users, wherein they are taken directly to a login page (or at least a page with more information about why they cannot access the given page) when they lack the credentials to reach the page they are requesting.</p>
<p>The trouble with this, however, was that once your application reached the login page and your user attempted to log in, there was no clear/easy/universal way to get the user back to the location he/she was originally requesting.&#160; Ideally, an application would keep its context (i.e. the Uri wouldn’t change) when it sends a user to a login page, and take the user to the restricted content once the right credentials are acquired.</p>
<p>When I wrote my original post, I was aware of this limitation, and didn’t have a great solution for it.&#160; Attempting to re-navigate to the requested page was unhelpful because navigating twice to the same Uri is a no-op.&#160; Starting with the Silverlight 4 RC (and continuing into the RTW release, of course), however, such a solution exists!&#160; We quietly added an API to <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.frame(VS.95).aspx">Frame</a> and <a href="http://msdn.microsoft.com/en-us/library/system.windows.navigation.navigationservice(v=VS.95).aspx">NavigationService</a>: <a href="http://msdn.microsoft.com/en-us/library/system.windows.navigation.navigationservice.refresh(v=VS.95).aspx">Refresh()</a>.</p>
<h3>How does refreshing help?</h3>
<p>Calling Frame.Refresh() or NavigationService.Refresh() causes the entire page to be reloaded, meaning that a custom content loader will be called, providing an opportunity to return a different page (or redirect elsewhere).&#160; Without having to make any changes to <a href="http://www.davidpoll.com/downloads-and-samples/#SLaB" target="_blank">SLaB</a> and the <a href="http://www.davidpoll.com/2010/01/01/opening-up-silverlight-4-navigation-authenticationauthorization-in-an-inavigationcontentloader/" target="_blank">AuthContentLoader</a> or <a href="http://www.davidpoll.com/2009/12/07/opening-up-silverlight-4-navigation-event-based-and-error-handling-inavigationcontentloaders/" target="_blank">ErrorPageLoader</a>, we can now produce the desired experience!</p>
<p>Now, our ContentLoader XAML looks 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">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;&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.ContentLoader</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPage </span><span style="color: red">ExceptionType</span><span style="color: blue">=&quot;UnauthorizedAccessException&quot;
                            </span><span style="color: red">ErrorPageUri</span><span style="color: blue">=&quot;/Views/LoginPage.xaml&quot; /&gt;
            &lt;</span><span style="color: #a31515">SLaB</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">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ContentLoader</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">AuthContentLoader </span><span style="color: red">Principal</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">User</span><span style="color: blue">, </span><span style="color: red">Source</span><span style="color: blue">={</span><span style="color: #a31515">StaticResource </span><span style="color: red">WebContext</span><span style="color: blue">}}&quot;&gt;
                    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthorizer</span><span style="color: blue">&gt;
                        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule </span><span style="color: red">UriPattern</span><span style="color: blue">=&quot;^/Views/About\.xaml\??.*$&quot;&gt;
                            &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">Deny </span><span style="color: red">Users</span><span style="color: blue">=&quot;?&quot; /&gt;
                            &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">Allow </span><span style="color: red">Users</span><span style="color: blue">=&quot;*&quot; /&gt;
                        &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule</span><span style="color: blue">&gt;
                        &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule </span><span style="color: red">UriPattern</span><span style="color: blue">=&quot;^/Views/RegisteredUsersPage\.xaml\??.*$&quot;&gt;
                            &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">Allow </span><span style="color: red">Roles</span><span style="color: blue">=&quot;Registered Users&quot; /&gt;
                        &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthRule</span><span style="color: blue">&gt;
                    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">NavigationAuthorizer</span><span style="color: blue">&gt;
                &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">AuthContentLoader</span><span style="color: blue">&gt;
            &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">ErrorPageLoader.ContentLoader</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">SLaB</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;
</span></pre>
<p>The primary difference between the XAML above and the original XAML I had posted was to remove the ErrorRedirector (which caused redirection to the login page rather than loading the login page in place of the requested page).&#160; Because this was removed, we no longer need nested ErrorPageLoaders (which existed in order to redirect only in the login case, and load the error page without changing the Uri for other errors).&#160; You’ll note that for the About page and the RegisteredUsers page, access is restricted.&#160; When an UnauthorizedAccessException occurs, users will see the LoginPage.</p>
<p>In the login page, all we need to do now is call NavigationService.Refresh() when the user logs in.&#160; My example uses WCF RIA Service’s WebContext find out this information, but you could just as easily attempt to refresh after a ChildWindow is closed or a Login button is clicked.</p>
<p>My LoginPage code looks like this:</p>
<pre class="code"><span style="color: blue">protected override void </span>OnNavigatedTo(<span style="color: #2b91af">NavigationEventArgs </span>e)
{
    <span style="color: #2b91af">WebContext</span>.Current.Authentication.LoggedIn += Authentication_LoggedIn;
}

<span style="color: blue">protected override void </span>OnNavigatedFrom(<span style="color: #2b91af">NavigationEventArgs </span>e)
{
    <span style="color: #2b91af">WebContext</span>.Current.Authentication.LoggedIn -= Authentication_LoggedIn;
}

<span style="color: blue">void </span>Authentication_LoggedIn(<span style="color: blue">object </span>sender, <span style="color: #2b91af">AuthenticationEventArgs </span>e)
{
    <strong><em><u>NavigationService.Refresh();</u></em></strong>
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Yep, that’s all it takes!&#160; Now, when a user logs in (either by clicking the login button on the page or logging in through some other dialog in the application), the Frame’s content is refreshed, and the AuthContentLoader attempts to verify the user’s credentials once again.</p>
<h3>Cool!&#160; Can I see it in action?</h3>
<p>You know I would never leave you without a sample!&#160; Click the image below to see the sample application (based on my <a href="http://www.davidpoll.com/2010/01/01/opening-up-silverlight-4-navigation-authenticationauthorization-in-an-inavigationcontentloader/">original example</a>, just updated for SL4).&#160; First try navigating to the protected pages without logging in, then try logging in and note how the page automatically is refreshed based upon your new credentials.</p>
<p><strong><em>Login information:</em></strong> Log in with User = “Test”, Password = “_Testing”</p>
<p><a href="http://www.davidpoll.com/Samples/AuthorizingNavigation/ScratchBusinessApplicationTestPage.aspx#/Home" 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="A WCF RIA Services application with the AuthContentLoader" border="0" alt="A WCF RIA Services application with the AuthContentLoader" src="http://www.davidpoll.com/wp-content/uploads/2010/04/image5.png" width="644" height="432" /></a></p>
<p>&#160;</p>
<p>You can find the source for this application <a href="http://www.davidpoll.com/Samples/Download/AuthorizingNavigation.zip" target="_blank">here</a>. </p>
<h3>Anything else I should know about Refresh()?</h3>
<p>Without a doubt, Refresh()’s usefulness is not restricted to this scenario.&#160; With custom content loaders, it’s particularly useful to be able to refresh the page, since the page returned as a result of that navigation may change from one attempt to the next.&#160; Even without a custom content loader, Refresh() allows you to create a new instance of a page, making re-initializing the page you’ve navigated to clean and simple.&#160; The behavior is identical to navigating to a new page – the only difference is that the old and new Uris are identical, and the <a href="http://msdn.microsoft.com/en-us/library/system.windows.navigation.navigationmode(VS.95).aspx" target="_blank">NavigationMode</a> of the operation is “Refresh”.</p>
<p>Please note: Refresh() will still respect the <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.page.navigationcachemode(v=VS.95).aspx" target="_blank">NavigationCacheMode</a> of the Page and the <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.frame.cachesize(v=VS.95).aspx" target="_blank">CacheSize</a> of the <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.frame(v=VS.95).aspx" target="_blank">Frame</a>.&#160; If a Page is being cached, calling Refresh() will not create a new instance (but will still cause the Navigating/Navigated events and the corresponding overrides on Page to be raised/called).&#160; To prevent this from happening, set the NavigationCacheMode of the page being refreshed to Disabled before the new page would be loaded (i.e. before Refresh() is called or while handling the Navigating event).</p>
<h3>Is that it?</h3>
<p>Yep, that’s it! <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> &#160; Let me know what you think!&#160; What else would you like to see?</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2010/04/25/a-refreshing-authenticationauthorization-experience-with-silverlight-4/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>Making printing easier in Silverlight 4</title>
		<link>http://www.davidpoll.com/2010/04/16/making-printing-easier-in-silverlight-4/</link>
		<comments>http://www.davidpoll.com/2010/04/16/making-printing-easier-in-silverlight-4/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 23:35:21 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Printing]]></category>
		<category><![CDATA[Silverlight 4]]></category>
		<category><![CDATA[Silverlight and Beyond (SLaB)]]></category>
		<category><![CDATA[Silverlight Toolkit]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2010/04/16/making-printing-easier-in-silverlight-4/</guid>
		<description><![CDATA[Well, what an exciting week!&#160; First Visual Studio 2010 is released, followed by Silverlight 4 yesterday!&#160; Consequently, I was inspired to post about something new!&#160; I’ve been spending some time looking at the new printing feature in Silverlight 4, and while on the surface it looks like a pretty simple and lower-level set of APIs, [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Well, what an exciting week!&#160; First Visual Studio 2010 is released, followed by <a href="http://www.silverlight.net/getstarted/silverlight-4/">Silverlight 4</a> yesterday!&#160; Consequently, I was inspired to post about something new!&#160; I’ve been spending some time looking at the new printing feature in Silverlight 4, and while on the surface it looks like a pretty simple and lower-level set of APIs, it’s possible to build rich frameworks on top of them for accomplishing common printing tasks.&#160; In this post, I’ll take a look at an attempt I made (and added to <a href="http://www.davidpoll.com/downloads-and-samples/#SLaB">SLaB</a>) at building such a higher-level API over printing that makes printing collections of data easier.</p>
<p>Specifically, I’ve been building a CollectionPrinter control – a control that paginates, previews, and prints collections in a template-driven, designer-friendly way.&#160; With this control, printing a collection can be entirely XAML-based and code-free!</p>
<p>For example, the image below shows some sample data (courtesy of the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=88484825-1b3c-4e8c-8b14-b05d025e1541&amp;displaylang=en">Blend 4 RC</a>) within a DataGrid being printed across multiple pages.</p>
<p><a href="http://www.davidpoll.com/Samples/Download/Short%20DataGrid%20Document.pdf"><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="A printed collection." border="0" alt="A printed collection." src="http://www.davidpoll.com/wp-content/uploads/2010/04/image.png" width="644" height="404" /></a></p>
<p>And you can see it in action by clicking <a href="http://www.davidpoll.com/Samples/SLaB/#/Views/SitemapPage.xaml?sitemapname=PrintingSitemap">here</a>.</p>
<p>Of course, this is just an example of how one might want to build such a library, but it hopefully inspires some ideas you all might have around printing!&#160; I’d love to know what you think! </p>
<h3>So, how does printing work?</h3>
<p>The printing APIs in Silverlight 4 center around the <a href="http://msdn.microsoft.com/en-us/library/system.windows.printing.printdocument(VS.96).aspx">PrintDocument</a> class.&#160; SilverlightShow has a great <a href="http://www.silverlightshow.net/items/A-look-at-the-Printing-API-in-Silverlight-4.aspx">article on the basics of using this class</a>.&#160; Basically, the workflow for printing in Silverlight 4 is the following:</p>
<ol>
<li>Create a new PrintDocument </li>
<li>Attach a handler to the PrintDocument.PrintPage event, which will be called for each page you choose to print </li>
<li>Call PrintDocument.Print(), passing in a document name (which will appear in the print spooler, for example) </li>
<li>The user is prompted to print </li>
<li>In each PrintPage call:
<ol>
<li>If you have content ready to print:
<ol>
<li>Choose some UI to print to the page and set the PageVisual in the PrintPageEventArgs </li>
<li>If there are more pages to print, set HasMorePages on PrintPageEventPargs to true </li>
</ol>
</li>
<li>If you’re not ready to print yet:
<ol>
<li>Set PageVisual to null </li>
<li>Set HasMorePages to true (you will be called back after a short delay for the content – up to 8 attempts will be made to print a page before printing fails) </li>
</ol>
</li>
</ol>
</li>
</ol>
<p>And that’s it!&#160; For each page, Silverlight will render a bitmap of the visuals you provided in PageVisual (just like with <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap(VS.95).aspx">WriteableBitmap</a>), then send this bitmap to the printer.</p>
<h3>That all seems pretty straightforward… why do I need anything more?</h3>
<p>Well, it<em> is</em> pretty straightforward.&#160; However, there’s a fair amount of work that you would have to do in order to create a coherently printed document:</p>
<ul>
<li><strong>Pagination</strong> – in order to figure out which items to print on each page, you will need to add items to the page, searching for the item that would flow beyond the end of the page.&#160; This involves measuring/arranging pages and expanding templates, keeping track of the items you’ve printed so far, handling cases where items are too big for the page, and so on. </li>
<li><strong>Page layout</strong> – it’s very common to want headers/footers on your pages, which further complicates the pagination process. </li>
<li><strong>Page context</strong> – when printing a particular page, you often want some additional context, such as which items are on the page, the page number, the total number of pages (so that you can print “Page 1 / 10”, whether this is the first or last page, etc.&#160; This context must be calculated and tracked, and is difficult when the printing process is progressive as with the above API (e.g. how can I print the first page without first having rendered all of the pages, so that I know what the total page count will be?) </li>
<li><strong>Dealing with content not in the visual tree</strong> – often, you want to print UI directly from the visual tree, which is much easier.&#160; But when printing controls that are <strong><em>NOT</em></strong> in the visual tree, life gets much more complicated.&#160; As with WriteableBitmap, controls used as the PageVisual don’t get a full visual tree pass, meaning that events like <a href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.loaded(v=VS.95).aspx">FrameworkElement.Loaded</a> don’t get raised.&#160; Some controls use such events to do initialization, such as the charting controls in the <a href="http://silverlight.codeplex.com/">Silverlight Toolkit</a>.&#160; In order to properly print arbitrary controls, it’s often helpful to actually place the control in the visual tree. </li>
<li><strong>Handling animations</strong> – many controls (again, such as the charting controls in the Silverlight Toolkit) have animations and transitions by default.&#160; For the charting controls, the data points being charted fade in by default.&#160; If you try to print this when the control is created, you’ll get a blank chart!&#160; One way to deal with this (if it’s the desired behavior) is to walk the visual tree, causing any running storyboard to <a href="http://msdn.microsoft.com/en-us/library/cc190726(VS.96).aspx">SkipToFill</a>. </li>
<li><strong>Print preview</strong> – while it’s not really possible to give a full preview of what a printed document will look like (because you can’t find out what the size/margins of the page will be before printing has started), one can approximate it and at least provide a hint as to what to expect when printing begins. </li>
<li><strong>Designability</strong> – Working with pages to print in Blend or Visual Studio’s designer can be somewhat difficult, especially if you need to write the code to handle the above cases. </li>
</ul>
<p>As you can see, there are a number of complicating factors when doing sophisticated printing, but these can be abstracted away if the domain you’re given is specific enough.&#160; In this case, we’re printing a collection, and we can use the items in the collection as the units between which we can break up pages.</p>
<h3>OK, cool, I think I get it.&#160; So, how does it work?</h3>
<p>You can use the CollectionPrinter much like an <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol(VS.95).aspx">ItemsControl</a>.&#160; It’s fundamentally DataTemplate-driven.&#160; It has an ItemsSource and an ItemTemplate, but instead, you can specify a BodyTemplate (which, by default, is an ItemsControl <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ).&#160; For headers, footers, and such, you can specify additional DataTemplates.</p>
<p>All of the DataTemplates are bound to a “CollectionPrintContext” which contains the following pieces of information:</p>
<ul>
<li><strong>CurrentItems</strong> – the set of items being printed on this page (this collection will be built up dynamically during printing/previewing) </li>
<li><strong>CurrentPage/CurrentPageIndex</strong> – the page number (1- or 0-based) being printed </li>
<li>First/Last items (so that you can print “Items 1-10” or “Aa – Aardvark” on each page):
<ul>
<li><strong>FirstItem/FirstItemIndex/FirstItemValue</strong> – the first item being printed on the page (1-based index, 0-based index, or actual value, respectively) </li>
<li><strong>LastItem/LastItemIndex/LastItemValue</strong> – the last item being printed on the page (1-based index, 0-based index, or actual value, respectively) </li>
</ul>
</li>
<li><strong>PageCount</strong> – the total number of pages to print (note: this is a nullable int value and may not be provided if there isn’t time to finish pre-rendering all pages before the PrintPage callback limit is reached) </li>
<li><strong>PageMargins</strong> – the margins of the page being printed </li>
<li><strong>PrintableArea</strong> – the size of the space in which the page can be printed </li>
</ul>
<p>The hope is that with these pieces of information to bind to, you can print rich pages for your users.&#160; The rest is just creative use of bindings <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>To kick off printing, either call the Print() method on the CollectionPrinter or bind a button to the PrintCommand property on the CollectionPrinter for completely code-free printing!</p>
<p>The CollectionPrinter will attempt to address all of the issues above, spawning invisible popups to ensure that the UI actually has a moment to be in the visual tree, walking the visual tree to skip animations to fill, and most importantly paginating all of the items in the ItemsSource.</p>
<h3>Let’s see it in action!</h3>
<h4>Using an ItemTemplate</h4>
<p>The most basic case for printing with the CollectionPrinter is to use an ItemTemplate, just as you would with an ItemsControl.&#160; The CollectionPrinter will happily handle cases where items are irregularly sized, so be as rich as you’d like!</p>
<p>For example:</p>
<p><a href="http://www.davidpoll.com/Samples/SLaB/#pack://siteoforigin:,,ScratchPrintingProject.xap/ScratchPrintingProject;component/ItemTemplatePrinting.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="ItemTemplate-based Printing" border="0" alt="ItemTemplate-based Printing" src="http://www.davidpoll.com/wp-content/uploads/2010/04/image1.png" width="644" height="425" /></a> </p>
<p>The XAML style for this CollectionPrinter is as follows:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">Style </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Key</span><span style="color: blue">=&quot;PrintStyle&quot;
        </span><span style="color: red">TargetType</span><span style="color: blue">=&quot;SLaB:CollectionPrinter&quot;&gt;
    &lt;</span><span style="color: #a31515">Setter </span><span style="color: red">Property</span><span style="color: blue">=&quot;ItemTemplate&quot;&gt;
        &lt;</span><span style="color: #a31515">Setter.Value</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">Border </span><span style="color: red">BorderThickness</span><span style="color: blue">=&quot;1&quot;
                        </span><span style="color: red">BorderBrush</span><span style="color: blue">=&quot;Gray&quot;&gt;
                    &lt;</span><span style="color: #a31515">Grid</span><span style="color: blue">&gt;
                        &lt;</span><span style="color: #a31515">Grid.Resources</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;TextBlock&quot;&gt;
                                &lt;</span><span style="color: #a31515">Setter </span><span style="color: red">Property</span><span style="color: blue">=&quot;FontSize&quot;
                                        </span><span style="color: red">Value</span><span style="color: blue">=&quot;12&quot; /&gt;
                            &lt;/</span><span style="color: #a31515">Style</span><span style="color: blue">&gt;
                        &lt;/</span><span style="color: #a31515">Grid.Resources</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: blue">/&gt;
                            &lt;</span><span style="color: #a31515">ColumnDefinition </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">StackPanel </span><span style="color: red">Grid.Column</span><span style="color: blue">=&quot;0&quot;
                                    </span><span style="color: red">Margin</span><span style="color: blue">=&quot;10&quot;&gt;
                            &lt;</span><span style="color: #a31515">Image </span><span style="color: red">Source</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Photo</span><span style="color: blue">}&quot;
                                   </span><span style="color: red">Height</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Age</span><span style="color: blue">}&quot;
                                   </span><span style="color: red">Width</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Age</span><span style="color: blue">}&quot;
                                   </span><span style="color: red">HorizontalAlignment</span><span style="color: blue">=&quot;Left&quot; /&gt;
                            &lt;</span><span style="color: #a31515">TextBlock </span><span style="color: red">Text</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Name</span><span style="color: blue">, </span><span style="color: red">StringFormat</span><span style="color: blue">='Name: {0}'}&quot; /&gt;
                            &lt;</span><span style="color: #a31515">TextBlock </span><span style="color: red">Text</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Age</span><span style="color: blue">, </span><span style="color: red">StringFormat</span><span style="color: blue">='Age: {0}'}&quot; /&gt;
                            &lt;</span><span style="color: #a31515">TextBlock </span><span style="color: red">Text</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Address</span><span style="color: blue">, </span><span style="color: red">StringFormat</span><span style="color: blue">='Address: {0}'}&quot;
                                       </span><span style="color: red">TextWrapping</span><span style="color: blue">=&quot;Wrap&quot; /&gt;
                        &lt;/</span><span style="color: #a31515">StackPanel</span><span style="color: blue">&gt;
                        &lt;</span><span style="color: #a31515">toolkit</span><span style="color: blue">:</span><span style="color: #a31515">Chart </span><span style="color: red">Grid.Column</span><span style="color: blue">=&quot;1&quot;
                                       </span><span style="color: red">Title</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Name</span><span style="color: blue">}&quot;&gt;
                            &lt;</span><span style="color: #a31515">toolkit</span><span style="color: blue">:</span><span style="color: #a31515">ScatterSeries </span><span style="color: red">DependentValuePath</span><span style="color: blue">=&quot;X&quot;
                                                   </span><span style="color: red">IndependentValuePath</span><span style="color: blue">=&quot;Y&quot;
                                                   </span><span style="color: red">Title</span><span style="color: blue">=&quot;Values&quot;
                                                   </span><span style="color: red">ItemsSource</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Values</span><span style="color: blue">}&quot; /&gt;
                        &lt;/</span><span style="color: #a31515">toolkit</span><span style="color: blue">:</span><span style="color: #a31515">Chart</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">Border</span><span style="color: blue">&gt;
            &lt;/</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">Setter.Value</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">Setter</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">Setter </span><span style="color: red">Property</span><span style="color: blue">=&quot;HeaderTemplate&quot;&gt;
        &lt;</span><span style="color: #a31515">Setter.Value</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt; ... </span><span style="color: blue">&lt;/</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">Setter.Value</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">Setter</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">Setter </span><span style="color: red">Property</span><span style="color: blue">=&quot;FooterTemplate&quot;&gt;
        &lt;</span><span style="color: #a31515">Setter.Value</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt; ... </span><span style="color: blue">&lt;/</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">Setter.Value</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">Setter</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">Style</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">CollectionPrinter </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;printer&quot;
                        </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">PrintStyle</span><span style="color: blue">}&quot; /&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>All it takes to print based on this style is setting the ItemsSource (in this case to some Blend sample data) and binding a button to the PrintCommand on the control.&#160; In my header and footer templates, I have controls that are bound to the CollectionPrintContext, and whose visibilities are determined by binding to things like IsFirstPage (see the source included in the SLaB download for more details).</p>
<h4>Changing the BodyTemplate (and printing a DataGrid)</h4>
<p>Now, that’s all wonderful if all I want to do is print something that looks like an ItemsControl.&#160; But what can we do if we want to print a DataGrid (with column headers, etc.)?&#160; Well, the CollectionPrinter doesn’t depend on being given an ItemsControl at any point.&#160; Instead, it determines pagination based upon the DesiredSize of its content after measuring/arranging.&#160; As a result, anything that grows as its bound content is changed will work with the CollectionPrinter.&#160; You can easily print a DataGrid in this way, as I’ve done below:</p>
<p><a href="http://www.davidpoll.com/Samples/SLaB/#pack://siteoforigin:,,ScratchPrintingProject.xap/ScratchPrintingProject;component/PrintingPage.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="DataGrid-based Printing" border="0" alt="DataGrid-based Printing" src="http://www.davidpoll.com/wp-content/uploads/2010/04/image2.png" width="644" height="432" /></a>And the XAML barely changes from what you see above.&#160; In this case, instead of using an ItemTemplate, I set a BodyTemplate, which is a DataGrid (with vertical scrolling disabled) with a variety of columns.&#160; In this case, I’ll specify the DataTemplates inline:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">CollectionPrinter </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">sdk</span><span style="color: blue">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk&quot;
                        </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">chartingToolkit</span><span style="color: blue">=&quot;clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit&quot;
</span><span style="color: blue">                        </span><span style="color: red">xmlns</span><span style="color: blue">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
                        </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">x</span><span style="color: blue">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
</span><span style="color: blue">                        </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">SLaB</span><span style="color: blue">=&quot;http://www.davidpoll.com/SLaB</span><span style="color: blue">&quot;&gt;
    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">CollectionPrinter.HeaderTemplate</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt; ...</span><span style="color: blue"> &lt;/</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">CollectionPrinter.HeaderTemplate</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">CollectionPrinter.FooterTemplate</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt; ...</span><span style="color: blue"> &lt;/</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">CollectionPrinter.FooterTemplate</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">CollectionPrinter.BodyTemplate</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">sdk</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">CurrentItems</span><span style="color: blue">}&quot;
                          </span><span style="color: red">AutoGenerateColumns</span><span style="color: blue">=&quot;False&quot;
                          </span><span style="color: red">VerticalScrollBarVisibility</span><span style="color: blue">=&quot;Disabled&quot;&gt;
                &lt;</span><span style="color: #a31515">sdk</span><span style="color: blue">:</span><span style="color: #a31515">DataGrid.Columns</span><span style="color: blue">&gt;
                    &lt;</span><span style="color: #a31515">sdk</span><span style="color: blue">:</span><span style="color: #a31515">DataGridTextColumn </span><span style="color: red">Binding</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Name</span><span style="color: blue">}&quot;
                                            </span><span style="color: red">Header</span><span style="color: blue">=&quot;Name&quot; /&gt;
                    &lt;</span><span style="color: #a31515">sdk</span><span style="color: blue">:</span><span style="color: #a31515">DataGridTextColumn </span><span style="color: red">Binding</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Address</span><span style="color: blue">}&quot;
                                            </span><span style="color: red">Header</span><span style="color: blue">=&quot;Address&quot; /&gt;
                    &lt;</span><span style="color: #a31515">sdk</span><span style="color: blue">:</span><span style="color: #a31515">DataGridTextColumn </span><span style="color: red">Binding</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Age</span><span style="color: blue">}&quot;
                                            </span><span style="color: red">Header</span><span style="color: blue">=&quot;Age&quot; /&gt;
                    &lt;</span><span style="color: #a31515">sdk</span><span style="color: blue">:</span><span style="color: #a31515">DataGridTemplateColumn </span><span style="color: red">Header</span><span style="color: blue">=&quot;Image&quot;
                                                </span><span style="color: red">IsReadOnly</span><span style="color: blue">=&quot;True&quot;&gt;
                        &lt;</span><span style="color: #a31515">sdk</span><span style="color: blue">:</span><span style="color: #a31515">DataGridTemplateColumn.CellTemplate</span><span style="color: blue">&gt;
                            &lt;</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
                                &lt;</span><span style="color: #a31515">Image </span><span style="color: red">Source</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Photo</span><span style="color: blue">}&quot;
                                       </span><span style="color: red">Height</span><span style="color: blue">=&quot;50&quot;
                                       </span><span style="color: red">Width</span><span style="color: blue">=&quot;50&quot; /&gt;
                            &lt;/</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
                        &lt;/</span><span style="color: #a31515">sdk</span><span style="color: blue">:</span><span style="color: #a31515">DataGridTemplateColumn.CellTemplate</span><span style="color: blue">&gt;
                    &lt;/</span><span style="color: #a31515">sdk</span><span style="color: blue">:</span><span style="color: #a31515">DataGridTemplateColumn</span><span style="color: blue">&gt;
                    &lt;</span><span style="color: #a31515">sdk</span><span style="color: blue">:</span><span style="color: #a31515">DataGridTemplateColumn </span><span style="color: red">Header</span><span style="color: blue">=&quot;Values&quot;
                                                </span><span style="color: red">Width</span><span style="color: blue">=&quot;*&quot;
                                                </span><span style="color: red">IsReadOnly</span><span style="color: blue">=&quot;True&quot;&gt;
                        &lt;</span><span style="color: #a31515">sdk</span><span style="color: blue">:</span><span style="color: #a31515">DataGridTemplateColumn.CellTemplate</span><span style="color: blue">&gt;
                            &lt;</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
                                &lt;</span><span style="color: #a31515">chartingToolkit</span><span style="color: blue">:</span><span style="color: #a31515">Chart </span><span style="color: red">Title</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Name</span><span style="color: blue">}&quot;&gt;
                                    &lt;</span><span style="color: #a31515">chartingToolkit</span><span style="color: blue">:</span><span style="color: #a31515">ScatterSeries </span><span style="color: red">DependentValuePath</span><span style="color: blue">=&quot;X&quot;
                                                                   </span><span style="color: red">IndependentValuePath</span><span style="color: blue">=&quot;Y&quot;
                                                                   </span><span style="color: red">Title</span><span style="color: blue">=&quot;Values&quot;
                                                                   </span><span style="color: red">ItemsSource</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">Values</span><span style="color: blue">}&quot; /&gt;
                                &lt;/</span><span style="color: #a31515">chartingToolkit</span><span style="color: blue">:</span><span style="color: #a31515">Chart</span><span style="color: blue">&gt;
                            &lt;/</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
                        &lt;/</span><span style="color: #a31515">sdk</span><span style="color: blue">:</span><span style="color: #a31515">DataGridTemplateColumn.CellTemplate</span><span style="color: blue">&gt;
                    &lt;/</span><span style="color: #a31515">sdk</span><span style="color: blue">:</span><span style="color: #a31515">DataGridTemplateColumn</span><span style="color: blue">&gt;
                &lt;/</span><span style="color: #a31515">sdk</span><span style="color: blue">:</span><span style="color: #a31515">DataGrid.Columns</span><span style="color: blue">&gt;
            &lt;/</span><span style="color: #a31515">sdk</span><span style="color: blue">:</span><span style="color: #a31515">DataGrid</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">CollectionPrinter.BodyTemplate</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">CollectionPrinter</span><span style="color: blue">&gt;

</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h4>Explicitly providing individual pages</h4>
<p>You can also use the CollectionPrinter for printing multiple pages explicitly (automatically dealing with all of the PrintPage callbacks, running animations, etc.) by providing a series of DataTemplates (one for each page) as the ItemsSource, changing the BodyTemplate to a ContentControl, and setting the maximum number of items to print per page to 1.&#160; For example:</p>
<p><a href="http://www.davidpoll.com/Samples/SLaB/#pack://siteoforigin:,,ScratchPrintingProject.xap/ScratchPrintingProject;component/ItemTemplatePrinting.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="Individual Pages" border="0" alt="Individual Pages" src="http://www.davidpoll.com/wp-content/uploads/2010/04/IndividualPages.png" width="644" height="419" /></a> </p>
<p>And, of course, the corresponding XAML:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">ObservableObjectCollection </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Key</span><span style="color: blue">=&quot;Pages&quot;&gt;
    &lt;</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">StackPanel</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">TextBlock </span><span style="color: red">FontWeight</span><span style="color: blue">=&quot;Bold&quot;
                        </span><span style="color: red">FontSize</span><span style="color: blue">=&quot;20&quot;&gt;</span><span style="color: #a31515">Lorem Ipsum</span><span style="color: blue">&lt;/</span><span style="color: #a31515">TextBlock</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">TextBlock </span><span style="color: red">TextWrapping</span><span style="color: blue">=&quot;Wrap&quot;
                        </span><span style="color: red">Margin</span><span style="color: blue">=&quot;10&quot;
                        </span><span style="color: red">xml</span><span style="color: blue">:</span><span style="color: red">space</span><span style="color: blue">=&quot;preserve&quot;&gt;</span><span style="color: #a31515">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ultrices cursus tortor ac egestas. Pellentesque semper lobortis enim, vel imperdiet dolor vehicula ac. Suspendisse auctor tempus molestie. Cras pulvinar sagittis libero, vel pretium ipsum consectetur sit amet. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum feugiat nunc eget ante euismod ac facilisis velit aliquet. Vestibulum eget nulla magna, eget scelerisque ligula. Cras nec nisi faucibus leo fermentum euismod eu vel lacus. Etiam lacus massa, pulvinar id tempor eget, varius at lorem. Praesent venenatis nisi ac ipsum facilisis at suscipit magna sollicitudin. Phasellus placerat imperdiet hendrerit. Nulla ac risus velit. Sed orci lorem, imperdiet vel ultrices et, viverra ut leo. Mauris feugiat, diam eget mollis tempus, est leo pellentesque risus, vitae lacinia ante felis hendrerit elit. 

Suspendisse potenti. Donec dui justo, ultrices quis condimentum vel, bibendum vel nisi. Pellentesque suscipit fermentum dui vel sodales. Nulla vitae tortor vel orci posuere vestibulum. Curabitur non lacus quam. Nulla sit amet tempor libero. Integer dictum lectus ut sem adipiscing vitae fringilla felis accumsan. Mauris ut risus felis, ut pulvinar quam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer fermentum, turpis sit amet tincidunt fermentum, metus mauris bibendum nisi, nec tincidunt purus enim nec nisi. Sed faucibus congue ultricies. Maecenas sed lorem id sem ornare imperdiet ut vitae libero. Curabitur mi diam, ornare sit amet dignissim eu, imperdiet sed nibh. Donec ultrices libero sed ipsum sollicitudin in dapibus elit rutrum. Nulla egestas tempus est, nec semper lacus sodales vel. Quisque consectetur turpis nunc, eu pretium felis. Etiam non adipiscing elit. 

Cras sit amet volutpat metus. Nunc eu augue eu urna placerat adipiscing in vel lacus. Etiam auctor orci nec dui adipiscing non viverra nisl gravida. In lacinia venenatis lobortis. Vestibulum dignissim, dolor ut feugiat ultricies, eros odio adipiscing augue, quis congue turpis augue quis mauris. Aliquam at ligula sem. Aenean eget arcu ac odio eleifend convallis. Aenean eu tellus ac eros placerat aliquam. Nam consectetur neque sed massa accumsan mollis. Pellentesque in mi erat, eget tristique elit. Praesent mattis magna sed est placerat bibendum venenatis nulla facilisis. Duis nec mollis nisi. Vestibulum et eros vitae felis vestibulum scelerisque. Donec venenatis, nulla vel rutrum tempus, purus nulla feugiat felis, eu semper diam nibh tincidunt metus. 

Praesent venenatis aliquet vulputate. In suscipit, nulla ut pulvinar ullamcorper, diam ligula sagittis enim, fermentum tempus nunc neque sed nisi. Vivamus aliquam rutrum scelerisque. Phasellus suscipit, quam sed suscipit pretium, massa nunc elementum lectus, et adipiscing arcu turpis sed dolor. Suspendisse potenti. Proin nisl mauris, sodales tincidunt ultricies sed, placerat quis enim. Nulla elementum nunc vel sapien venenatis venenatis vel eu ligula. Sed vitae erat ante. Etiam nec sapien nec sapien sagittis hendrerit. Duis at odio dolor. Sed condimentum euismod felis, ut congue dolor luctus quis. Duis non tellus enim. Quisque quis odio erat. Nulla nulla mi, dapibus ut euismod ut, adipiscing nec lacus. Aliquam faucibus dui at est accumsan ut laoreet erat pellentesque. Nullam id malesuada tellus. Donec et ligula tincidunt metus rutrum pretium. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; 

Sed lacinia dignissim scelerisque. Duis pharetra elit et nisl euismod viverra. Nam semper, purus ut luctus tincidunt, eros nisi aliquam nunc, non semper lorem enim sit amet augue. Vestibulum adipiscing tortor a magna tristique fringilla. Etiam porta volutpat odio, eu posuere velit mollis non. Mauris ut arcu quis lectus dapibus condimentum. Pellentesque non bibendum nisi. In hac habitasse platea dictumst. Maecenas laoreet lorem ut sem pellentesque id facilisis nibh pulvinar. Vivamus tempus erat placerat diam condimentum ac bibendum felis egestas. Quisque mollis hendrerit risus, ac euismod metus dapibus nec. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus quis ipsum euismod dolor pharetra viverra eget a augue. Morbi lorem enim, porta ut congue quis, pretium et enim.
            </span><span style="color: blue">&lt;/</span><span style="color: #a31515">TextBlock</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">StackPanel</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">DataTemplate</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;*&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">FontWeight</span><span style="color: blue">=&quot;Bold&quot;
                        </span><span style="color: red">FontSize</span><span style="color: blue">=&quot;20&quot;&gt;</span><span style="color: #a31515">Lorem Ipsum</span><span style="color: blue">&lt;/</span><span style="color: #a31515">TextBlock</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">Image </span><span style="color: red">Grid.Row</span><span style="color: blue">=&quot;1&quot;
                    </span><span style="color: red">HorizontalAlignment</span><span style="color: blue">=&quot;Center&quot;
                    </span><span style="color: red">VerticalAlignment</span><span style="color: blue">=&quot;Center&quot;
                    </span><span style="color: red">Source</span><span style="color: blue">=&quot;/ScratchPrintingProject;component/SLaB Logo.png&quot; /&gt;
        &lt;/</span><span style="color: #a31515">Grid</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">ObservableObjectCollection</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">Style </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Key</span><span style="color: blue">=&quot;PrintStyle&quot;
        </span><span style="color: red">TargetType</span><span style="color: blue">=&quot;SLaB:CollectionPrinter&quot;&gt;
    &lt;</span><span style="color: #a31515">Setter </span><span style="color: red">Property</span><span style="color: blue">=&quot;MaximumItemsPerPage&quot;
            </span><span style="color: red">Value</span><span style="color: blue">=&quot;1&quot; /&gt;
    &lt;</span><span style="color: #a31515">Setter </span><span style="color: red">Property</span><span style="color: blue">=&quot;BodyTemplate&quot;&gt;
        &lt;</span><span style="color: #a31515">Setter.Value</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">ContentControl </span><span style="color: red">ContentTemplate</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">CurrentItems</span><span style="color: blue">[</span>0<span style="color: blue">]}&quot;
                                </span><span style="color: red">HorizontalContentAlignment</span><span style="color: blue">=&quot;Stretch&quot;
                                </span><span style="color: red">VerticalContentAlignment</span><span style="color: blue">=&quot;Stretch&quot; /&gt;
            &lt;/</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">Setter.Value</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">Setter</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">Setter </span><span style="color: red">Property</span><span style="color: blue">=&quot;HeaderTemplate&quot;&gt;
        &lt;</span><span style="color: #a31515">Setter.Value</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt; ...</span><span style="color: blue"> &lt;/</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">Setter.Value</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">Setter</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">Style</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">CollectionPrinter </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;printer&quot;
                        </span><span style="color: red">ItemsSource</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">Pages</span><span style="color: blue">}&quot;
                        </span><span style="color: red">Style</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">PrintStyle</span><span style="color: blue">}&quot; /&gt;
</span></pre>
<p>Above, I have two pages: one with a bunch of text, and one with a large image on it.&#160; I still get all of the context for my headers/footers, and can use this as a way to get the benefits of using the CollectionPrinter without being locked into an ItemsControl-like behavior.</p>
<h3></h3>
<h3></h3>
<h4>Headers and Footers</h4>
<p>Creating Headers and Footers for each page is also really easy with the CollectionPrinter – just specify a HeaderTemplate or a FooterTemplate.&#160; These DataTemplates are bound to the CollectionPrintContext, which you can use to generate your header and footer info.&#160; I use some ValueConverters (in one of the SLaB libraries, if you’d like to reuse them) to conditionalize Visibility of a title for a document to the first page, and to change colors/text for the other pages.&#160; I also use the FirstItemValue/LastItemValue to provide a “Aa – Aardvark” (like you’d find in a dictionary) footer on each page.</p>
<p>For example, the sample pages above use the following XAML for their header/footers:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">CollectionPrinter.HeaderTemplate</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">StackPanel </span><span style="color: red">HorizontalAlignment</span><span style="color: blue">=&quot;Stretch&quot;&gt;
            &lt;</span><span style="color: #a31515">StackPanel.Resources</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">BoolConverter </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Key</span><span style="color: blue">=&quot;BoolConverter&quot; /&gt;
            &lt;/</span><span style="color: #a31515">StackPanel.Resources</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">StackPanel </span><span style="color: red">HorizontalAlignment</span><span style="color: blue">=&quot;Right&quot;
                        </span><span style="color: red">Orientation</span><span style="color: blue">=&quot;Horizontal&quot;&gt;
                &lt;</span><span style="color: #a31515">TextBlock </span><span style="color: red">Text</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">CurrentPage</span><span style="color: blue">, </span><span style="color: red">StringFormat</span><span style="color: blue">='{}Page {0} '}&quot; /&gt;
                &lt;</span><span style="color: #a31515">TextBlock </span><span style="color: red">Text</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">PageCount</span><span style="color: blue">, </span><span style="color: red">StringFormat</span><span style="color: blue">='{}/ {0}'}&quot; /&gt;
            &lt;/</span><span style="color: #a31515">StackPanel</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">TextBlock </span><span style="color: red">HorizontalAlignment</span><span style="color: blue">=&quot;Center&quot;
                        </span><span style="color: red">Visibility</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">IsFirstPage</span><span style="color: blue">, </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;
                        </span><span style="color: red">FontSize</span><span style="color: blue">=&quot;32&quot;&gt;</span><span style="color: #a31515">This is a test document!</span><span style="color: blue">&lt;/</span><span style="color: #a31515">TextBlock</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">TextBlock </span><span style="color: red">HorizontalAlignment</span><span style="color: blue">=&quot;Center&quot;
                        </span><span style="color: red">Visibility</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">IsLastPage</span><span style="color: blue">, </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;
                        </span><span style="color: red">FontSize</span><span style="color: blue">=&quot;16&quot;&gt;</span><span style="color: #a31515">This is the last page!</span><span style="color: blue">&lt;/</span><span style="color: #a31515">TextBlock</span><span style="color: blue">&gt;
            &lt;</span><span style="color: #a31515">TextBlock </span><span style="color: red">HorizontalAlignment</span><span style="color: blue">=&quot;Center&quot;
                        </span><span style="color: red">FontSize</span><span style="color: blue">=&quot;14&quot;&gt;
                &lt;</span><span style="color: #a31515">TextBlock.Foreground</span><span style="color: blue">&gt;
                    &lt;</span><span style="color: #a31515">Binding </span><span style="color: red">Path</span><span style="color: blue">=&quot;CurrentPage&quot;&gt;
                        &lt;</span><span style="color: #a31515">Binding.Converter</span><span style="color: blue">&gt;
                            &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">EvenOddConverter</span><span style="color: blue">&gt;
                                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">EvenOddConverter.Even</span><span style="color: blue">&gt;
                                    &lt;</span><span style="color: #a31515">SolidColorBrush </span><span style="color: red">Color</span><span style="color: blue">=&quot;Blue&quot; /&gt;
                                &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">EvenOddConverter.Even</span><span style="color: blue">&gt;
                                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">EvenOddConverter.Odd</span><span style="color: blue">&gt;
                                    &lt;</span><span style="color: #a31515">SolidColorBrush </span><span style="color: red">Color</span><span style="color: blue">=&quot;Red&quot; /&gt;
                                &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">EvenOddConverter.Odd</span><span style="color: blue">&gt;
                            &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">EvenOddConverter</span><span style="color: blue">&gt;
                        &lt;/</span><span style="color: #a31515">Binding.Converter</span><span style="color: blue">&gt;
                    &lt;/</span><span style="color: #a31515">Binding</span><span style="color: blue">&gt;
                &lt;/</span><span style="color: #a31515">TextBlock.Foreground</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">TextBlock.Text</span><span style="color: blue">&gt;
                    &lt;</span><span style="color: #a31515">Binding </span><span style="color: red">Path</span><span style="color: blue">=&quot;CurrentPage&quot;
                                </span><span style="color: red">StringFormat</span><span style="color: blue">=&quot;This page is {0}&quot;&gt;
                        &lt;</span><span style="color: #a31515">Binding.Converter</span><span style="color: blue">&gt;
                            &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">EvenOddConverter</span><span style="color: blue">&gt;
                                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">EvenOddConverter.Even</span><span style="color: blue">&gt;
                                    </span><span style="color: #a31515">Even
                                </span><span style="color: blue">&lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">EvenOddConverter.Even</span><span style="color: blue">&gt;
                                &lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">EvenOddConverter.Odd</span><span style="color: blue">&gt;
                                    </span><span style="color: #a31515">Odd
                                </span><span style="color: blue">&lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">EvenOddConverter.Odd</span><span style="color: blue">&gt;
                            &lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">EvenOddConverter</span><span style="color: blue">&gt;
                        &lt;/</span><span style="color: #a31515">Binding.Converter</span><span style="color: blue">&gt;
                    &lt;/</span><span style="color: #a31515">Binding</span><span style="color: blue">&gt;
                &lt;/</span><span style="color: #a31515">TextBlock.Text</span><span style="color: blue">&gt;
            &lt;/</span><span style="color: #a31515">TextBlock</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">StackPanel</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">CollectionPrinter.HeaderTemplate</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">CollectionPrinter.FooterTemplate</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">StackPanel </span><span style="color: red">HorizontalAlignment</span><span style="color: blue">=&quot;Center&quot;
                    </span><span style="color: red">Orientation</span><span style="color: blue">=&quot;Horizontal&quot;&gt;
            &lt;</span><span style="color: #a31515">TextBlock </span><span style="color: red">Text</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">FirstItemValue</span><span style="color: blue">.Name}&quot; /&gt;
            &lt;</span><span style="color: #a31515">TextBlock </span><span style="color: red">Text</span><span style="color: blue">=&quot; - &quot; /&gt;
            &lt;</span><span style="color: #a31515">TextBlock </span><span style="color: red">Text</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding </span><span style="color: red">LastItemValue</span><span style="color: blue">.Name}&quot; /&gt;
        &lt;/</span><span style="color: #a31515">StackPanel</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">CollectionPrinter.FooterTemplate</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Nifty, isn’t it? <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>That’s a lot of XAML!&#160; Do I have to write all of that by hand?</h3>
<p>Of course not!&#160; In fact, with the CollectionPrinter, Blend gives you a nice little print preview (especially if you use it as the root of a XAML file) and lets you modify the various templates directly in Blend, inline with the rest of the page!&#160; You can adjust the “CurrentPageIndex” property to preview your CollectionPrinter configuration in the designer.</p>
<p><a href="http://www.davidpoll.com/wp-content/uploads/2010/04/image3.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="Editing templates within Blend" border="0" alt="Editing templates within Blend" src="http://www.davidpoll.com/wp-content/uploads/2010/04/image_thumb.png" width="644" height="386" /></a> </p>
<p>To accomplish this in Blend:</p>
<ul>
<li>Select a CollectionPrinter on the designer (either making it the root of a XAML document or selecting it in your existing XAML) </li>
<li>Right-click the CollectionPrinter in the Objects and Timeline Window </li>
<li>Choose “Edit Additional Templates” </li>
<li>Choose a template to edit, and either edit a copy, edit the current template, or create an empty template. </li>
<li>Edit away!&#160; Drag/drop your printed content! </li>
</ul>
<h3></h3>
<h3>So, what’s it all add up to?</h3>
<p>It’s very common for business applications to want to print the data they’ve collected, and it’s not hard to see how that might be a chore.&#160; Silverlight 4 introduced the printing feature, which allows printing at a very low level, but it also allows a huge amount of freedom in determining exactly what gets rendered to the page.&#160; This freedom can make simple printing tasks a chore.&#160; My hope is that the CollectionPrinter helps demonstrate how one might build a general-purpose (but more constrained than the built-in API) printing API.&#160; I’d love to know what you think.&#160; For me, it was primarily an experiment to see how close I could come to making printing large data sets easy and designable.&#160; Does this come close to what you’d hope for?&#160; What would your ideal be?</p>
<h3>Sweet!&#160; Can I try it?!</h3>
<p>I’m glad you’re so enthused!&#160; I’m tempted to say no, but wouldn’t torture you like that <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .&#160; You can give it a shot using my latest build of <a href="http://www.davidpoll.com/downloads-and-samples/#SLaB">Silverlight and Beyond</a>.</p>
<p>You can see the live demos here (Requires Silverlight 4):</p>
<p><a href="http://www.davidpoll.com/Samples/SLaB/#/Views/SitemapPage.xaml?sitemapname=PrintingSitemap"><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="Printing samples" border="0" alt="Printing samples" src="http://www.davidpoll.com/wp-content/uploads/2010/04/image4.png" width="644" height="432" /></a></p>
<p>If you’d like to save time printing (yeah, it takes a while – it renders some pretty large bitmaps!), you can see some sample output files below.&#160; Notice that the “Long” documents don’t have the total page count displayed, since it took longer to pre-render all of the pages than the PrintPage retry limit would permit:</p>
<ul>
<li>ItemTemplate-based Document – <a href="http://www.davidpoll.com/Samples/Download/Short%20Template-based%20Document.pdf">Short</a> (PDF 7.5 MB), <a href="http://www.davidpoll.com/Samples/Download/Long%20Template-based%20Document.pdf">Long</a> (PDF 37.7 MB) </li>
<li>DataGrid-based Document – <a href="http://www.davidpoll.com/Samples/Download/Short%20DataGrid%20Document.pdf">Short</a> (PDF 7.9 MB), <a href="http://www.davidpoll.com/Samples/Download/Long%20DataGrid%20Document.pdf">Long</a> (PDF 37.0 MB) </li>
<li>Individual page-based Document – <a href="http://www.davidpoll.com/Samples/Download/Short%20Document.pdf">Download</a> (PDF 5.8 MB) </li>
</ul>
<p>Finally, some source code for you:</p>
<li><a href="http://www.davidpoll.com/Samples/SLaB/#/Views/SitemapPage.xaml?sitemapname=PrintingSitemap">Live Sample</a> (<a href="http://www.davidpoll.com/Download/SLaB/SLaBv0.5.zip">source &#8212; found in the SLaB v0.5 source under &quot;ScratchPrintingProject&quot;</a>) </li>
<p><a href="http://www.davidpoll.com/Download/SLaB/SLaBv0.5.zip">SLaB v0.5</a> (includes source, a sample app, some tests, and binaries) </p>
<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.5 download of SLaB includes the following changes:
<ul>
<li>Updated for SL4 RTW </li>
<li>Added CollectionPrinter for printing collections of items </li>
<li>Fixed a bug with Sitemap-based controls that caused some pack Uris to be evaluated as &quot;equivalent&quot; (and thus highlighted) even when they were not </li>
<li>Added EvenOddConverter that allows you to select an arbitrary value based on whether the input value was even or odd </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>
<h3>P.S. Do you know you talk to yourself in these blog posts?</h3>
<p>Yes, yes I do, Mr. “Person behind the headers of the sections in my blog posts who is actually me.”&#160; </p>
<p>&#160;</p>
<p><strong><em><u>UPDATE 4/25/2010:</u></em></strong> Thanks for the feedback in the comments on this post.&#160; I have updated the CollectionPrinter to help with the DataGrid AutoGenerateColumns issue reported by “mb”.&#160; It may still have problems if the ItemsSource is not an IEnumerable&lt;T&gt; (but rather just a plain IEnumerable), but I think this should cover the 90% case.</p>
<p>You can download the newest bits <a href="http://www.davidpoll.com/Download/SLaB/SLaBv0.6.zip">here</a>.&#160; I also added a nice little utility method to SLaB that helps get a MethodInfo using a compiled Expression (using the LINQ expression libraries).&#160; Please let me know if you encounter other issues!</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2010/04/16/making-printing-easier-in-silverlight-4/feed/</wfw:commentRss>
		<slash:comments>111</slash:comments>
		</item>
		<item>
		<title>Silverlight 4 Released!</title>
		<link>http://www.davidpoll.com/2010/04/15/silverlight-4-released/</link>
		<comments>http://www.davidpoll.com/2010/04/15/silverlight-4-released/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 01:38:48 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Silverlight 4]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2010/04/15/silverlight-4-released/</guid>
		<description><![CDATA[It’s an exciting day in Silverlight land!&#160; Today, Silverlight 4 was released, along with tools for working with it in Visual Studio 2010 and an RC of Blend 4! You can pick up the runtime and tools here! I’ve got lots of ideas for upcoming posts, and will be updating my beta/RC samples to run [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>It’s an exciting day in Silverlight land!&#160; Today, Silverlight 4 was released, along with tools for working with it in Visual Studio 2010 and an RC of Blend 4!</p>
<p>You can pick up the runtime and tools <a href="http://www.silverlight.net/getstarted/silverlight-4/">here</a>!</p>
<p>I’ve got lots of ideas for upcoming posts, and will be updating my beta/RC samples to run with the release version of Silverlight soon.</p>
<p>Happy coding!</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2010/04/15/silverlight-4-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New in the Silverlight 4 RC: XAML Features</title>
		<link>http://www.davidpoll.com/2010/03/15/new-in-the-silverlight-4-rc-xaml-features/</link>
		<comments>http://www.davidpoll.com/2010/03/15/new-in-the-silverlight-4-rc-xaml-features/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 00:58:35 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Silverlight 4]]></category>
		<category><![CDATA[Silverlight 4 RC]]></category>
		<category><![CDATA[Silverlight and Beyond (SLaB)]]></category>
		<category><![CDATA[Silverlight Toolkit]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2010/03/15/new-in-the-silverlight-4-rc-xaml-features/</guid>
		<description><![CDATA[Today, the Silverlight 4 RC was announced and made available to the masses.&#160; But you may be asking yourself: what’s new since the beta?&#160; Well, I’d like to dive into one of the areas where a bunch of new work was done to improve the development experience – the XAML Parser.&#160; With Silverlight 4, we’ve [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>Today, the <a href="http://www.silverlight.net/getstarted/silverlight-4/">Silverlight 4 RC</a> was announced and made available to the masses.&#160; But you may be asking yourself: what’s new since the beta?&#160; Well, I’d like to dive into one of the areas where a bunch of new work was done to improve the development experience – the XAML Parser.&#160; With Silverlight 4, we’ve done a significant overhaul of the XAML Parser, allowing us to add new features and improve consistency within the platform and with WPF’s XAML support.</p>
<p>So, let’s take a quick walk through some of the new things you can do with Silverlight XAML as of the RC!&#160; This is by no means an exhaustive list, but it’s definitely some of the bigger items.</p>
<h3>Direct Content</h3>
<p>This is one of those small inconsistencies with WPF that people hit almost immediately when they try to write Silverlight XAML after moving over from the WPF world.&#160; Specifically, things like this now work in Silverlight:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">Button</span><span style="color: blue">&gt;</span><span style="color: #a31515">Click me!</span><span style="color: blue">&lt;/</span><span style="color: #a31515">Button</span><span style="color: blue">&gt;
</span></pre>
<p>I know, I know – exciting, right!?&#160; In Silverlight 3, you had to use attribute syntax or explicitly surround “Click Me!” in a string, like this:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">Button </span><span style="color: red">Content</span><span style="color: blue">=&quot;Click me!&quot; /&gt;
</span></pre>
<p>or…</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">Button </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">sys</span><span style="color: blue">=&quot;clr-namespace:System;assembly=mscorlib&quot;&gt;
    &lt;</span><span style="color: #a31515">sys</span><span style="color: blue">:</span><span style="color: #a31515">String</span><span style="color: blue">&gt;</span><span style="color: #a31515">Click me!</span><span style="color: blue">&lt;/</span><span style="color: #a31515">sys</span><span style="color: blue">:</span><span style="color: #a31515">String</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">Button</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>I know when I first made the move from WPF to Silverlight, this was among the most irksome and frustrating things about its XAML parser.&#160; With Silverlight 4, that frustration is gone, and I can enjoy direct content in my controls once again!</p>
<p>See the image below for more examples:</p>
<p><a href="http://www.davidpoll.com/wp-content/uploads/2010/03/image3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="A quick demo of direct content support in Silverlight 4 XAML." border="0" alt="A quick demo of direct content support in Silverlight 4 XAML." src="http://www.davidpoll.com/wp-content/uploads/2010/03/image_thumb3.png" width="644" height="437" /></a> </p>
<h3></h3>
<h3>xml:space=”preserve”</h3>
<p>In previous versions of Silverlight, the XAML parser was rather liberal about how it applied whitespace.&#160; In general, it didn’t discard extra whitespace as most XML parsers will.</p>
<p>For example, the following XAML:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">TextBlock</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">TextBlock.Text</span><span style="color: blue">&gt;</span><span style="color: #a31515">This
Text
Is
On
Separate
Lines
    </span><span style="color: blue">&lt;/</span><span style="color: #a31515">TextBlock.Text</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">TextBlock</span><span style="color: blue">&gt;
</span></pre>
<p>Looked like this:</p>
<p><a href="http://www.davidpoll.com/wp-content/uploads/2010/03/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Whitespace preservation in prior versions of Silverlight." border="0" alt="Whitespace preservation in prior versions of Silverlight." src="http://www.davidpoll.com/wp-content/uploads/2010/03/image_thumb1.png" width="67" height="104" /></a> </p>
<p>The XAML parser in Silverlight 4 has finally corrected this behavior, and has also added support for xml:space=”preserve”.</p>
<p>When you recompile your application with the Silverlight 4 RC, the same XAML will produce the following:</p>
<p><a href="http://www.davidpoll.com/wp-content/uploads/2010/03/image2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.davidpoll.com/wp-content/uploads/2010/03/image_thumb2.png" width="179" height="20" /></a>&#160;</p>
<p>To get back the old behavior, add xml:space=”preserve” to your XAML:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">TextBlock </span><span style="color: red">xml</span><span style="color: blue">:</span><span style="color: red">space</span><span style="color: blue">=&quot;preserve&quot;&gt;
    &lt;</span><span style="color: #a31515">TextBlock.Text</span><span style="color: blue">&gt;</span><span style="color: #a31515">This
Text
Is
On
Separate
Lines
    </span><span style="color: blue">&lt;/</span><span style="color: #a31515">TextBlock.Text</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">TextBlock</span><span style="color: blue">&gt;
</span></pre>
<p>Finally, you have control over your whitespace back!&#160; The results are much more predictable, and you can now be explicit about what you want the text content to be.</p>
<p><strong>Please note:</strong> when you upgrade your application to Silverlight 4 (i.e. recompile for Silverlight 4), you’ll need to watch out for this change!</p>
<h3>ISupportInitialize</h3>
<p>If you were a fan of the <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.isupportinitialize.aspx">ISupportInitialize</a> interface in the full framework, it’s finally made its way into Silverlight!&#160; The XAML parser in Silverlight will now call ISupportInitialize.BeginInit() and ISupportInitialize.EndInit() on your classes (if you implement the interface) before and after setting properties defined in XAML.&#160; This allows you to wait to do work until after all of your properties have been set, allowing you to handle properties that would otherwise be order-dependent and add some validation that combinations of properties are valid.</p>
<p>It’s a convenient and welcome functionality to have around, especially for those of us that like declarative programming and are happy to use XAML as our format for doing so!</p>
<h3>XmlnsDefinition attribute</h3>
<p>In Silverlight 3 and earlier, how many times did you find yourself in a situation like this?</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">UserControl </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Class</span><span style="color: blue">=&quot;SilverlightApplication1.MainPage&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">x</span><span style="color: blue">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">d</span><span style="color: blue">=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">mc</span><span style="color: blue">=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">controls</span><span style="color: blue">=&quot;clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">data</span><span style="color: blue">=&quot;clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">input</span><span style="color: blue">=&quot;clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">navigationMappings</span><span style="color: blue">=&quot;clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">navigation</span><span style="color: blue">=&quot;clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">ohmygoshtherearetoomanyofthese</span><span style="color: blue">=&quot;clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data&quot;
             </span><span style="color: red">mc</span><span style="color: blue">:</span><span style="color: red">Ignorable</span><span style="color: blue">=&quot;d&quot;
             </span><span style="color: red">d</span><span style="color: blue">:</span><span style="color: red">DesignHeight</span><span style="color: blue">=&quot;300&quot;
             </span><span style="color: red">d</span><span style="color: blue">:</span><span style="color: red">DesignWidth</span><span style="color: blue">=&quot;400&quot;&gt;...
</span></pre>
<p>And that’s just with some of the SDK assemblies!&#160; Declaring xmlns’s in your XAML was a chore, and it was extremely easy to end up with a huge mess of them, as they require one definition per namespace/assembly.&#160; Add in the toolkit controls and any custom libraries, and you’re easily looking at 20 lines of these definitions.&#160; This is more than just a problem of convenience – it makes XAML intellisense a big problem as well.&#160; Visual Studio starts its intellisense experience by waiting for an xmlns to be entered, such as “input:”.&#160; Within that namespace, it will filter your options to valid tags for your context within the XAML.</p>
<p>But, if you’re like me and like to break your libraries up into small pieces, this is not very helpful – I have to remember exactly which xmlns has which set of things that derives from the type I’m trying to create in XAML, and if I got it wrong, there’s not much there to help me.</p>
<p>Silverlight 4 adds support for the <a href="http://msdn.microsoft.com/en-us/library/system.windows.markup.xmlnsdefinitionattribute.aspx">XmlnsDefinitionAttribute</a> in custom assemblies, and the SDK has been updated to take advantage of this.&#160; Now, you can replace all of the code above with this:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">UserControl </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Class</span><span style="color: blue">=&quot;SilverlightApplication1.MainPage&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">x</span><span style="color: blue">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">d</span><span style="color: blue">=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">mc</span><span style="color: blue">=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
             </span><strong><em><u><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">sdk</span></u></em></strong><span style="color: blue"><strong><em><u>=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk&quot;</u></em></strong>
             </span><span style="color: red">mc</span><span style="color: blue">:</span><span style="color: red">Ignorable</span><span style="color: blue">=&quot;d&quot;
             </span><span style="color: red">d</span><span style="color: blue">:</span><span style="color: red">DesignHeight</span><span style="color: blue">=&quot;300&quot;
             </span><span style="color: red">d</span><span style="color: blue">:</span><span style="color: red">DesignWidth</span><span style="color: blue">=&quot;400&quot;&gt;</span><span style="color: #a31515">...
</span></pre>
<p>Likewise, with the next update of the <a href="http://silverlight.codeplex.com">Silverlight Toolkit</a>, you will likely see a similar change, allowing you access to all referenced toolkit controls from one xmlns!&#160; Phew!&#160; What a relief!</p>
<p>With that in mind, I’ve also updated <a href="http://www.davidpoll.com/downloads-and-samples/#SLaB">SLaB</a> to use XmlnsDefinitionAttribute, which really helps clean up the use of those libraries with Silverlight 4.</p>
<p>This is one of my favorite features, if only because it makes working with XAML <em>so</em> much simpler in Visual Studio, and now it’s available for you and other control/XAML-centric developers to use in your libraries as well!</p>
<h3></h3>
<h3>Xmlns flexibility</h3>
<p>Silverlight 3 required that your default namespace always be the following:</p>
<pre class="code"><span style="color: red">xmlns</span><span style="color: blue">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
</span></pre>
<p>This was sometimes irritating when you wanted to use XAML as a serialization format for something other than UI, since you had to preface every element with some other xmlns.&#160; In Silverlight 4, you can now change the default xmlns namespace at will, which you can use to clean up your XAML and customize your serialization format as you wish.</p>
<h3></h3>
<h3>Custom IDictionary support</h3>
<p>In XAML, it’s supposed to be possible to add items to a dictionary just as you would a list by using the “x:Key” attribute.&#160; In prior versions of Silverlight, the only case where this was allowed was when used inside of a ResourceDictionary.</p>
<p>With Silverlight 4, anything that implements IDictionary can be used in XAML.&#160; To this end, I’ve provided a simple BindableDictionary in my SLaB libraries that you can now use like so (although you could just as easily use a Dictionary&lt;object, SomeType&gt; or a custom implementation of IDictionary):</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">BindableDictionary </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Key</span><span style="color: blue">=&quot;ValueBag&quot;
                                </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">sys</span><span style="color: blue">=&quot;clr-namespace:System;assembly=mscorlib&quot;&gt;
    &lt;</span><span style="color: #a31515">sys</span><span style="color: blue">:</span><span style="color: #a31515">Double </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Key</span><span style="color: blue">=&quot;Value Between Zero and 100&quot;&gt;</span><span style="color: #a31515">37.9184273</span><span style="color: blue">&lt;/</span><span style="color: #a31515">sys</span><span style="color: blue">:</span><span style="color: #a31515">Double</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">sys</span><span style="color: blue">:</span><span style="color: #a31515">Boolean </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Key</span><span style="color: blue">=&quot;A boolean&quot;&gt;</span><span style="color: #a31515">True</span><span style="color: blue">&lt;/</span><span style="color: #a31515">sys</span><span style="color: blue">:</span><span style="color: #a31515">Boolean</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">SLaB</span><span style="color: blue">:</span><span style="color: #a31515">BindableDictionary</span><span style="color: blue">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>This is extremely useful for more complex XAML scenarios where you want a Dictionary rather than a List to be declared in XAML.&#160; One example I’ve been wanting to play with: an INavigationContentLoader (it’s an obsession – I’m sick, I know <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ) that maps a protocol (e.g. http:// or pack://) to another INavigationContentLoader, allowing protocol-specific content loading within a single application.</p>
<h3></h3>
<h3>Non-DependencyProperty Attached Properties</h3>
<p>Although you’re probably used to seeing them as such, attached properties are actually completely separate from DependencyProperties (just as properties are distinct from DependencyProperties).&#160; In order to style or bind to them, they must be DependencyProperties.&#160; Otherwise, it’s just an API convention:</p>
<pre class="code"><span style="color: blue">using </span>System.Collections.Generic;
<span style="color: blue">using </span>System.Windows.Controls;

<span style="color: blue">namespace </span>SilverlightApplication1
{
    <span style="color: blue">public class </span><span style="color: #2b91af">ClassWithAttachedProperty
    </span>{
        <span style="color: blue">private static </span><span style="color: #2b91af">Dictionary</span>&lt;<span style="color: #2b91af">Grid</span>, <span style="color: blue">int</span>&gt; values = <span style="color: blue">new </span><span style="color: #2b91af">Dictionary</span>&lt;<span style="color: #2b91af">Grid</span>, <span style="color: blue">int</span>&gt;();
        <span style="color: blue">public static int </span>GetGridMetadata(<span style="color: #2b91af">Grid </span>g)
        {
            <span style="color: blue">return </span>values[g];
        }
        <span style="color: blue">public static void </span>SetGridMetadata(<span style="color: #2b91af">Grid </span>g, <span style="color: blue">int </span>someValue)
        {
            values[g] = someValue;
        }
    }
}</pre>
<p>Which can then be used in XAML like so:</p>
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">UserControl </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Class</span><span style="color: blue">=&quot;SilverlightApplication1.MainPage&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">x</span><span style="color: blue">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
             </span><span style="color: red">xmlns</span><span style="color: blue">:</span><span style="color: red">my</span><span style="color: blue">=&quot;clr-namespace:SilverlightApplication1&quot;&gt;
    &lt;</span><span style="color: #a31515">Grid </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Name</span><span style="color: blue">=&quot;LayoutRoot&quot; </span><strong><em><u><span style="color: red">my</span><span style="color: blue">:</span><span style="color: red">ClassWithAttachedProperty.GridMetadata</span></u></em></strong><span style="color: blue"><strong><em><u>=&quot;150&quot;</u></em></strong>&gt;
    &lt;/</span><span style="color: #a31515">Grid</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">UserControl</span><span style="color: blue">&gt;
</span></pre>
<p><strong>Note:</strong> I don’t recommend keeping a dictionary of Grid—&gt;int around <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .&#160; That’s a giant memory leak waiting to happen!&#160; It’s just convenient for demonstrative purposes.</p>
<h3>Better error messages</h3>
<p>One of the biggest complaints about XAML in Silverlight has been its poor reporting of errors when you’ve done something wrong.&#160; This should have significantly improved in Silverlight 4.&#160; In general, you’ll get more context and much clearer error messages at runtime when you make a mistake in XAML.&#160; In general, that feeling of “what the heck just happened?” should be lifting when it comes to working with XAML.&#160; It’s still not perfect, but things have improved significantly.</p>
<h3></h3>
<h3>Wow, that’s a lot of stuff!</h3>
<p>Yep, there’s been plenty of change with the parser, and the improvements should lead to a better experience when doing declarative development using XAML in Silverlight!&#160; Please let me know what you think!&#160; What’s your favorite feature or biggest peeve?</p>
<h3>What about SLaB?</h3>
<p>I’ve updated SLaB for the Silverlight 4 RC.&#160; There’s a bunch of new stuff in there that I hope to blog about soon.&#160; In the meantime, here’s a snippet from the changelog:</p>
<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 <a href="http://www.davidpoll.com/Download/SLaB/SLaBv0.4.zip">v0.4 download</a> of SLaB includes the following changes:
<ul>
<li>Added ZipUtilities so that the contents of a zip file can be discovered </li>
<li>Updated XapLoader to use ZipUtilities, allowing all TPEs to work rather than being limited to single-file TPEs where the file is named the same as the zip </li>
<li>Added Sitemap-based controls: BreadCrumbNavigator and TreeViewNavigator </li>
<li>Added ChangeLinq libraries for working with INotifyCollectionChanged collections and LINQ </li>
<li>Added ObservableDictionary and BindableDictionary, which raise INotifyCollectionChanged and INotifyPropertyChanged events as the dictionary changes, making it more usable with Binding </li>
<li>Added a basic MEFContentLoader </li>
<li>Updated to use XmlnsDefinitionAttribute wherever possible </li>
<li>Added XmlnsDefinition attributes to all libraries and updated ScratchApplication to use them </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 class="wp-smiley" alt=":)" src="http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif" /> .</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2010/03/15/new-in-the-silverlight-4-rc-xaml-features/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Silverlight 4 RC Announced at MIX 2010!</title>
		<link>http://www.davidpoll.com/2010/03/15/silverlight-4-rc-announced-at-mix-2010/</link>
		<comments>http://www.davidpoll.com/2010/03/15/silverlight-4-rc-announced-at-mix-2010/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 17:24:32 +0000</pubDate>
		<dc:creator>david.poll</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[MIX '10]]></category>
		<category><![CDATA[Silverlight 4]]></category>
		<category><![CDATA[Silverlight 4 RC]]></category>

		<guid isPermaLink="false">http://www.davidpoll.com/2010/03/15/silverlight-4-rc-announced-at-mix-2010/</guid>
		<description><![CDATA[If you’re not watching already, head on over to http://live.visitmix.com to watch the keynote, where Scott Guthrie has just announced the Silverlight 4 RC! So, for those of you who’ve been wondering where I’ve been with my blog for the last month, now you know .&#160; There’s lots to look forward to, and I’ll be [...]]]></description>
			<content:encoded><![CDATA[<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_start --><p>If you’re not watching already, head on over to <a href="http://live.visitmix.com">http://live.visitmix.com</a> to watch the keynote, where <a href="http://weblogs.asp.net/scottgu/">Scott Guthrie</a> has just announced the Silverlight 4 RC!</p>
<p>So, for those of you who’ve been wondering where I’ve been with my blog for the last month, now you know <img src='http://www.davidpoll.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .&#160; There’s lots to look forward to, and I’ll be talking about some of what’s new and different in the Silverlight 4 RC soon.</p>
<p>In the meantime, you can grab the bits here:&#160; <a title="http://www.silverlight.net/getstarted/silverlight-4/" href="http://www.silverlight.net/getstarted/silverlight-4/">http://www.silverlight.net/getstarted/silverlight-4/</a></p>
<p>It’s all very exciting!&#160; Stay tuned for more!</p>
<!-- Advanced AdSense by Jim Gaudet --><!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.davidpoll.com/2010/03/15/silverlight-4-rc-announced-at-mix-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

