<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.rightpoint.com/community/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Viewpoint : Silverlight</title><link>http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Silverlight/default.aspx</link><description>Tags: Silverlight</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Debug Build: 31106.3070)</generator><item><title>How to use Silverlight Pivot Viewer with SharePoint Lists</title><link>http://www.rightpoint.com/community/blogs/viewpoint/archive/2011/09/01/using-silverlight-pivot-viewer-with-sharepoint-lists.aspx</link><pubDate>Thu, 01 Sep 2011 20:20:00 GMT</pubDate><guid isPermaLink="false">f7450ba4-a08e-465a-831a-f9a15c21b696:2879</guid><dc:creator>Steve Samnadda</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.rightpoint.com/community/blogs/viewpoint/rsscomments.aspx?PostID=2879</wfw:commentRss><comments>http://www.rightpoint.com/community/blogs/viewpoint/archive/2011/09/01/using-silverlight-pivot-viewer-with-sharepoint-lists.aspx#comments</comments><description>&lt;p&gt;The Internet provides us with an ever-increasing amount of information.&amp;nbsp; Despite this fact, most people are still not very good at multi-tasking.&amp;nbsp; Unlike a computer, human context-switching&amp;nbsp;wastes a tremendous&amp;nbsp;amount of time and energy.&amp;nbsp; As a result we have become better at filtering out the information we choose to spend our time on.&amp;nbsp;&amp;nbsp;For instance,&amp;nbsp;a typical person only revisits about 6-7 websites on a daily basis.&amp;nbsp; And when browsing the web a typical user spends less than&amp;nbsp;one minute on each site.&lt;/p&gt;
&lt;p&gt;For that reason, when designing websites with large amounts of data it is necessary to present that information in such a way that users can quickly find and consume the items they are looking for.&amp;nbsp; (Remember you have less than 60 seconds!)&lt;/p&gt;
&lt;p&gt;&lt;a target="_blank" href="http://www.silverlight.net/learn/data-networking/pivot-viewer/pivotviewer-control"&gt;Microsoft&amp;#39;s Pivot Viewer Control&lt;/a&gt; uses Silverlight to provide faceted searches in a fluid and visually appealing manner.&amp;nbsp; This tool has tremondous potential for running searches of any kind.&amp;nbsp;Deep Zoom Image technology allows high-resolution images to represent each search item.&amp;nbsp; And faceted search items can be selected, sort, and reshaped in very quick, intuitive manner.&lt;/p&gt;
&lt;p&gt;There are several great examples on the web already using Microsoft Pivot Viewer (&lt;a target="_blank" href="http://netflixpivot.cloudapp.net/"&gt;Netflix&lt;/a&gt;, &lt;a target="_blank" href="http://www.hitched.co.uk/wedding-venues/visual-search.htm"&gt;Hitched&lt;/a&gt;, &lt;a target="_blank" href="http://memorabilia.hardrock.com/"&gt;Hard Rock&lt;/a&gt;, &lt;a target="_blank" href="http://visualize.sfmoma.org/EmbarkPivot/"&gt;SFMOMA&lt;/a&gt;).&amp;nbsp; Also, there are class libraries (&lt;a target="_blank" href="http://www.silverlight.net/archives/whitepapers/deep-zoom-tools"&gt;Deep Zoom Tools&lt;/a&gt;, &lt;a target="_blank" href="http://geekswithblogs.net/tkokke/archive/2010/08/17/runtime-pivotviewer-collection-creation.aspx"&gt;Pivot Server Tools&lt;/a&gt;) available to&amp;nbsp;dynamically generate the&amp;nbsp;images and supporting&amp;nbsp;xml needed to&amp;nbsp;feed this control.&amp;nbsp;&amp;nbsp;These tools run well on a computer or off an normal ASP.NET application with direct access to the hard drive.&amp;nbsp; But how easy would it be to integrate this control with Microsoft&amp;#39;s premier platform for business intelligence, document management, and collaboration: SharePoint.&amp;nbsp; The answer was not the easy, especially generating Deep Zoom Images from SharePoint.&amp;nbsp; Once we figured out how to map these files the result was &lt;span style="text-decoration:underline;"&gt;rock-solid&lt;/span&gt; search tool for our team sites.&lt;/p&gt;
&lt;p&gt;For our purposes, we wanted to use the Pivot Viewer to search team sites based on metadata associated with that site&amp;rsquo;s purpose.&amp;nbsp; Our metadata&amp;nbsp; was specific to the project: Country, Department, Created Date, Keywords.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Screenshots below:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.rightpoint.com/community/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/viewpoint/screenshot2.jpg"&gt;&lt;img src="http://www.rightpoint.com/community/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/viewpoint/screenshot2.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href="http://www.rightpoint.com/community/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/viewpoint/screenshot1.jpg"&gt;&lt;img src="http://www.rightpoint.com/community/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/viewpoint/screenshot1.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;There were four main components used to make the Pivot Viewer work with SharePoint&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Landing Page Site &amp;ndash; This site is the parent to each or our team sites. It contains the following lists and pages: 
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Sites&amp;rdquo; list &amp;ndash; This list is used to auto-create team sites and track metadata within them&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Site Images&amp;rdquo; list &amp;ndash; Contains images associated with each team site&lt;/li&gt;
&lt;li&gt;&amp;ldquo;XAP library&amp;rdquo; &amp;ndash; Document library used to store PivotViewer.xap.&lt;/li&gt;
&lt;li&gt;Search.aspx -&amp;nbsp; Search page with a Content Editor with Silverlight &amp;lt;object&amp;gt; tag&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Sites.cxml &amp;ndash; This is an XML file is passed in as a parameter to PivotViewer.xap.&amp;nbsp; It is generated from the &amp;quot;Sites&amp;quot; list and contains a listing of all our team sites and the metadata or &amp;ldquo;facets&amp;rdquo; associated with each team site.&amp;nbsp; An event receiver is attached to the &amp;ldquo;Sites&amp;rdquo; list to generate this file any time a metadata column is updated.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;dzc_output.xml &amp;ndash; A catalog of all images uploaded to &amp;ldquo;Site Images&amp;rdquo; list.&amp;nbsp; Each image is assigned an id# that is referenced by an item inside Site.cxml.&lt;/li&gt;
&lt;li&gt;Deep Zoom Tiles &amp;ndash; Each image added to &amp;ldquo;Site Images&amp;rdquo; fires an event receiver to process the photo into Deep Zoom Tiles.&amp;nbsp; Deep zoom tiles allow for a quick initial load time and the ability to quickly zoom very deep into an image.&amp;nbsp; This is achieved by creating a &amp;lsquo;pyramid&amp;rsquo; of images where each level of the pyramid is written to a folder and contains successively more slices of the photos at higher zoom levels.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;So between the &amp;ldquo;Sites&amp;rdquo;&amp;nbsp;metadata&amp;nbsp;and &amp;ldquo;Site Images&amp;rdquo; lists and their respective event handlers there is everything needed to generate a Pivot View.&amp;nbsp; There is a specific folder structure that these files should be contained in (which is all &lt;a target="_blank" href="http://www.silverlight.net/learn/data-networking/pivot-viewer/pivotviewer-control"&gt;documented&lt;/a&gt;).&amp;nbsp; Instead of explaining that, I will go straight into the technical challenges involved in generating these files programmatically.&lt;/p&gt;
&lt;p&gt;Overview: Deep Zoom Tools (&lt;a target="_blank" href="http://www.silverlight.net/archives/whitepapers/deep-zoom-tools"&gt;documentation&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;DeepZoomTools handles writing dzc_output.xml and each corresponding image tile using the ImageCreator and CollectionCreator classes.&amp;nbsp; The biggest challenge was getting DeepZoomTools.dll to write file to an SPFile stream instead of to the hard drive.&amp;nbsp; The filenames would always correspond to local path while we wanted to write to a SharePoint folder.&amp;nbsp; Luckily, their are many events we can attach to before and after a file stream request is being made.&amp;nbsp; At this point we can supplant the filestream with a memorystream of our own making&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration:underline;"&gt;First Issue - Switching the stream dz&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="text-decoration:underline;"&gt;c_output_images&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We overrode the OutputNeeded event to translate the filename, ensure the proper SharePoint folder/file exists, and create a MemoryStream to write.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.rightpoint.com/community/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/viewpoint/screenshot3.jpg"&gt;&lt;img src="http://www.rightpoint.com/community/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/viewpoint/screenshot3.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then overrode the OutputCompleted event to stuff the resulting file from the MemoryStream into a SPFile.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href="http://www.rightpoint.com/community/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/viewpoint/screenshot4.jpg"&gt;&lt;img src="http://www.rightpoint.com/community/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/viewpoint/screenshot4.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The magic happens with PrepFilename method which converts a local path file to the Sharepoint file we want:&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;&lt;a href="http://www.rightpoint.com/community/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/viewpoint/screenshot5.jpg"&gt;&lt;img src="http://www.rightpoint.com/community/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/viewpoint/screenshot5.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;Examples&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;source&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;file:///c:/windows/system32/inetsrv/dzc_output_images/ourimage.xml&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;destination&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;/sites/Projects/DeepZoomImages/SiteImages/dzc_output_images/ourimage.xml &lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;source&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;c:\windows\system32\inetsrv\dzc_output_images\ourimage_files\0\0_0.png&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;destination&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;/sites/sis/projects/deepzoomimages/projectimages/dzc_output_images/ourimage_files/0/0_0.png&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration:underline;"&gt;Second Issue - Switching the stream dzc_output.xml&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The dzc_output.xml is a catalog of all the images created during the last step.&amp;nbsp; It was easy enough to tell it what to generate but when it actually came time to write it wasn&amp;#39;t as simple as the solution in the first issue.&amp;nbsp; This time the Collection Creator Wrapper was entirely disposing of the file before we had a chance to write to it.&amp;nbsp; To solve this issue we overrode the MemoryStream class, attached an event to the Dispose event and handled it in our code to get the contents of the XML.&amp;nbsp; Problem&amp;nbsp; solved!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href="http://www.rightpoint.com/community/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/viewpoint/screenshot6.jpg"&gt;&lt;img src="http://www.rightpoint.com/community/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/viewpoint/screenshot6.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;&lt;strong&gt;Third Issue - Creating the Faceted Search Collection&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Oh this wasn&amp;#39;t really an issue.&amp;nbsp; Thanks to &lt;a target="_blank" href="http://geekswithblogs.net/tkokke/archive/2010/08/17/runtime-pivotviewer-collection-creation.aspx"&gt;PivotServerTools&lt;/a&gt;, we just passed in the data and it did all the work for us.&amp;nbsp; OK, there may have been some more wiring needed, but we can&amp;#39;t give up all our secrets. ;)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.rightpoint.com/community/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/viewpoint/Screenshot7.jpg"&gt;&lt;img src="http://www.rightpoint.com/community/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/viewpoint/Screenshot7.jpg" border="0" alt="" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Kidding!&amp;nbsp; If anyone would like some more details on implementation just shoot us an email!&lt;/p&gt;
&lt;p&gt;Cheers.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.rightpoint.com/community/aggbug.aspx?PostID=2879" width="1" height="1"&gt;</description><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/SharePoint/default.aspx">SharePoint</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/search/default.aspx">search</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Silverlight/default.aspx">Silverlight</category></item><item><title>Getting Silverlight Drag And Drop Support For FireFox 5 On A Mac</title><link>http://www.rightpoint.com/community/blogs/viewpoint/archive/2011/08/10/getting-silverlight-drag-and-drop-support-for-firefox-5-on-a-mac.aspx</link><pubDate>Wed, 10 Aug 2011 22:33:00 GMT</pubDate><guid isPermaLink="false">f7450ba4-a08e-465a-831a-f9a15c21b696:2872</guid><dc:creator>Chris Domino</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.rightpoint.com/community/blogs/viewpoint/rsscomments.aspx?PostID=2872</wfw:commentRss><comments>http://www.rightpoint.com/community/blogs/viewpoint/archive/2011/08/10/getting-silverlight-drag-and-drop-support-for-firefox-5-on-a-mac.aspx#comments</comments><description>&lt;p class="Text"&gt;I&amp;#39;ve been working on a massive cross browser, cross platform Silverlight application for the last year or so. One of the major components is file drag and drop (heretofore D&amp;amp;D, not to of course be confused with Dungeons and Dragons). Getting this to work on Windows is trivial, and there are myriad resources out there to get you started. However, over on the Mac, things were much more difficult. &lt;/p&gt;
&lt;p class="Text"&gt;FireFox wasn&amp;#39;t actually too bad, but Safari required us to wire up some JavaScript to help convince the browser to pass the dropped file&amp;#39;s bits along to Silverlight. But all-in-all, when we were done, I felt that it was still pretty amazing that we had D&amp;amp;D working in Silverlight cross-platform with what turned out to be a lot less effort than I expected. &lt;/p&gt;
&lt;p class="Text"&gt;Our app went into beta, and the Mac users immediately started logging bugs about D&amp;amp;D not working on FireFox. So we dusted off our test Mac, and everything seemed fine. The disconnect turned out to be, after some quick investigation, a version conflict. We were running one of the last builds of FireFox 3; the users were all on 5 (if you recall, version 5 came out rather quickly after 4 shipped). &lt;/p&gt;
&lt;p class="Text"&gt;So we upgraded, and quickly saw the problem: although &lt;span class="Italic"&gt;drag&lt;/span&gt; still worked, &lt;span class="Italic"&gt;drop&lt;/span&gt; was completely dead. FireFox version 4 and up had broken support for Silverlight D&amp;amp;D (or, technically, just the second D). And I use the term &amp;quot;support&amp;quot; loosely because official backing from Microsoft wasn&amp;#39;t really there. (It was kind of like Silverlight 4 &amp;quot;not supporting&amp;quot; Chrome, although it works just fine.) &lt;/p&gt;
&lt;p class="Text"&gt;What I want to discuss here is how to get Silverlight D&amp;amp;D working on Macs running FireFox 5. &lt;/p&gt;
&lt;p class="Text"&gt;We went the full nine yards when we built our Silverlight D&amp;amp;D infrastructure: using a Silverlight &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/ff726531(Expression.40).aspx" class="Link"&gt;Behavior&lt;/a&gt; for the infrastructure that allowed us to attach the functionality to any &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.uielement(v=VS.95).aspx" class="Link"&gt;UIElement&lt;/a&gt;. It used a &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.visualstatemanager%28v=VS.95%29.aspx" class="Link"&gt;VisualStateManager&lt;/a&gt; to provide cues to the user that a dragged file could be dropped at that particular area (by &amp;quot;lighting&amp;quot; up the text and animating a glowing &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.media.effects.dropshadoweffect(v=VS.95).aspx" class="Link"&gt;DropShadow&lt;/a&gt; around the boarder). Additionally, we had a cursor control that hid the mouse pointer and showed different images in its place that provided additional visual indications where D&amp;amp;D was enabled. Finally, a static helper class provided common functionality, such as flags to track if we were dragging and if a drop action, based on the current cursor location, was possible. &lt;/p&gt;
&lt;p class="Text"&gt;Check out my colleague &lt;a target="_blank" href="http://www.rightpoint.com/community/blogs/viewpoint/archive/2011/03/27/silverlight-4-file-drag-and-drop-on-firefox-on-mac.aspx" class="Link"&gt;Jonathan Rupp&amp;#39;s post&lt;/a&gt; on how he got us this far. I&amp;#39;m going to take the next step here and get our Silverlight D&amp;amp;D logic working for FireFox 5 on a Mac. The basic approach is to leverage the fact that drag still works, and use a combination of HTML 5, the Silverlight HTML bridge, and jQuery to basically &amp;quot;fake&amp;quot; a drop. Do read Jonathan&amp;#39;s post, as I&amp;#39;ll be referring to the code he presents. &lt;/p&gt;
&lt;p class="Text"&gt;The idea is to use Silverlight&amp;#39;s ability to still subscribe to the drag events raised by FireFox 5 on a Mac to position a transparent div over the drop zone, wire up HTML 5 drop events on it, handle the file processing in JavaScript, and then pass the raw data back to Silverlight. I know that I just presented like half a dozen different technologies in that one sentence, so let&amp;#39;s break the procedure down step by step. &lt;/p&gt;
&lt;p class="Text"&gt;The first thing to do is create a div in the ASPX page that hosts our Silverlight control. This is what we&amp;#39;ll be using as our drop surface; there&amp;#39;s nothing too special about it (yet): &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;div&lt;/span&gt;&lt;span class="ClassName"&gt; id&lt;/span&gt;&lt;span class="Operator"&gt;=&amp;quot;&lt;/span&gt;divDropSurface&lt;span class="Operator"&gt;&amp;quot;&lt;/span&gt; &lt;span class="ClassName"&gt;style&lt;/span&gt;&lt;span class="Operator"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="StyleName"&gt;background&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt; transparent&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;span class="StyleName"&gt; z-index&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt; 50&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;span class="StyleName"&gt; position&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt; absolute&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;span class="StyleName"&gt; top&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt; 0px&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;span class="StyleName"&gt; left&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt; 0px&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;span class="StyleName"&gt; width&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt; 0px&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;span class="StyleName"&gt; height&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt; 0px&lt;span class="Operator"&gt;;&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;As you can tell, the styling implies that this div will be absolutely positioned and dimensioned to cover a certain portion of the screen. One thing to note: this technique will only work on a Mac, where Silverlight automatically sets the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc838156(v=VS.95).aspx" class="Link"&gt;windowless&lt;/a&gt; mode to true, allowing the Silverlight region to participate in HTML Z-indexing. If you set windowless to true on a PC, you&amp;#39;ll break D&amp;amp;DN altogether, as well as introduce some performance hits. I wrote more about this &lt;a target="_blank" href="http://chrisdomino.com/blog/post/Silverlight-IsWindowless-ness-And-How-You-Don-t-Need-It-To-Display-Flash" class="Link"&gt;here&lt;/a&gt;. &lt;/p&gt;
&lt;p class="Text"&gt;Next we need to hook up the HTML 5 D&amp;amp;D events on our drop surface. Call the following method in jQuery&amp;#39;s &lt;a target="_blank" href="http://docs.jquery.com/Tutorials:Introducing_%24%28document%29.ready%28%29" class="Link"&gt;document ready&lt;/a&gt; event: &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;function&lt;/span&gt; HookFFDropEvents&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//ff on mac&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;window&lt;span class="Operator"&gt;.&lt;/span&gt;navigator&lt;span class="Operator"&gt;.&lt;/span&gt;userAgent&lt;span class="Operator"&gt;.&lt;/span&gt;indexOf&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;Mac OS&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="Operator"&gt;=&lt;/span&gt; 0 &lt;span class="Operator"&gt;&amp;amp;&lt;/span&gt;&lt;span class="Operator"&gt;&amp;amp;&lt;/span&gt; $&lt;span class="Operator"&gt;.&lt;/span&gt;browser&lt;span class="Operator"&gt;.&lt;/span&gt;mozilla&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//get drop surface&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;var&lt;/span&gt; ds &lt;span class="Operator"&gt;=&lt;/span&gt; document&lt;span class="Operator"&gt;.&lt;/span&gt;getElementById&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;divDropSurface&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//hook D&amp;amp;D events&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;ds&lt;span class="Operator"&gt;.&lt;/span&gt;addEventListener&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;drop&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; FFDrop&lt;span class="Operator"&gt;,&lt;/span&gt;&lt;span class="Keyword"&gt; false&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;ds&lt;span class="Operator"&gt;.&lt;/span&gt;addEventListener&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;dragenter&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; FFDragEnter&lt;span class="Operator"&gt;,&lt;/span&gt;&lt;span class="Keyword"&gt; false&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;ds&lt;span class="Operator"&gt;.&lt;/span&gt;addEventListener&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;dragleave&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; FFDragLeave&lt;span class="Operator"&gt;,&lt;/span&gt;&lt;span class="Keyword"&gt; false&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;ds&lt;span class="Operator"&gt;.&lt;/span&gt;addEventListener&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;dragover&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; FFClearEvent&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;false&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;We&amp;#39;ll talk about the FFDragLeave and FFDrop methods later. FFDragEnter is not used (but will be, I&amp;#39;m sure, if FireFox 6 breaks drag as well). FFClearEvent is the standard JavaScript that blocks the browser&amp;#39;s default handling of a file drop and allows the code on the page to handle it. &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;function&lt;/span&gt; FFClearEvent&lt;span class="Operator"&gt;(&lt;/span&gt;e&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//override the browser&amp;#39;s default behavior for file drops&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;e&lt;span class="Operator"&gt;.&lt;/span&gt;stopPropagation&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;e&lt;span class="Operator"&gt;.&lt;/span&gt;preventDefault&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;The next step is to position this div directly on top of a particular area of your Silverlight control when a drag is detected. (Recall that in Silverlight, you hook drag events on a particular UIElement, not the entire application.) Our Silverlight D&amp;amp;D behavior keeps a reference to the UIElement that it&amp;#39;s supporting. So when a file is being dragged over a valid drop zone, an event is fired that basically updates the VisualStateManager for that UIElement. What I added to this was logic to get the HTML coordinates of this UIElement, and position our drop surface div over it. &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//determine if we are on mac on FF5&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;FileDragDropHelper&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;IsMacFF5&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//get the drop target and the drop surfce&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;Control&lt;/span&gt; target &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;GetCurrentDNDBehavior&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Target&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;HtmlElement&lt;/span&gt; element &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;HtmlPage&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Document&lt;span class="Operator"&gt;.&lt;/span&gt;GetElementById&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;divDropSurface&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;element &lt;span class="Operator"&gt;!&lt;/span&gt;&lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//set flag to indicate that we&amp;#39;re currently dragging&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;FileDragDropHelper&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;IsHovered &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;true&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//position drop surface over drop target&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;Point&lt;/span&gt; position &lt;span class="Operator"&gt;=&lt;/span&gt; target&lt;span class="Operator"&gt;.&lt;/span&gt;TransformToVisual&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Transform&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;Point&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;element&lt;span class="Operator"&gt;.&lt;/span&gt;SetStyleAttribute&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;top&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Concat&lt;span class="Operator"&gt;(&lt;/span&gt;position&lt;span class="Operator"&gt;.&lt;/span&gt;Y&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;px&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;element&lt;span class="Operator"&gt;.&lt;/span&gt;SetStyleAttribute&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;left&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Concat&lt;span class="Operator"&gt;(&lt;/span&gt;position&lt;span class="Operator"&gt;.&lt;/span&gt;X&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;px&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;element&lt;span class="Operator"&gt;.&lt;/span&gt;SetStyleAttribute&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;width&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Concat&lt;span class="Operator"&gt;(&lt;/span&gt;target&lt;span class="Operator"&gt;.&lt;/span&gt;ActualWidth&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;px&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;element&lt;span class="Operator"&gt;.&lt;/span&gt;SetStyleAttribute&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;height&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Concat&lt;span class="Operator"&gt;(&lt;/span&gt;target&lt;span class="Operator"&gt;.&lt;/span&gt;ActualHeight&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;px&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;The flag in Line #2 is maintained in the aforementioned D&amp;amp;D helper utility. Line #5 is another helper method that takes in the current mouse position (gotten from the drag event), gets the UIElement at that location, and grabs the associated behavior (made possible by the gluey nature of attached properties). Everything else is pretty straight forward, utilizing the beauty of the Silverlight HTML bridge. &lt;/p&gt;
&lt;p class="Text"&gt;Now if the user were to release the mouse button, the drop would happen. But before we drop, we need to handle the case were the user drags &lt;span class="Italic"&gt;off&lt;/span&gt; the control without dropping. This interaction is important, as it not only mimics what our D&amp;amp;D behavior is doing for us automatically in other environments, but can be reused upon a drop (since the UI needs to be reset properly). &lt;/p&gt;
&lt;p class="Text"&gt;First, we create a hidden HTML button that will be used to facilitate communication from JavaScript to Silverlight. &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;input&lt;/span&gt;&lt;span class="ClassName"&gt; type&lt;/span&gt;&lt;span class="Operator"&gt;=&amp;quot;&lt;/span&gt;button&lt;span class="Operator"&gt;&amp;quot;&lt;/span&gt;&lt;span class="ClassName"&gt; id&lt;/span&gt;&lt;span class="Operator"&gt;=&amp;quot;&lt;/span&gt;hidFileDropInfo&lt;span class="Operator"&gt;&amp;quot;&lt;/span&gt; &lt;span class="ClassName"&gt;style&lt;/span&gt;&lt;span class="Operator"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="StyleName"&gt;display&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt; none&lt;span class="Operator"&gt;;&amp;quot;&lt;/span&gt; &lt;span class="Operator"&gt;/&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;Then we hook its click event in Silverlight (as part of the behavior). &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;HtmlPage&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Document&lt;span class="Operator"&gt;.&lt;/span&gt;GetElementById&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;hidFileDropInfo&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;AttachEvent&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; HandleFileReceived&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;We&amp;#39;ll see what HandleFileReceived looks like in a bit. First, let&amp;#39;s revisit the FFDragLeave JavaScript method. &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;function&lt;/span&gt; FFDragLeave&lt;span class="Operator"&gt;(&lt;/span&gt;e&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//reset our button, telling silverlight to update the UI that we&amp;#39;re no longer over a drop surface&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;$&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;#hidFileDropInfo&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;val&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;CLEAR&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;click&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;We&amp;#39;re using the Silverlight HTML bridge and jQuery chaining to set the value of the hidden HTML button to &amp;quot;CLEAR&amp;quot; and then click it. That click event will be handled in Silverlight by the aforementioned HandleFileReceived method, which we&amp;#39;re still not quite ready to discuss. First, let&amp;#39;s talk about the drop workflow. &lt;/p&gt;
&lt;p class="Text"&gt;While the drop surface is positioned over the drop zone, Silverlight won&amp;#39;t be receiving any mouse input. But that&amp;#39;s okay, since the visual state won&amp;#39;t need to change until the drop surface receives either a drag leave or a drop event. We&amp;#39;ve covered what happens in the former case, so without further ado, let&amp;#39;s talk about drop. &lt;/p&gt;
&lt;p class="Text"&gt;Here&amp;#39;s the FFDrop method in all its glory: &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//globals&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;var&lt;/span&gt; _xml&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;var&lt;/span&gt; _fileCounter&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;function&lt;/span&gt; FFDrop&lt;span class="Operator"&gt;(&lt;/span&gt;e&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//override the browser&amp;#39;s default behavior for file drops&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;FFClearEvent&lt;span class="Operator"&gt;(&lt;/span&gt;e&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//get files&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;var&lt;/span&gt; files &lt;span class="Operator"&gt;=&lt;/span&gt; e&lt;span class="Operator"&gt;.&lt;/span&gt;dataTransfer&lt;span class="Operator"&gt;.&lt;/span&gt;files&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;typeof&lt;/span&gt; files &lt;span class="Operator"&gt;=&lt;/span&gt;&lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;undefined&amp;quot;&lt;/span&gt; &lt;span class="Operator"&gt;|&lt;/span&gt;&lt;span class="Operator"&gt;|&lt;/span&gt; files&lt;span class="Operator"&gt;.&lt;/span&gt;length &lt;span class="Operator"&gt;=&lt;/span&gt;&lt;span class="Operator"&gt;=&lt;/span&gt; 0&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//initialize global variables&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;_xml &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;&amp;lt;files&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;_fileCounter &lt;span class="Operator"&gt;=&lt;/span&gt; files&lt;span class="Operator"&gt;.&lt;/span&gt;length&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//process each file&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;for&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;var&lt;/span&gt; n &lt;span class="Operator"&gt;=&lt;/span&gt; 0&lt;span class="Operator"&gt;;&lt;/span&gt; n &lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt; files&lt;span class="Operator"&gt;.&lt;/span&gt;length&lt;span class="Operator"&gt;;&lt;/span&gt; n&lt;span class="Operator"&gt;+&lt;/span&gt;&lt;span class="Operator"&gt;+&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;ProcessFile&lt;span class="Operator"&gt;(&lt;/span&gt;files&lt;span class="Operator"&gt;[&lt;/span&gt;n&lt;span class="Operator"&gt;]&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;The idea is to get the HTML 5 drop event metadata, process each file, and build up some XML that acts as a data contract between JavaScript and Silverlight. Lines #13 and #14 initialize the _xml global variable to the root node of our XML markup, and _fileCounter to the number of dropped files. &lt;/p&gt;
&lt;p class="Text"&gt;Most of the magic happens in ProcessFile, which follows. &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;function&lt;/span&gt; ProcessFile&lt;span class="Operator"&gt;(&lt;/span&gt;file&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//create reader&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;var&lt;/span&gt; reader &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;new&lt;/span&gt; FileReader&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//client side error handling&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;reader&lt;span class="Operator"&gt;.&lt;/span&gt;onerror &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;function&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;error&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//determine error&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;switch&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;error&lt;span class="Operator"&gt;.&lt;/span&gt;target&lt;span class="Operator"&gt;.&lt;/span&gt;error&lt;span class="Operator"&gt;.&lt;/span&gt;code&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//show appropriate error&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;case&lt;/span&gt; 1&lt;span class="Operator"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;alert&lt;span class="Operator"&gt;(&lt;/span&gt;file&lt;span class="Operator"&gt;.&lt;/span&gt;name &lt;span class="Operator"&gt;+&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot; was not found.&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;break&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;case&lt;/span&gt; 2&lt;span class="Operator"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;alert&lt;span class="Operator"&gt;(&lt;/span&gt;file&lt;span class="Operator"&gt;.&lt;/span&gt;name &lt;span class="Operator"&gt;+&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot; has been modified since it was dropped.&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;break&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;case&lt;/span&gt; 3&lt;span class="Operator"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;alert&lt;span class="Operator"&gt;(&lt;/span&gt;file&lt;span class="Operator"&gt;.&lt;/span&gt;name &lt;span class="Operator"&gt;+&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot; has been cancelled.&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;break&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;case&lt;/span&gt; 4&lt;span class="Operator"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;alert&lt;span class="Operator"&gt;(&lt;/span&gt;file&lt;span class="Operator"&gt;.&lt;/span&gt;name &lt;span class="Operator"&gt;+&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot; could not be read.&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;break&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;case&lt;/span&gt; 5&lt;span class="Operator"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;alert&lt;span class="Operator"&gt;(&lt;/span&gt;file&lt;span class="Operator"&gt;.&lt;/span&gt;name &lt;span class="Operator"&gt;+&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot; is too large.&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;break&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//read data&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;reader&lt;span class="Operator"&gt;.&lt;/span&gt;readAsDataURL&lt;span class="Operator"&gt;(&lt;/span&gt;file&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;reader&lt;span class="Operator"&gt;.&lt;/span&gt;onloadend &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;function&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;dropped&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//get raw data from file&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;var&lt;/span&gt; data &lt;span class="Operator"&gt;=&lt;/span&gt; dropped&lt;span class="Operator"&gt;.&lt;/span&gt;target&lt;span class="Operator"&gt;.&lt;/span&gt;result&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;data&lt;span class="Operator"&gt;.&lt;/span&gt;length &lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt; 128&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//build xml representation of each file&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;_xml &lt;span class="Operator"&gt;=&lt;/span&gt; _xml &lt;span class="Operator"&gt;+&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;&amp;lt;file&amp;gt;&amp;lt;name&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class="Operator"&gt;+&lt;/span&gt; file&lt;span class="Operator"&gt;.&lt;/span&gt;name &lt;span class="Operator"&gt;+&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;&amp;lt;/name&amp;gt;&amp;lt;size&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class="Operator"&gt;+&lt;/span&gt; file&lt;span class="Operator"&gt;.&lt;/span&gt;size &lt;span class="Operator"&gt;+&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;&amp;lt;/size&amp;gt;&amp;lt;data&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class="Operator"&gt;+&lt;/span&gt; data &lt;span class="Operator"&gt;+&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;&amp;lt;/data&amp;gt;&amp;lt;/file&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//decrement the counter...&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;_fileCounter&lt;span class="Operator"&gt;-&lt;/span&gt;&lt;span class="Operator"&gt;-&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//...and when there are no more files to upload...&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;_fileCounter &lt;span class="Operator"&gt;=&lt;/span&gt;&lt;span class="Operator"&gt;=&lt;/span&gt; 0&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//...close the xml...&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;_xml &lt;span class="Operator"&gt;=&lt;/span&gt; _xml &lt;span class="Operator"&gt;+&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;&amp;lt;/files&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//...and send it to silverlight&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;$&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;#hidFileDropInfo&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;val&lt;span class="Operator"&gt;(&lt;/span&gt;_xml&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;click&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//error&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;alert&lt;span class="Operator"&gt;(&lt;/span&gt;file&lt;span class="Operator"&gt;.&lt;/span&gt;name &lt;span class="Operator"&gt;+&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot; has invalid data. It may be corrupted.&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;In Line #4, we new up an HTML 5 &lt;a target="_blank" href="http://www.w3.org/TR/FileAPI/" class="Link"&gt;FileReader&lt;/a&gt;, which when fed the metadata of a drop event, gives us a nice OO representation of a file. The error event is hooked in Line #6, and processing is done according W3C protocol. Line #&amp;#39;s 30 and 31 load the file; the fact that this is an asynchronous process is what forces us to use global variables. In Line #38, we build the XML representation of the file array we&amp;#39;re going to be passing to Silverlight. The _fileCounter variable is decremented in Line #40 each time a file is successfully collected, so that the check in Line #42 can determine if all asynchronous operations have completed, the XML can be capped off, and finally be sent to Silverlight via the aforementioned bridge-and-change method in Line #47. &lt;/p&gt;
&lt;p class="Text"&gt;So we have both our drag leave and our drop methods setting the value of a hidden HTML button and then clicking it. The click event is handled by Silverlight, and deals with both cases. &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;private&lt;/span&gt; &lt;span class="Keyword"&gt;void&lt;/span&gt; HandleFileReceived&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;object&lt;/span&gt; sender&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;HtmlEventArgs&lt;/span&gt; args&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//initialization&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;FileDragDropHelper&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;IsHovered &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;false&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;string&lt;/span&gt; &lt;span class="Keyword"&gt;value&lt;/span&gt; &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;HtmlPage&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Document&lt;span class="Operator"&gt;.&lt;/span&gt;GetElementById&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;hidFileDropInfo&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;GetProperty&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;value&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;ToString&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//get value&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;string&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;IsNullOrEmpty&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;value&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;|&lt;/span&gt;&lt;span class="Operator"&gt;|&lt;/span&gt; &lt;span class="Keyword"&gt;value&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Equals&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;CLEAR&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//process a reset&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;HtmlElement&lt;/span&gt; element &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;HtmlPage&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Document&lt;span class="Operator"&gt;.&lt;/span&gt;GetElementById&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;divDropSurface&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;element &lt;span class="Operator"&gt;!&lt;/span&gt;&lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//reset drop surface&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;element&lt;span class="Operator"&gt;.&lt;/span&gt;SetStyleAttribute&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;top&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;0px&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;element&lt;span class="Operator"&gt;.&lt;/span&gt;SetStyleAttribute&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;left&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;0px&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;element&lt;span class="Operator"&gt;.&lt;/span&gt;SetStyleAttribute&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;width&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;0px&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;element&lt;span class="Operator"&gt;.&lt;/span&gt;SetStyleAttribute&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;height&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;0px&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//build xml doc to hold D&amp;amp;D raw data&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;XDocument&lt;/span&gt; doc &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;XDocument&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Load&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;StringReader&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;value&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;List&lt;/span&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ClassName"&gt;FileDragDropHelper&lt;span class="Operator"&gt;.&lt;/span&gt;DroppedFileWrapper&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt; files &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;List&lt;/span&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ClassName"&gt;FileDragDropHelper&lt;span class="Operator"&gt;.&lt;/span&gt;DroppedFileWrapper&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//iterate all dropped files...&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;foreach&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;XElement&lt;/span&gt; node &lt;span class="Keyword"&gt;in&lt;/span&gt; doc&lt;span class="Operator"&gt;.&lt;/span&gt;Root&lt;span class="Operator"&gt;.&lt;/span&gt;Nodes&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//...and poor-man deserialize them&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;List&lt;/span&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ClassName"&gt;XElement&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt; nodes &lt;span class="Operator"&gt;=&lt;/span&gt; node&lt;span class="Operator"&gt;.&lt;/span&gt;Nodes&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Cast&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ClassName"&gt;XElement&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;ToList&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;string&lt;/span&gt; name &lt;span class="Operator"&gt;=&lt;/span&gt; nodes&lt;span class="Operator"&gt;[&lt;/span&gt;0&lt;span class="Operator"&gt;]&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Value&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;long&lt;/span&gt; size &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;Convert&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;ToInt64&lt;span class="Operator"&gt;(&lt;/span&gt;nodes&lt;span class="Operator"&gt;[&lt;/span&gt;1&lt;span class="Operator"&gt;]&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Value&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//strip heading off of base64 file header data&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;string&lt;/span&gt; data &lt;span class="Operator"&gt;=&lt;/span&gt; nodes&lt;span class="Operator"&gt;[&lt;/span&gt;2&lt;span class="Operator"&gt;]&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Value&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;data &lt;span class="Operator"&gt;=&lt;/span&gt; data&lt;span class="Operator"&gt;.&lt;/span&gt;Substring&lt;span class="Operator"&gt;(&lt;/span&gt;data&lt;span class="Operator"&gt;.&lt;/span&gt;IndexOfThatDoesntBreakMacs&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;;base64,&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;+&lt;/span&gt; 8&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//collect files&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;files&lt;span class="Operator"&gt;.&lt;/span&gt;Add&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;FileDragDropHelper&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;DroppedFileWrapper&lt;span class="Operator"&gt;(&lt;/span&gt;name&lt;span class="Operator"&gt;,&lt;/span&gt; size&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;Convert&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;FromBase64String&lt;span class="Operator"&gt;(&lt;/span&gt;data&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//pass file along to behavior&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;var&lt;/span&gt; b &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;GetCurrentDNDBehavior&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;b &lt;span class="Operator"&gt;!&lt;/span&gt;&lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;b&lt;span class="Operator"&gt;.&lt;/span&gt;OnDrop&lt;span class="Operator"&gt;(&lt;/span&gt;files&lt;span class="Operator"&gt;.&lt;/span&gt;ToArray&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;catch&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Exception&lt;/span&gt; ex&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//error&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;MessageBox&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Show&lt;span class="Operator"&gt;(&lt;/span&gt;ex&lt;span class="Operator"&gt;.&lt;/span&gt;ToString&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;finally&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//pass drag leave to the rest of the D&amp;amp;D infrastructure&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;DoLeave&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;FileDragDropHelper&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;DoHangledDragLeave&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;Once again, Line #41 gets the D&amp;amp;D behavior, and fires the drop event (with the files) on the target UIElement. Line #7 determines if this is a &amp;quot;CLEAR&amp;quot; event (in which case the drop surface is hidden) or if this is an actual drop. Drag leave still works normally in FireFox 5 on a Mac, so the behavior itself can update the VisualStateManager and reset any &amp;quot;dragging&amp;quot; flags in either case. The rest is not too exciting: Line #31 builds an &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.aspx" class="Link"&gt;XDocument&lt;/a&gt; from the raw XML and iterates the child &amp;quot;file&amp;quot; nodes. It then pulls out the file name and size properties, as well as converts the data from a base64 string to a byte array, and feeds it to our DroppedFileWrapper DTO (which is a wrapper around a &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.io.fileinfo(v=VS.95).aspx" class="Link"&gt;FileInfo&lt;/a&gt; object). &lt;/p&gt;
&lt;p class="Text"&gt;If time allowed, this would have all been baked into our behavior and done proper: implementing XML deserialization for the file bits, not using buttons to pass data around, and generally less piece-wising these technologies together. But with the timeline I had, the complexity of the solution, and the existing infrastructure it had to fit into, (which itself was already quite complex due to cross-browser, cross-platform Silverlight D&amp;amp;D support) this is how it was born. &lt;/p&gt;
&lt;p class="Text"&gt;To summarize, if you&amp;#39;re not using a behavior or any other existing D&amp;amp;D implementation, here&amp;#39;s what you need to do to get Silverlight D&amp;amp;D working in FireFox 5 on a Mac: &lt;/p&gt;
&lt;p class="Text"&gt;&lt;ol class="Text"&gt;
&lt;li class="Text"&gt;Create a &amp;quot;hidden&amp;quot; (no length or width and positioned at 0,0) absolutely-positioned div to act as a drop surface.&lt;/li&gt;
&lt;li class="Text"&gt;Wire up the HTML 5 D&amp;amp;D events on the drop surface.&lt;/li&gt;
&lt;li class="Text"&gt;Position it over the &amp;quot;drop zone&amp;quot; (the Silverlight UIElement to be dropped onto) when it&amp;#39;s dragged over.&lt;/li&gt;
&lt;li class="Text"&gt;Use HTML 5 JavaScript to process the drop event and read each file.&lt;/li&gt;
&lt;li class="Text"&gt;Pass the raw data to Silverlight.&lt;/li&gt;
&lt;li class="Text"&gt;&amp;quot;Hide&amp;quot; the drop surface (remove its length and width and reposition to 0,0) after the drop or upon the drop surface&amp;#39;s drag leave event.&lt;/li&gt;
&lt;/ol&gt;&lt;/p&gt;
&lt;p class="Text"&gt;And there you have it: Silverlight drag and drop in FireFox 5 on a Mac. Have fun! &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.rightpoint.com/community/aggbug.aspx?PostID=2872" width="1" height="1"&gt;</description><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Firefox/default.aspx">Firefox</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Drag+and+Drop/default.aspx">Drag and Drop</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Mac/default.aspx">Mac</category></item><item><title>Using oEmbed To Generate Thumbnails From Content On YouTube And Other Social Media Sites</title><link>http://www.rightpoint.com/community/blogs/viewpoint/archive/2011/04/10/using-oembed-to-generate-thumbnails-from-content-on-youtube-and-other-social-media-sites.aspx</link><pubDate>Sun, 10 Apr 2011 13:21:00 GMT</pubDate><guid isPermaLink="false">f7450ba4-a08e-465a-831a-f9a15c21b696:2837</guid><dc:creator>Chris Domino</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.rightpoint.com/community/blogs/viewpoint/rsscomments.aspx?PostID=2837</wfw:commentRss><comments>http://www.rightpoint.com/community/blogs/viewpoint/archive/2011/04/10/using-oembed-to-generate-thumbnails-from-content-on-youtube-and-other-social-media-sites.aspx#comments</comments><description>&lt;p class="Text"&gt;In my &lt;a target="_blank" href="http://chrisdomino.com/blog/post/Silverlight-IsWindowless-ness-And-How-You-Don-t-Need-It-To-Display-Flash" class="Link"&gt;second-to-last post&lt;/a&gt;, I talked about showing Flash superimposed over Silverlight without the need to enable &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/bb979728(VS.95).aspx" class="Link"&gt;IsWindowless&lt;/a&gt; mode on the plugin. Something I foreshadowed but didn&amp;#39;t discuss was where the Flash content came from, so I wanted to continue along the topic and elucidate this detail. &lt;/p&gt;
&lt;p class="Text"&gt;There is a new protocol out there called &lt;a target="_blank" href="http://oembed.com/" class="Link"&gt;oEmbed&lt;/a&gt;. This spec, supported by all the major media providers out there (YouTube, Flickr, Hulu, Vimeo, etc.) is a REST-ish API that takes in a URL to a video or image, and responds with an XML or JSON object containing all the metadata you&amp;#39;ll need to integrate this content into your application. &lt;/p&gt;
&lt;p class="Text"&gt;It&amp;#39;s actually really easy. Check out the link above for the details, but all you need to do is construct a URL to the provider&amp;#39;s specification (all are a bit different), and serialize the result into a .NET object. You can then persist it in a database or bind it to your UI. Here&amp;#39;s an example of what a YouTube request will be (start by loading a page and copy-and-pasting the URL; I&amp;#39;m using &amp;quot;http://www.youtube.com/watch?v=6E3znZoFnN8&amp;quot;): &lt;/p&gt;
&lt;p class="Text"&gt;http://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=6E3znZoFnN8&amp;amp;format=xml &lt;/p&gt;
&lt;p class="Text"&gt;The response will be a nice XML document containing several nice pieces of metadata: &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;ul class="Text"&gt;
&lt;li class="Text"&gt;Title&lt;/li&gt;
&lt;li class="Text"&gt;Flash object tag&amp;#39;s HTML&lt;/li&gt;
&lt;li class="Text"&gt;Thumbnail Image URL&lt;/li&gt;
&lt;li class="Text"&gt;Height (both of plugin and thumbnail)&lt;/li&gt;
&lt;li class="Text"&gt;Width (both of plugin and thumbnail)&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;And much more. If you prefer JSON (which is faster to deserialize than XML), the APIs will have a way to specify the format for the response, either as a query string parameter or a part of the path. As you can see, you don&amp;#39;t even need to encode the raw URL! &lt;/p&gt;
&lt;p class="Text"&gt;Some weirdness I ran into was the concept of &amp;quot;protected videos.&amp;quot; These are proprietary pieces of content on the web that the author does not want displayed anywhere else except for where it was originally published. My guess is that it has something to do with copyrights or distribution or promotions or advertisements; money in other words. &lt;/p&gt;
&lt;p class="Text"&gt;It&amp;#39;s difficult to detect this situation from the response, but an oEmbed request for protected content will fail; make sure you have some good error handling around this. I&amp;#39;ve found your best shot is to use a Try/Catch block, catching both &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.net.webexception.aspx" class="Link"&gt;WebExceptions&lt;/a&gt; and standard &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.exception.aspx" class="Link"&gt;Exceptions&lt;/a&gt;. My fail-case contingency flow was to still persist the URL, display a message to the user (in lieu of the Flash content) when it was needed in my app, and provide a link to pop the video up in a new Window navigated to its home on YouTube or wherever. &lt;/p&gt;
&lt;p class="Text"&gt;Here is an example of a wrapper method I used to take in a URL and return the raw response from a provider&amp;#39;s oEmbed endpoint: &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt; GetRawoEmbed&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;string&lt;/span&gt; url&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//initialization&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;WebClient&lt;/span&gt; wc &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;WebClient&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//get base url&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;Uri&lt;/span&gt; uri &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;Uri&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;url&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;UriKind&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Absolute&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;string&lt;/span&gt; baseUri &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Format&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;{0}://{1}&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; uri&lt;span class="Operator"&gt;.&lt;/span&gt;Scheme&lt;span class="Operator"&gt;,&lt;/span&gt; uri&lt;span class="Operator"&gt;.&lt;/span&gt;Authority&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;ToLower&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Replace&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;www.&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Empty&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;wc&lt;span class="Operator"&gt;.&lt;/span&gt;BaseAddress &lt;span class="Operator"&gt;=&lt;/span&gt; baseUri&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//get provider&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;oEmbedProvider&lt;/span&gt; provider &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;ObjectContext&lt;span class="Operator"&gt;.&lt;/span&gt;oEmbedProviders&lt;span class="Operator"&gt;.&lt;/span&gt;Where&lt;span class="Operator"&gt;(&lt;/span&gt;o &lt;span class="Operator"&gt;=&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt; o&lt;span class="Operator"&gt;.&lt;/span&gt;BaseURL&lt;span class="Operator"&gt;.&lt;/span&gt;ToLower&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Replace&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;www.&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Empty&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Equals&lt;span class="Operator"&gt;(&lt;/span&gt;baseUri&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;FirstOrDefault&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;provider &lt;span class="Operator"&gt;!&lt;/span&gt;&lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//get data&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="ClassName"&gt;ASCIIEncoding&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;ASCII&lt;span class="Operator"&gt;.&lt;/span&gt;GetString&lt;span class="Operator"&gt;(&lt;/span&gt;wc&lt;span class="Operator"&gt;.&lt;/span&gt;DownloadData&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;string&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Concat&lt;span class="Operator"&gt;(&lt;/span&gt;provider&lt;span class="Operator"&gt;.&lt;/span&gt;oEmbedFormattedURL&lt;span class="Operator"&gt;,&lt;/span&gt; url&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//not supported&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;UNSUPPORTED&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;catch&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;WebException&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//protected&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;PROTECTED&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;catch&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Exception&lt;/span&gt; ex&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//error&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;ERROR&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;Notes: &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;ul class="Text"&gt;
&lt;li class="Text"&gt;Line #12 is just a call into our database where we store the &amp;quot;supported&amp;quot; oEmbed providers. This is a &amp;quot;system&amp;quot; table in our schema that has the URL format string, friendly name, etc. for each endpoint. &lt;/li&gt;
&lt;li class="Text"&gt;Line #16 uses standard ASCII encoding to get the raw data as a string out of the response bits. &lt;/li&gt;
&lt;li class="Text"&gt;Errors: I know that returning strings like &amp;quot;ERROR&amp;quot; or &amp;quot;UNSUPPORTED&amp;quot; are not the most elegant way to allow your application to fail gracefully. But for our situation, this whole feature was a last minute enhancement, and we had no choice but to cut corners. However I feel that it&amp;#39;s a small price to pay for getting the URL to a thumbnail image for a YouTube video essentially for free.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;Once we get the data back from the oEmbed endpoint of our provider, the last step is to deserialize the string into an object and databind it to the UI. Here&amp;#39;s that logic: &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;private&lt;/span&gt; &lt;span class="ClassName"&gt;OEmbed&lt;/span&gt; DeserializeOEmbed&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;string&lt;/span&gt; result&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//get result&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;result&lt;span class="Operator"&gt;.&lt;/span&gt;Equals&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;ERROR&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//handle error&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;else&lt;/span&gt; &lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;result&lt;span class="Operator"&gt;.&lt;/span&gt;Equals&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;PROTECTED&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//handle protected&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;else&lt;/span&gt; &lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;result&lt;span class="Operator"&gt;.&lt;/span&gt;Equals&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;UNSUPPORTED&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//handle unsupported&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//deserialize video metadata&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//open stream&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;using&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;MemoryStream&lt;/span&gt; ms &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;MemoryStream&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Encoding&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Unicode&lt;span class="Operator"&gt;.&lt;/span&gt;GetBytes&lt;span class="Operator"&gt;(&lt;/span&gt;result&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//deserialize&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;DataContractJsonSerializer&lt;/span&gt; serializer &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;DataContractJsonSerializer&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;typeof&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;OEmbed&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;OEmbed&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;serializer&lt;span class="Operator"&gt;.&lt;/span&gt;ReadObject&lt;span class="Operator"&gt;(&lt;/span&gt;ms&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;catch&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Exception&lt;/span&gt; ex&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//error&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;Assuming there are no errors along the way, most of the magic is in Line #28, where we use the trusty WCF &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx" class="Link"&gt;DataContractJsonSerializer&lt;/a&gt; to turn the JSON we get from the providers into our business object. Hmm. The term &amp;quot;Business Object&amp;quot; might be a bit too stuffy to use for something as cool as dynamically displaying Flash content over Silverlight, but I&amp;#39;ll get over it. &lt;/p&gt;
&lt;p class="Text"&gt;Well that&amp;#39;s about it, except for one final note. In case you&amp;#39;re wondering if there&amp;#39;s a more dynamic way to call the oEmbed providers based on the input URL than checking a database or configuration file of &amp;quot;supported&amp;quot; endpoints, well then you&amp;#39;re right. There is a clearing house service out there that does just that: takes a URL, and tries to parse it against dozens and dozens of providers. &lt;/p&gt;
&lt;p class="Text"&gt;Check out &lt;a target="_blank" href="http://api.embed.ly" class="Link"&gt;http://api.embed.ly&lt;/a&gt; for the API. It&amp;#39;s free. Just use it as you would any other oEmbed provider&amp;#39;s API. The endpoint looks like this: &lt;/p&gt;
&lt;p class="Text"&gt;http://api.embed.ly /1/oembed?url=[copy-and-pasted URL from the browser here] &lt;/p&gt;
&lt;p class="Text"&gt;&lt;span class="Rant"&gt;&amp;lt;Rant&amp;gt;&lt;/span&gt; &lt;/p&gt;
&lt;p class="Text"&gt;If you are like me, you&amp;#39;ll be awesome and spend hours refactoring your code until it is pristinely organized into reusable methods, has the absolute minimum amount of external dependencies it needs to physically run, and is as dynamic and beautiful as possible. If you&amp;#39;re not like me, then you&amp;#39;re probably not even reading this, which means I&amp;#39;m really just talking to myself. Anyway, I waged a fierce battle against my team in favor of using the clearing house. Why introduce a new database table to our schema that has nothing to do with our data model, only to effectively &lt;span class="Italic"&gt;reduce&lt;/span&gt; the number of providers we support? &lt;/p&gt;
&lt;p class="Text"&gt;I was overruled, in favor of the argument that if the clearing house went away, the feature would be dead, and we&amp;#39;d have to do it more statically anyway. I see the wisdom and foresight of this, (I know you&amp;#39;re reading, Jonathan) but I personally dislike architecting against the apocalypse. Whenever a healthy debate ensues in the project room, I hate the arguments that begin with &amp;quot;Well, what if...&amp;quot; &lt;/p&gt;
&lt;p class="Text"&gt;There&amp;#39;s always a &amp;quot;what if&amp;quot; when it comes to software development. &lt;/p&gt;
&lt;p class="Text"&gt;Until we get to whatever is waiting for us after the Internet, we will ultimately be dependent on it for almost every app we build. And guess what? The Internet is made out of plastic and wires and other people&amp;#39;s code. Everything is dependent on something else. We depend on electricity not going down. We depend on routers not going down. We depend on the .NET Framework not going down. We depend on YouTube not going down. So although the clearing house is indeed the weakest link in our logical chain of dependencies, we can&amp;#39;t eliminate it based on that alone. &lt;/p&gt;
&lt;p class="Text"&gt;If the clearing house goes down, then the feature will break. But until we have contingency plans for the rest of the components failing, I am comfortable taking that risk. Sometimes building beautiful, dynamic software requires a more ballsy architecture. I&amp;#39;d rather have to explain to the client why the feature went down (since it won&amp;#39;t be my fault, technically) than why the hot new media website on the Internet isn&amp;#39;t supported by our application. &lt;/p&gt;
&lt;p class="Text"&gt;&lt;span class="Rant"&gt;&amp;lt;/Rant&amp;gt;&lt;/span&gt; &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.rightpoint.com/community/aggbug.aspx?PostID=2837" width="1" height="1"&gt;</description><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Social+Media/default.aspx">Social Media</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/flash/default.aspx">flash</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/oEmbed/default.aspx">oEmbed</category></item><item><title>Silverlight IsWindowless-ness, And How You Don’t Need It To Display Flash!</title><link>http://www.rightpoint.com/community/blogs/viewpoint/archive/2011/03/11/silverlight-iswindowless-ness-and-how-you-don-t-need-it-to-display-flash.aspx</link><pubDate>Sat, 12 Mar 2011 00:13:00 GMT</pubDate><guid isPermaLink="false">f7450ba4-a08e-465a-831a-f9a15c21b696:2831</guid><dc:creator>Chris Domino</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.rightpoint.com/community/blogs/viewpoint/rsscomments.aspx?PostID=2831</wfw:commentRss><comments>http://www.rightpoint.com/community/blogs/viewpoint/archive/2011/03/11/silverlight-iswindowless-ness-and-how-you-don-t-need-it-to-display-flash.aspx#comments</comments><description>&lt;p class="Text"&gt;Now, a lot has been written about Silverlight interop with regard Flash, not to mention HTML, JavaScript, WCF, and even other Silverlight controls. Like my last few postings on the topic, I want to call out that even though there&amp;#39;s much blogging that&amp;#39;s been done on this topic, I&amp;#39;ve stumbled onto an ancillary scenario &lt;span class="Italic"&gt;seemingly&lt;/span&gt; along the same lines as others. However, it&amp;#39;s distinct enough to be worth mentioning; distinct enough to not be yet another of the same thing as the previous six links you probably just glazed over on Bing or Google. &lt;/p&gt;
&lt;p class="Text"&gt;When you consider a browser with plugins (specifically plugins that are part of the content, verses &amp;quot;add-ins&amp;quot; which are tools that may or may not interact with the content, but are definitely not part of it [Silverlight is a plugin, &lt;a target="_blank" href="http://getfirebug.com/" class="Link"&gt;FireBug&lt;/a&gt; is an add-in]) there are two dimensions at play when it comes to physically rendering the page. First there&amp;#39;s the HTML, and second there&amp;#39;s the plugin. And generally, they stay separate. FireFox, for example, goes so far as to run its plugins in a different process. &lt;/p&gt;
&lt;p class="Text"&gt;I use the word &amp;quot;dimension&amp;quot; specifically in the preceding paragraph. HTML is in one dimension, and Silverlight or Flash or Java is in another. Even though plugins &lt;span class="Italic"&gt;appear&lt;/span&gt; to be embedded within the HTML, they really aren&amp;#39;t part of it at all. The browser tells the plugin where it will be displayed, and the plugin does the rest: its own execution, app domain management, rendering, etc. Despite the HTML bridge that exists in Silverlight, plugins and HTML are not aware of each other. In fact, that&amp;#39;s why such a bridge exists at all. &lt;/p&gt;
&lt;p class="Text"&gt;To continue this spatial metaphor, each dimension has its own Z-indexing system, much like the axes of the Cartesian plane. The Z-index of a div has no bearing on the Z-index of a &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.canvas(v=VS.95).aspx" class="Link"&gt;Canvas&lt;/a&gt;. I&amp;#39;ve seen people in the forums making this mistake time and again. There is no magical combination of Z-Indexes of div tags, object tags, or Silverlight controls that will, for example, allow you to have a long Silverlight &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.combobox(VS.95).aspx" class="Link"&gt;ComboBox&lt;/a&gt; hang below its object tag&amp;#39;s content region and superimpose itself over the surrounding HTML. Not possible. That would be like simultaneously standing on both sides of a wall with no doorway or threshold. &lt;/p&gt;
&lt;p class="Text"&gt;The confusion deepens with Silverlight&amp;#39;s introduction of the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.interop.settings.windowless(v=VS.95).aspx" class="Link"&gt;IsWindowless&lt;/a&gt; property into the mix. This is probably the least understood (or most misunderstood) Silverlight concept. Some seem to regard this as a panacea for Silverlight oddities. Does your non-rectangular control have a weird black background? Set IsWindowless to true. Can&amp;#39;t get HTML to show up on top of Silverlight? Set IsWindowless to true. Those who have been through the trenches know that there&amp;#39;s a performance hit to IsWindowless-ness, but it&amp;#39;s hard to stop at that when this magical Boolean makes your bizarre issues go away. &lt;/p&gt;
&lt;p class="Text"&gt;What&amp;#39;s really happening is that IsWindowless acts like an interdimensional worm hole between the HTML and Silverlight worlds. Even though the dimensions stay separate, IsWindowless forces Silverlight to do the diligence of rendering itself as though the worlds could be combined. I assume this is where the extra work comes in causing the much-warned-against performance ramifications. But it still doesn&amp;#39;t inject itself into the HTML Z-indexing scheme. Now, that said, the div that the object tag lives will be rendered in the specified Z order, as in the following example: &lt;/p&gt;
&lt;p class="Text"&gt;A div with a Z-index of 2 will be rendered beneath a div with a Z-index of 3 that contains Silverlight content. A div with a Z-index of 4 (and the proper absolute positioning) will be rendered topmost. &lt;/p&gt;
&lt;p class="Text"&gt;However, any Silverlight Z-indexes will stay in their own dimension. So although you can now have HTML on top of Silverlight, you still can&amp;#39;t shuffle Canvases and divs together. But at least we can get this multidimensional beast of a webpage acting as though its constituent parts were cohesively working together to render unified content. &lt;/p&gt;
&lt;p class="Text"&gt;But this worm hole can lead us to more harm than good. For example, such blending of HTML and Silverlight breaks drag &amp;amp; drop. Since Silverlight now lives &amp;quot;within-ish&amp;quot; the HTML, it stops receiving its own mouse events, as the browser intercepts them. Our application depended on drag &amp;amp; drop, so IsWindowless was out, as was our requirement to be able to display Flash videos over our Silverlight control. &lt;/p&gt;
&lt;p class="Text"&gt;So that brings me to the point: you can still superimpose Flash over Silverlight &lt;span class="Italic"&gt;without&lt;/span&gt; the crutch (and ensuing sluggishness) of IsWindowless. &lt;/p&gt;
&lt;p class="Text"&gt;In both HTML and Silverlight, any ties between two elements with the same Z-index values would be broken by the order in which they were added to their parent container. For example, if two &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.textblock(v=VS.95).aspx" class="Link"&gt;TextBlocks&lt;/a&gt; were added to a Canvas in xaml and had no Z-indexes set, both values would default to zero, the the TextBlock add last would display over top the of the first one. What if this principle guided the Z-index ordering of plugins as it did elements? &lt;/p&gt;
&lt;p class="Text"&gt;When I had IsWindowless turned on, an absolutely-positioned div I created dynamically via a Silverlight button click (and is therefore added to the DOM &lt;span class="Italic"&gt;after&lt;/span&gt; the Silverlight) would position itself correctly topmost on the page with the proper Z-index. When I turned IsWindowless off, the div, as expected, disappeared. Upon inspecting the page with FireBug, out wayward div was indeed still there, just loitering in the wrong dimension! &lt;/p&gt;
&lt;p class="Text"&gt;Now what if this div contained the Flash content (by way of an HTML object tag)? Even though the div wouldn&amp;#39;t be displayed, since the Flash plugin was technically added to the DOM after Silverlight&amp;#39;s, it should still show up, on top of the app, positioned according to its div. And guess what: it worked! Well, almost; IE needed some coaxing. Here&amp;#39;s the JavaScript that worked cross-browser. &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;var&lt;/span&gt; _div&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;function&lt;/span&gt; ShowVideo&lt;span class="Operator"&gt;(&lt;/span&gt;html&lt;span class="Operator"&gt;,&lt;/span&gt; width&lt;span class="Operator"&gt;,&lt;/span&gt; height&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//get middle x and y&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;var&lt;/span&gt; x &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;$&lt;span class="Operator"&gt;(&lt;/span&gt;window&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;width&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;/&lt;/span&gt; 2&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;-&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;width &lt;span class="Operator"&gt;/&lt;/span&gt; 2&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;var&lt;/span&gt; y &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;$&lt;span class="Operator"&gt;(&lt;/span&gt;window&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;height&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;/&lt;/span&gt; 2&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;-&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;Number&lt;span class="Operator"&gt;(&lt;/span&gt;height&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;-&lt;/span&gt; 30&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;/&lt;/span&gt; 2&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//show div&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;_div &lt;span class="Operator"&gt;=&lt;/span&gt; $&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;#divVideo&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;_div&lt;span class="Operator"&gt;.&lt;/span&gt;css&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;{&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;height&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt; height&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;width&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt; width&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;top&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt; y&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;left&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt; x &lt;span class="Operator"&gt;}&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;_div&lt;span class="Operator"&gt;.&lt;/span&gt;html&lt;span class="Operator"&gt;(&lt;/span&gt;html&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//set timeout fixes an ie issue&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;setTimeout&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;_div.show();&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; 100&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;function&lt;/span&gt; HideVideo&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//kill flash&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;var&lt;/span&gt; div &lt;span class="Operator"&gt;=&lt;/span&gt; $&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;#divVideo&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;div&lt;span class="Operator"&gt;.&lt;/span&gt;hide&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;div&lt;span class="Operator"&gt;.&lt;/span&gt;html&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;In Line #2, we&amp;#39;re pulling a chunk of HTML out of the database with the object tag all ready to go, along with the height and width of the video, and passing those to the JavaScript method via Silverlight. (How you can easily get these wonderful values with nothing more than a URL to a YouTube clip will be the topic of a future post.) &lt;/p&gt;
&lt;p class="Text"&gt;Line #6 is an adjustment for some Silverlight chrome we display around where the div will show up. We animate a popup with a close button, and then fire the JavaScript that creates the Flash content. The video displays perfectly in the middle of the popup, giving no indication of how many technologies had to be entangled to get it to work. The close button calls &amp;quot;HideVideo&amp;quot; in Line #14. &lt;/p&gt;
&lt;p class="Text"&gt;Line #12 is the fix for IE wonkiness. Basically, nothing would happen when the popup first showed. However, merely clicking on the page would immediately bring the Flash content into position. It was as though IE needed to be kicked like a stubborn horse to recalculate the Z-indexes of the plugins. This is indeed a hack, but it&amp;#39;s worked for weeks now. My hunch is that the slower JavaScript engine on IE is to blame. By showing the div, pausing, and then populating it with Flash, it had time to catch up. &lt;/p&gt;
&lt;p class="Text"&gt;Chrome is now my primary browser. Don&amp;#39;t tell Microsoft. &lt;/p&gt;
&lt;p class="Text"&gt;But like I said, it works, without having to resort to IsWindowless-ness. Calling HideVideo() in Line #14 properly &amp;quot;disposes&amp;quot; of the Flash by wiping it off the DOM, which will stop playing the current movie before closing it. &lt;/p&gt;
&lt;p class="Text"&gt;That&amp;#39;s it! Have fun Flashing your Silverlight! &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.rightpoint.com/community/aggbug.aspx?PostID=2831" width="1" height="1"&gt;</description><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/flash/default.aspx">flash</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/HTML/default.aspx">HTML</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Interop/default.aspx">Interop</category></item><item><title>A Color Comparison Algorithm</title><link>http://www.rightpoint.com/community/blogs/viewpoint/archive/2011/03/01/a-color-comparison-algorithm.aspx</link><pubDate>Wed, 02 Mar 2011 03:29:00 GMT</pubDate><guid isPermaLink="false">f7450ba4-a08e-465a-831a-f9a15c21b696:2829</guid><dc:creator>Chris Domino</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.rightpoint.com/community/blogs/viewpoint/rsscomments.aspx?PostID=2829</wfw:commentRss><comments>http://www.rightpoint.com/community/blogs/viewpoint/archive/2011/03/01/a-color-comparison-algorithm.aspx#comments</comments><description>&lt;p class="Text"&gt;Every once in a while you are presented with an opportunity to write something that is truly &lt;span class="Italic"&gt;cool&lt;/span&gt;. And by &amp;quot;cool&amp;quot; I don&amp;#39;t mean programmatically interesting or logically fun. I&amp;#39;ve done cool things with SharePoint list event handlers and cool things with .NET RIA Services, for example. But what I mean here is something, literally, cool; something that someone who is not in the world of software development would overhear and think to themselves, &amp;quot;Wow. That sounds...&lt;span class="Italic"&gt;cool&lt;/span&gt;.&amp;quot; &lt;/p&gt;
&lt;p class="Text"&gt;We are building a Facebook-ish Silverlight application for a group of designers. Part of the data model for this app is the storage of about two thousand &amp;quot;Defined Colors,&amp;quot; which they use in their brands. Each color is stored in a bit-shifted integer representation (four 8-bit bytes smashed together) of the component aRGB values. The requirement was to allow users to be able to select an image from their machine, and have it pop open on the page. They could then click anywhere within in, and based on the shade of the selected pixel, I needed to return the closest color to it from among the palette of Defined Colors. &lt;/p&gt;
&lt;p class="Text"&gt;Yeah. That&amp;#39;s cool. &lt;/p&gt;
&lt;p class="Text"&gt;My brain immediately whirred with how this could be done. I had played with &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap(VS.95).aspx" class="Link"&gt;WritableBitmap&lt;/a&gt; in the past for some lightweight photo-cropping functionality I needed, and knew this was the correct vehicle to use. Not only did it serve as an &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.image.source(VS.95).aspx" class="Link"&gt;ImageSource&lt;/a&gt;, but also provided an aperture into the underlying array of pixels beneath the image, not unlike a microscope exposing the atoms making up a flower. However, this was not the cool part, not the part that exited me. &lt;/p&gt;
&lt;p class="Text"&gt;The &lt;span class="Italic"&gt;cool&lt;/span&gt; part was the algorithm that flew into my head to compare two colors for similarity. The math wasn&amp;#39;t complicated at all (as you&amp;#39;ll see); it was the careful dissection of the colors that I found fascinating. Any time something abstract can be mapped to a system of numbers, I feel like anything is possible. That&amp;#39;s how technologies like voice recognition or handwriting-to-text conversion probably came about: whittle it down to a number, something you can work with, something that follows rules, and we can make it do anything. &lt;/p&gt;
&lt;p class="Text"&gt;Suddenly my excitement waned and quickly turned to anxiety. The lines of code that I had already begun subconsciously composing in my head seemed so simplistic - someone had certainly done something like this before...right? But a little bit of Binging put my mind back at ease. If this has been done, and then had been written up, it wasn&amp;#39;t well tagged; I couldn&amp;#39;t find anything quite like what I came up with. A lot of things were close: calculating luminosity, converting hex to RGB, etc. But there was nothing exactly hitting home regarding the comparison of two colors. Perhaps it had been deemed too obscure or unusable to be worth the time to blog. Either way, it was a rare occurrence for me to be glad not to find what I was looking for; this was my story to tell. &lt;/p&gt;
&lt;p class="Text"&gt;So let&amp;#39;s get to it. My idea was to first lobotomize the &amp;quot;input&amp;quot; color (corresponding to the clicked-on pixel from the image) and store its constituent aRGB parts as four integer variables. Next, spin through all of the Defined Colors, performing the same operation on them. In each iteration, we need to obtain a new color, the literal &amp;quot;difference&amp;quot; between the current Defined Color and selected input color, by subtracting the aRGB values from one another, component by component. In other words: for each comparison, subtract alpha from alpha, red from red, green from green, and blue from blue. I&amp;#39;ll refer to this &amp;quot;new&amp;quot; color as the &amp;quot;offset color.&amp;quot; &lt;/p&gt;
&lt;p class="Text"&gt;Now that we have each &amp;quot;difference,&amp;quot; we need to know which one is the &lt;span class="Italic"&gt;least&lt;/span&gt; different. This is done by summing the four parts of each offset color, (which I&amp;#39;ll call the &amp;quot;constituent sum&amp;quot; because that sounds awesome) and tracking the smallest such sum as we iterate through our palette. Think of these aRGB values as vectors with the same origin and length. If we have an input vector and a finite set of source vectors, the one pointing in the &amp;quot;closest&amp;quot; direction to our input is the one with the smallest magnitude of difference from it; the one least offset from it. &lt;/p&gt;
&lt;p class="Text"&gt;Turns out it&amp;#39;s the same story with colors. Basically, after enumerating the source Defined Colors, we grab the one corresponding to the offset color whose constituent sum produced that smallest delta from the input color&amp;#39;s sum. And upon testing, it totally worked! I think the code is much more straightforward than the narrative, so let&amp;#39;s take a look: &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;private&lt;/span&gt; &lt;span class="ClassName"&gt;Color&lt;/span&gt; GetClosestColor&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Color&lt;/span&gt; color&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//initialization&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;int&lt;/span&gt; minA &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;byte&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;MaxValue&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;int&lt;/span&gt; minR &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;byte&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;MaxValue&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;int&lt;/span&gt; minG &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;byte&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;MaxValue&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;int&lt;/span&gt; minB &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;byte&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;MaxValue&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;Color&lt;/span&gt; closest &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;Colors&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Transparent&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//iterate all colors&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;foreach&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;DefinedColor&lt;/span&gt; dc &lt;span class="Keyword"&gt;in&lt;/span&gt; &lt;span class="ClassName"&gt;DataAccessLayer&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;GetAllDefinedColors&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//get each .net color&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;Color&lt;/span&gt; c &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;Utilities&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;GetColorFromDefinedColorRGB&lt;span class="Operator"&gt;(&lt;/span&gt;dc&lt;span class="Operator"&gt;.&lt;/span&gt;RGB&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//subtract the components&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;int&lt;/span&gt; a &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;Math&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Abs&lt;span class="Operator"&gt;(&lt;/span&gt;c&lt;span class="Operator"&gt;.&lt;/span&gt;A &lt;span class="Operator"&gt;-&lt;/span&gt; color&lt;span class="Operator"&gt;.&lt;/span&gt;A&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;int&lt;/span&gt; r &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;Math&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Abs&lt;span class="Operator"&gt;(&lt;/span&gt;c&lt;span class="Operator"&gt;.&lt;/span&gt;R &lt;span class="Operator"&gt;-&lt;/span&gt; color&lt;span class="Operator"&gt;.&lt;/span&gt;R&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;int&lt;/span&gt; g &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;Math&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Abs&lt;span class="Operator"&gt;(&lt;/span&gt;c&lt;span class="Operator"&gt;.&lt;/span&gt;G &lt;span class="Operator"&gt;-&lt;/span&gt; color&lt;span class="Operator"&gt;.&lt;/span&gt;G&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;int&lt;/span&gt; b &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;Math&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Abs&lt;span class="Operator"&gt;(&lt;/span&gt;c&lt;span class="Operator"&gt;.&lt;/span&gt;B &lt;span class="Operator"&gt;-&lt;/span&gt; color&lt;span class="Operator"&gt;.&lt;/span&gt;B&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//determine if the sum of the differences of this color is the least of all so far&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;a &lt;span class="Operator"&gt;+&lt;/span&gt; r &lt;span class="Operator"&gt;+&lt;/span&gt; g &lt;span class="Operator"&gt;+&lt;/span&gt; b&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;minA &lt;span class="Operator"&gt;+&lt;/span&gt; minR &lt;span class="Operator"&gt;+&lt;/span&gt; minG &lt;span class="Operator"&gt;+&lt;/span&gt; minB&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//if so, this is the closest color&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;minA &lt;span class="Operator"&gt;=&lt;/span&gt; a&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;minR &lt;span class="Operator"&gt;=&lt;/span&gt; r&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;minG &lt;span class="Operator"&gt;=&lt;/span&gt; g&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;minB &lt;span class="Operator"&gt;=&lt;/span&gt; b&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//store this color&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;closest &lt;span class="Operator"&gt;=&lt;/span&gt; c&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;ExistingColor &lt;span class="Operator"&gt;=&lt;/span&gt; dc&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//return&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; closest&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;Some notes: &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;ul class="Text"&gt;
&lt;li class="Text"&gt;The &amp;quot;DefinedColor&amp;quot; object in Line #10 is simply a wrapper object around what we have stored in the database for each source Defined Color: basically the &amp;quot;int&amp;quot; value (byte representation of the aRGB and a friendly name).&lt;/li&gt;
&lt;li class="Text"&gt;Line #29 stores the closest Defined Color in a global variable for use in data binding (which is outside the scope of this discussion).&lt;/li&gt;
&lt;li class="Text"&gt;You&amp;#39;ll see a call to a utility method in Line #13. This converts the integer representation of a color (&amp;quot;raw&amp;quot; aRGB) into a .NET color. Here&amp;#39;s that method, along with its corollary (which isn&amp;#39;t used here, but I wanted to include it for your reference).&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="Keyword"&gt;static&lt;/span&gt; &lt;span class="ClassName"&gt;Color&lt;/span&gt; GetColorFromDefinedColorRGB&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;int&lt;/span&gt; definedColor&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//convert color&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="ClassName"&gt;Color&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;FromArgb&lt;span class="Operator"&gt;(&lt;/span&gt;255&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;byte&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;definedColor &lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt; 16 &lt;span class="Operator"&gt;&amp;amp;&lt;/span&gt; 0xFF&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;byte&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;definedColor &lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt; 8 &lt;span class="Operator"&gt;&amp;amp;&lt;/span&gt; 0xFF&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;byte&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;definedColor &lt;span class="Operator"&gt;&amp;amp;&lt;/span&gt; 0xFF&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="Keyword"&gt;static&lt;/span&gt; &lt;span class="Keyword"&gt;int&lt;/span&gt; GetIntFromColor&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Color&lt;/span&gt; color&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//convert color&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; color&lt;span class="Operator"&gt;.&lt;/span&gt;A &lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt; 24 &lt;span class="Operator"&gt;|&lt;/span&gt; color&lt;span class="Operator"&gt;.&lt;/span&gt;R &lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt; 16 &lt;span class="Operator"&gt;|&lt;/span&gt; color&lt;span class="Operator"&gt;.&lt;/span&gt;G &lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt; 8 &lt;span class="Operator"&gt;|&lt;/span&gt; color&lt;span class="Operator"&gt;.&lt;/span&gt;B&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;In Line #4, you&amp;#39;ll see that I &amp;quot;hard coded&amp;quot; 255 for the alpha channel. This simplification is due to fact that the application doesn&amp;#39;t support transparent colors (although it easily could). &lt;/p&gt;
&lt;p class="Text"&gt;That&amp;#39;s about it for my color comparison algorithm. Although certainly not an everyday thing, it&amp;#39;s interesting to understand how to extract the constituent parts of colors in general. This has come up more times than I thought it would, especially using technologies like Silverlight. &lt;/p&gt;
&lt;p class="Text"&gt;Have fun coloring! &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.rightpoint.com/community/aggbug.aspx?PostID=2829" width="1" height="1"&gt;</description><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Color/default.aspx">Color</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/RGB/default.aspx">RGB</category></item><item><title>Silverlight Navigation with 100% Custom Transitional Animations</title><link>http://www.rightpoint.com/community/blogs/viewpoint/archive/2011/02/26/silverlight-navigation-with-100-custom-transitional-animations.aspx</link><pubDate>Sat, 26 Feb 2011 20:16:00 GMT</pubDate><guid isPermaLink="false">f7450ba4-a08e-465a-831a-f9a15c21b696:2828</guid><dc:creator>Chris Domino</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.rightpoint.com/community/blogs/viewpoint/rsscomments.aspx?PostID=2828</wfw:commentRss><comments>http://www.rightpoint.com/community/blogs/viewpoint/archive/2011/02/26/silverlight-navigation-with-100-custom-transitional-animations.aspx#comments</comments><description>&lt;p class="Text"&gt;Something that&amp;#39;s always impressed me about Silverlight (and has made my life a lot easier) has been the browser integration, both in terms of the HTML bridge and the navigation history functionality. I want to focus on the latter; the former has been beaten to death, and at this point, it&amp;#39;s hard for me to get excited about yet another way to sling JavaScript. &lt;/p&gt;
&lt;p class="Text"&gt;Clicking the &amp;quot;back&amp;quot; browser button is one of the handiest UX innovations I&amp;#39;ve ever seen. At the same time, it creates quite an onus for the web developer, as it can easily put a poorly-designed application into an indeterminate state. This can be a rude awakening (it was for me) the first time you need to start messing with &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.web.ui.page.ispostback.aspx" class="Link"&gt;Page.IsPostBack&lt;/a&gt; and &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/ms529034(VS.85).aspx" class="Link"&gt;Control.AutoPostBack&lt;/a&gt;. Then throw some AJAX into the mix. If you are not diligent with your page transitions, you could get a poor user experience, or worse, garbage data when the user clicks the seemingly harmless back button. &lt;/p&gt;
&lt;p class="Text"&gt;Now in Silverlight applications (verses a web page that has &lt;span class="Bold"&gt;some&lt;/span&gt; Silverlight on it for purposes of sex appeal alone), the back button takes on a different role. If you aren&amp;#39;t using the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc838245(VS.95).aspx" class="Link"&gt;Silverlight Navigation Framework&lt;/a&gt;, then much like a hard page refresh, &amp;quot;backing&amp;quot; to a Silverlight page will cause the control to reload from scratch, as if it was the first time it had been visited. However, the nav framework will nestle itself into the browser&amp;#39;s history quite nicely, using hashed &amp;quot;relative&amp;quot; URLs, making your Silverlight app behave as though it were a standard website comprised of distinct physical pages. &lt;/p&gt;
&lt;p class="Text"&gt;This enables SEO, browser forward/back navigation, true MVC-like architecture with the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.navigation.urimapper(VS.95).aspx" class="Link"&gt;UriMapper&lt;/a&gt;, quasi-master pages, and lots of other enterprise-ish application features. Behind the scenes, all that&amp;#39;s happening is that URLs are mapped to relative folder locations for XAML files within the XAP, and the corresponding file is loaded into a particular content frame. There are a bunch of posts out there regarding how to transition smoothly between pages while remaining within the Silverlight Navigation Framework, but none quite worked out for our situation. &lt;/p&gt;
&lt;p class="Text"&gt;We were building our second Silverlight application for a client. The first one was a SharePoint intranet, with lots of isolated Silverlight controls (ie, many XAPs) on the page. There were some major performance ramifications to this, as we had to pay a price for the spin up of each XAP&amp;#39;s app domain. In other words, a separate version of the Silverlight runtime was loaded into memory for each control on the page. Yeah. Ouch. &lt;/p&gt;
&lt;p class="Text"&gt;So when we began architecting the second app, which was pure Silverlight, the first thing we decided upon was one XAP that contains the entire UI. This made start up times faster, which is a good first step in a development project where performance was considered a feature, not an optimization. Additionally, the app demanded very intense styling and animations, so almost every control we created has a custom template of some sort. Basically, we had to do more, and do it faster. For the navigation, pages fly in and out of the screen and the background scrolls in the opposite direction &lt;span class="Italic"&gt;behind&lt;/span&gt; the &amp;quot;chrome&amp;quot; of the application. Here&amp;#39;s a Paint masterpiece of what we had to do. (The blue rectangles represent the viewable area of the app in the browser, the solid-colored boxes are stacked images, and the back rectangles are user controls.) &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;p class="Image"&gt;&lt;img src="http://chrisdomino.com/content/images/Silverlight-Navigation-with-100-Custom-Transitional-Animations/navigation.png" class="Image" alt="" /&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;As the user navigates to different &amp;quot;pages,&amp;quot; the user control that corresponds to it animates &amp;quot;down&amp;quot; into view, while the appropriate background slides &amp;quot;up&amp;quot; behind it. (The word &amp;quot;pages&amp;quot; above is in quotes because, remember, everything is physically on the same page, within the same XAP.) However, the magic that happens is that browser back/forward navigation, browser tab titles, and deep linking all work! &lt;/p&gt;
&lt;p class="Text"&gt;In other words, the technique I will show allows us to essentially browser navigate &lt;span class="Italic"&gt;around a single user control&lt;/span&gt; in Silverlight! &lt;/p&gt;
&lt;p class="Text"&gt;No idea what I&amp;#39;m talking about? Here&amp;#39;s an &lt;a target="_blank" href="http://chrisdomino.com/blogexamples/navigationtransition/uitestpage.aspx" class="Link"&gt;example&lt;/a&gt;. Even though the application seems to navigate normally, notice how the pages animate feely (instead of one disappearing and another appearing, a la some cheesy PowerPoint slide transition) and smoothly. The source code will be included at the end of this post. &lt;/p&gt;
&lt;p class="Text"&gt;Since we&amp;#39;re not actually moving to different pages or loading different controls, the sky is the limit for animated transitions; we don&amp;#39;t need to rely on any third party controls or limited OOTB functionality. Instead all we need is the chrome (the main user control; the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.application.rootvisual(VS.95).aspx" class="Link"&gt;RootVisual&lt;/a&gt; of the Silverlight application itself), the child user controls that act as &amp;quot;pages&amp;quot; (but aren&amp;#39;t &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.page(v=VS.95).aspx" class="Link"&gt;&lt;span class="Italic"&gt;Pages&lt;/span&gt;&lt;/a&gt; a la Silverlight 3 Navigation), and a custom &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.navigation.inavigationcontentloader(VS.95).aspx" class="Link"&gt;Navigation Loader&lt;/a&gt; that does the magic of making the browser think it&amp;#39;s going to different pages when it&amp;#39;s really staying in the same place. &lt;/p&gt;
&lt;p class="Text"&gt;The &amp;quot;chrome&amp;quot; of the application is more or less like a master page: it contains all the UI that remains stationary while the content pages animate around it. This includes menus, tab strips, footer links, mastheads, etc. It also includes the Silverlight Navigation Framework pieces: the aforementioned UriMapper and Navigation Loader, as well as the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.frame(VS.95).aspx" class="Link"&gt;Frame&lt;/a&gt;, which, in conventional Silverlight navigation terms, is the area where the content for each actual page is loaded inside the chrome. Think of it just like an HTML iframe whose source is set with JavaScript. &lt;/p&gt;
&lt;p class="Text"&gt;Inside the chrome is some sort of &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.panel(VS.95).aspx" class="Link"&gt;Panel&lt;/a&gt; that contains all of the controls that act as our pages. This panel can be as simple as a &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.canvas.aspx" class="Link"&gt;Canvas&lt;/a&gt; wherein its children have their Y coordinates animated, or a custom panel (as was our case) that arranged pages all over the place and used interfaces and attributes to facilitate communication and positioning. This detail, however, is out of the scope of this post. What&amp;#39;s important is that all the pages live inside a single panel in the chrome. Alongside this panel is the navigation frame, which, as its children, has the UriMapper busily mapping URIs to XAML file relative paths, a navigation loader, and the content of the page being loaded. &lt;/p&gt;
&lt;p class="Text"&gt;I hope that last sentence sounded strange. If we have a panel that&amp;#39;s animating child controls around to show different pages, then what content are we loading into the frame itself? The answer: &lt;span class="Bold"&gt;nothing&lt;/span&gt;. The things we need the frame for are to fire navigation events and have its &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.frame.navigate.aspx" class="Link"&gt;Navigate&lt;/a&gt; method called. This method allows, for example, a button click on one page to kick off a nav to another. But there&amp;#39;s no rule that the frame&amp;#39;s &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol.content(v=VS.95).aspx" class="Link"&gt;Content&lt;/a&gt; property ever needs to be set! That&amp;#39;s right: we basically have a collapsed frame on the page that does nothing except listens for URL changes and fires events. It doesn&amp;#39;t have to display &lt;span class="Italic"&gt;anything&lt;/span&gt;! &lt;/p&gt;
&lt;p class="Text"&gt;How can this be so? Because frames have these navigation loader things we&amp;#39;ve been talking about. Their actual job is to asynchronously turn a URI into, essentially, a &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.usercontrol(VS.95).aspx" class="Link"&gt;UserControl&lt;/a&gt;. Frames have a default navigation loader: an instance of &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.navigation.pageresourcecontentloader(v=VS.95).aspx" class="Link"&gt;PageResourceContentLoader&lt;/a&gt;. This puppy cranks out actual Silverlight pages reflectively instantiated from the passed in Uri, and sets them to the content of the frame. Here is where conventional frame transition animations will be implemented. However, like I said, the fact that these animations are linked to the frame, and not the pages themselves, makes them not flexible enough. So my thinking: simply don&amp;#39;t show the frame at all and handle the UI myself. &lt;/p&gt;
&lt;p class="Text"&gt;(Besides, if I&amp;#39;m animating a transition from one page to another, it makes my head hurt conceptualizing that fact that I only have one page at time in the traditional transition model: the current page is destroyed and then the new page is materialized. With my technique, we actually have all of the physical page UserControls sitting next to each other; it&amp;#39;s much easier to conceive and work with.) &lt;/p&gt;
&lt;p class="Text"&gt;The only problem is that it doesn&amp;#39;t work. That is, we need to do a little more than simply ignore the frame&amp;#39;s content. Without a custom loader in place, Silverlight&amp;#39;s default frame loader will still &amp;quot;try&amp;quot; to navigate around, and with no content, blank pages will be displayed. So what I did was create a custom loader that EXPLICITLY loads nothing. It&amp;#39;s sort of like the different between a null string and an empty string where nulls are not supported. Leaving the frame &amp;quot;null&amp;quot; didn&amp;#39;t work; using a custom loader to ensure the frame that it was okay to be &amp;quot;empty&amp;quot; did the trick! Here&amp;#39;s what the loader looks like: &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;using&lt;/span&gt; System&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;using&lt;/span&gt; System&lt;span class="Operator"&gt;.&lt;/span&gt;Threading&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;using&lt;/span&gt; System&lt;span class="Operator"&gt;.&lt;/span&gt;Windows&lt;span class="Operator"&gt;.&lt;/span&gt;Controls&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;using&lt;/span&gt; System&lt;span class="Operator"&gt;.&lt;/span&gt;Windows&lt;span class="Operator"&gt;.&lt;/span&gt;Navigation&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;namespace&lt;/span&gt; UI&lt;span class="Operator"&gt;.&lt;/span&gt;Infrastructure&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="Keyword"&gt;class&lt;/span&gt; &lt;span class="ClassName"&gt;NavigationListener&lt;/span&gt; &lt;span class="Operator"&gt;:&lt;/span&gt; &lt;span class="ClassName"&gt;INavigationContentLoader&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;#region&lt;/span&gt; Members&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;private&lt;/span&gt; &lt;span class="Keyword"&gt;class&lt;/span&gt; &lt;span class="ClassName"&gt;LoadAsyncResult&lt;/span&gt; &lt;span class="Operator"&gt;:&lt;/span&gt; &lt;span class="ClassName"&gt;IAsyncResult&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;#region&lt;/span&gt; Members&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="Keyword"&gt;object&lt;/span&gt; AsyncState &lt;span class="Operator"&gt;{&lt;/span&gt; &lt;span class="Keyword"&gt;get&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt; &lt;span class="Keyword"&gt;set&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt; &lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="ClassName"&gt;WaitHandle&lt;/span&gt; AsyncWaitHandle&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;get&lt;/span&gt; &lt;span class="Operator"&gt;{&lt;/span&gt; &lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt; &lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="Keyword"&gt;bool&lt;/span&gt; CompletedSynchronously&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;get&lt;/span&gt; &lt;span class="Operator"&gt;{&lt;/span&gt; &lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;true&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt; &lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="Keyword"&gt;bool&lt;/span&gt; IsCompleted&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;get&lt;/span&gt; &lt;span class="Operator"&gt;{&lt;/span&gt; &lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;true&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt; &lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;#endregion&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;#endregion&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;#region&lt;/span&gt; Public Methods&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="ClassName"&gt;IAsyncResult&lt;/span&gt; BeginLoad&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Uri&lt;/span&gt; targetUri&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;Uri&lt;/span&gt; currentUri&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;AsyncCallback&lt;/span&gt; userCallback&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;object&lt;/span&gt; asyncState&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//oblige callback&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;userCallback&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;LoadAsyncResult&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;{&lt;/span&gt; AsyncState &lt;span class="Operator"&gt;=&lt;/span&gt; asyncState &lt;span class="Operator"&gt;}&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//fake result&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="Keyword"&gt;bool&lt;/span&gt; CanLoad&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Uri&lt;/span&gt; targetUri&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;Uri&lt;/span&gt; currentUri&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//TODO: security?&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;true&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="Keyword"&gt;void&lt;/span&gt; CancelLoad&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;IAsyncResult&lt;/span&gt; asyncResult&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//TODO: cancellation?&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="ClassName"&gt;LoadResult&lt;/span&gt; EndLoad&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;IAsyncResult&lt;/span&gt; asyncResult&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//fake result&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;LoadResult&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;Page&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;#endregion&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;As you can tell, this is more or less a fake class. The only notable lines are #35, where we actually return null for the result (which is okay) and #49, where we return a harmless new Page as our content. You&amp;#39;ll see why we need &lt;span class="Italic"&gt;something&lt;/span&gt; there later, even though the frame in XAML is collapsed. But that&amp;#39;s it. The rest of it is fluff to embody the interface. Even our implementation of &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.iasyncresult(v=VS.95).aspx" class="Link"&gt;IAsyncResult&lt;/a&gt; with LoadAsyncResult (Line #&amp;#39;s 10-27) is fake; it&amp;#39;s the bare minimum we need to get the meaningless IAsyncResult we need to pass our fake Page. It&amp;#39;s actually kind of depressing how abusive I am to this sub-system; all this work to nullify its functionality. &lt;/p&gt;
&lt;p class="Text"&gt;So right now, we have a frame that&amp;#39;s properly updating the browser&amp;#39;s history as we nav around the app, but isn&amp;#39;t showing anything. Next we need to wire in the event handlers so that we can tell our panel how to animate our pages. On your frame, handle any of the following events, per your requirements: &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;ul class="Text"&gt;
&lt;li class="Text"&gt;Navigating&lt;/li&gt;
&lt;li class="Text"&gt;Navigated&lt;/li&gt;
&lt;li class="Text"&gt;NavigationFailed&lt;/li&gt;
&lt;li class="Text"&gt;NavigationStopped&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;The first two adhere to the familiar .NET event &amp;quot;-ing&amp;quot; and &amp;quot;-ed&amp;quot; paring pattern. &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.frame.navigating(v=VS.95).aspx" class="Link"&gt;Navigating&lt;/a&gt; fires first, and like other &amp;quot;-ing&amp;quot; events, gives you the opportunity to cancel the navigation. The event args (&lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.navigation.navigatingcanceleventargs(v=VS.95).aspx" class="Link"&gt;NavigatingCancelEventArgs&lt;/a&gt;) contain the new Uri. If you keep track of the current Uri in your code behind (or custom navigation panel, as I did) and have a mechanism to associate your page user controls to URIs (via attribution on the user control itself, as I did), you can pretty easily come up with a nice little &amp;quot;page lifecycle&amp;quot; model for your controls. In fact, all of my pages (which, as I will keep reminding you, are normal UserControls, not Silverlight Pages) have a custom attribute that provides metadata containing which URL each responds to, an ordinal to make calculating coordinates easier, etc. &lt;/p&gt;
&lt;p class="Text"&gt;The code behind of each such page control looks like this: &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;[&lt;/span&gt;&lt;span class="ClassName"&gt;NavPage&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;/NewCustomerForm&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; 1&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="Keyword"&gt;partial&lt;/span&gt; &lt;span class="Keyword"&gt;class&lt;/span&gt; &lt;span class="ClassName"&gt;NewCustomerPage&lt;/span&gt; &lt;span class="Operator"&gt;:&lt;/span&gt; &lt;span class="ClassName"&gt;UserControl&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;So when Navigating fires, I will use the &lt;span class="Italic"&gt;current&lt;/span&gt; Uri to pull the corresponding UserControl from my panel via reflection. (Basically, find everything decorated with &amp;quot;NavPage&amp;quot; in my panel, and give me the one whose Uri matches.) Then I could do things like error validation, clean up, etc. on the current control, and, using the Uri from the event args, pull the destination control and start loading data. Finally, we kick off the animation. &lt;/p&gt;
&lt;p class="Text"&gt;Here&amp;#39;s what the frame looks like in XAML: &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;navigation&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt;&lt;span class="Keyword"&gt;Frame&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;x&lt;span class="Operator"&gt;:&lt;/span&gt;Name&lt;/span&gt;&lt;span class="Operator"&gt;=&amp;quot;&lt;/span&gt;frmContent&lt;span class="Operator"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;Visibility&lt;/span&gt;&lt;span class="Operator"&gt;=&amp;quot;&lt;/span&gt;Collapsed&lt;span class="Operator"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;Navigating&lt;/span&gt;&lt;span class="Operator"&gt;=&amp;quot;&lt;/span&gt;frmContent_Navigating&lt;span class="Operator"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;NavigationFailed&lt;/span&gt;&lt;span class="Operator"&gt;=&amp;quot;&lt;/span&gt;frmContent_NavigationFailed&lt;span class="Operator"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;navigation&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt;&lt;span class="Keyword"&gt;Frame.ContentLoader&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;infrastructure&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt;&lt;span class="Keyword"&gt;NavigationListener&lt;/span&gt; &lt;span class="Operator"&gt;/&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Operator"&gt;/&lt;/span&gt;&lt;span class="Keyword"&gt;navigation&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt;&lt;span class="Keyword"&gt;Frame.ContentLoader&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;navigation&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt;&lt;span class="Keyword"&gt;Frame.UriMapper&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;uriMapper&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt;&lt;span class="Keyword"&gt;UriMapper&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;uriMapper&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt;&lt;span class="Keyword"&gt;UriMapping&lt;/span&gt;&lt;span class="ClassName"&gt; Uri&lt;/span&gt;&lt;span class="Operator"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;&amp;quot;&lt;/span&gt;&lt;span class="ClassName"&gt; MappedUri&lt;/span&gt;&lt;span class="Operator"&gt;=&amp;quot;&lt;/span&gt;/Views/Home.xaml&lt;span class="Operator"&gt;&amp;quot;&lt;/span&gt; &lt;span class="Operator"&gt;/&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;&amp;lt;!-- other page mappings here --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Operator"&gt;/&lt;/span&gt;&lt;span class="Keyword"&gt;uriMapper&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt;&lt;span class="Keyword"&gt;UriMapper&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Operator"&gt;/&lt;/span&gt;&lt;span class="Keyword"&gt;navigation&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt;&lt;span class="Keyword"&gt;Frame.UriMapper&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Operator"&gt;/&lt;/span&gt;&lt;span class="Keyword"&gt;navigation&lt;/span&gt;&lt;span class="Operator"&gt;:&lt;/span&gt;&lt;span class="Keyword"&gt;Frame&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;Canvas&lt;/span&gt;&lt;span class="ClassName"&gt; x&lt;span class="Operator"&gt;:&lt;/span&gt;Name&lt;/span&gt;&lt;span class="Operator"&gt;=&amp;quot;&lt;/span&gt;canNavPanel&lt;span class="Operator"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;Canvas.Clip&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;&amp;lt;!-- something here to hide controls that are &amp;quot;off the screen&amp;quot; --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Operator"&gt;/&lt;/span&gt;&lt;span class="Keyword"&gt;Canvas.Clip&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;&amp;lt;!-- page here at (X,Y) --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;&amp;lt;!-- page here at (X,Y + 500 or however much needed to be off screen) --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Operator"&gt;/&lt;/span&gt;&lt;span class="Keyword"&gt;Canvas&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;Line #&amp;#39;s 6 - 8 tell the frame to use our custom navigation content loader (an instance of &amp;quot;NavigationListener&amp;quot; defined arbitrarily with the XAML namespace &amp;quot;infrastructure&amp;quot;). And notice Line #3 that makes the frame itself invisible, allowing the Canvas to take its place in the UI. &lt;/p&gt;
&lt;p class="Text"&gt;It should be pointed out that I didn&amp;#39;t handle the frame&amp;#39;s &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.frame.navigated(VS.95).aspx" class="Link"&gt;Navigated&lt;/a&gt; event in this case. (Note that this is what fires the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.page.onnavigatedto(VS.95).aspx" class="Link"&gt;OnNavigatedTo&lt;/a&gt; event in standard Silverlight Pages.) If you do use this event, make sure that any initialization work you do in your destination control isn&amp;#39;t intense enough to make your transition animation choppy. It&amp;#39;s for this reason that I hooked the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.media.animation.timeline.completed(v=VS.95).aspx" class="Link"&gt;Completed&lt;/a&gt; event of my animation&amp;#39;s &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.media.animation.storyboard(VS.95).aspx" class="Link"&gt;Storyboard&lt;/a&gt; and used that to tell the destination control that it&amp;#39;s currently on stage. &lt;/p&gt;
&lt;p class="Text"&gt;Now that all of this is wired up, when the URL changes (including deep linked, SEO-happy URLs) the navigation logic will flow as follows: &lt;/p&gt;
&lt;p class="Text"&gt;The frame detects the URL change and gets a relative path to the destination XAML file from the UriMapper. It then forwards this information to its INavigationContentLoader and raises the Navigating event. The navigation content loader has a few opportunities to cancel the navigation, and if it does, the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.frame.navigationstopped(v=VS.95).aspx" class="Link"&gt;NavigationStopped&lt;/a&gt; event is fired. (This will also fire if the user changes the URL again during the processing of the new page.) Otherwise, it will asynchronously load the new page, and the frame will raise Navigated when the new content is ready. Finally, if anything is amiss, the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.frame.navigationfailed(v=VS.95).aspx" class="Link"&gt;NavigationFailed&lt;/a&gt; event occurs. &lt;/p&gt;
&lt;p class="Text"&gt;So that&amp;#39;s how browser integration works. What if we wanted one page to be able to navigate to another? No sweat. The navigation frame has a lot of &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.hyperlinkbutton(VS.95).aspx" class="Link"&gt;HyperlinkButton&lt;/a&gt; behavior built into it, most notably, its &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/ms602275(v=VS.95).aspx" class="Link"&gt;Navigate&lt;/a&gt; method. Pass this puppy a Uri that the UriMapper can deal with and our navigation logic works as advertised. All we have to do is expose this as a utility method either directly in chrome (hacky) or have it all abstracted into a navigation behavior (elegant). I went with the hacky approach, as this entire mess evolved over time in Visual Studio as requirements changed on us, instead of being born fully mature on a whiteboard. &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="Keyword"&gt;bool&lt;/span&gt; NaviateToPage&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;string&lt;/span&gt; relativeUri&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//navigate&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;frmContent&lt;span class="Operator"&gt;.&lt;/span&gt;Navigate&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;Uri&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;relativeUri&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;UriKind&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Relative&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;Just one problem: as all of this browser integration goodness was happening, I found a bug; the browser tab&amp;#39;s title was being set to the relative path of the page! Since most users won&amp;#39;t notice the URL changing (no doubt transfixed on the beautiful page transitions) then we really lose the UX of being on a &lt;span class="Italic"&gt;different page&lt;/span&gt;, browser-wise, after each animation. Even the clicking sound your browser makes when a link is followed adds to this experience. I was able to trace the problem down to the fake Page we were returning from the custom nav content loader. Silverlight Pages (which extend UserControl directly) add a &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.page.title(v=VS.95).aspx" class="Link"&gt;Title&lt;/a&gt; property, which ultimately has the same functionality as the &amp;quot;title&amp;quot; tag in an HTML page&amp;#39;s &amp;quot;header.&amp;quot; The fake page I returned to the navigation frame had a blank title, which the Silverlight Navigation Framework must default to the URL. So the solution was simple: grab the frame, then grab the frame&amp;#39;s content (which is the instantiated fake page), and then grab the frame&amp;#39;s content&amp;#39;s title and set it. Set it to what? Whatever you want. You can add the title of each page to the custom attribute decorating our user controls, infer it from the Uri, etc. &lt;/p&gt;
&lt;p class="Text"&gt;Here&amp;#39;s a hypothetical idea of what the frame&amp;#39;s Navigating event could look like, assuming all of our page user controls implement some interface named &amp;quot;ISomePageUserControlInterface,&amp;quot; for example. (This is another option you can do to go along with the custom attribution of these controls we discussed earlier.) &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;private&lt;/span&gt; &lt;span class="Keyword"&gt;void&lt;/span&gt; frmContent_Navigating&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;object&lt;/span&gt; sender&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;NavigatingCancelEventArgs&lt;/span&gt; e&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//[pseudo-code example validation logic of current page]&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;ISomePageUserControlInterface&lt;/span&gt; currentPage &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;MethodToGetPageUserControlByURL&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_variableHoldingCurrentURL&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;!&lt;/span&gt;currentPage&lt;span class="Operator"&gt;.&lt;/span&gt;Validate&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//cancel&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;e&lt;span class="Operator"&gt;.&lt;/span&gt;Cancel &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;true&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//...&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//[pseudo-code example load logic of new page]&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;ISomePageUserControlInterface&lt;/span&gt; newPage &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;MethodToGetPageUserControlByURL&lt;span class="Operator"&gt;(&lt;/span&gt;e&lt;span class="Operator"&gt;.&lt;/span&gt;Uri&lt;span class="Operator"&gt;.&lt;/span&gt;ToString&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;newPage&lt;span class="Operator"&gt;.&lt;/span&gt;Load&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//...&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//begin invoke this so that the content is loaded before we nav to it (needed when app doesn&amp;#39;t start on home page (if we have been deep linked))&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Dispatcher&lt;span class="Operator"&gt;.&lt;/span&gt;BeginInvoke&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;=&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//set new page title on content of frame&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Page&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;frmContent&lt;span class="Operator"&gt;.&lt;/span&gt;Content&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Title &lt;span class="Operator"&gt;=&lt;/span&gt; newPage&lt;span class="Operator"&gt;.&lt;/span&gt;Title&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;Additionally, you&amp;#39;d kick off your animation in this event handler, as well as perform any other cleanup / maintenance tasks (like setting &amp;quot;this._variableHoldingCurrentURL&amp;quot; to &amp;quot;e.Uri.ToString(),&amp;quot; etc.). &lt;/p&gt;
&lt;p class="Text"&gt;Well that&amp;#39;s about it: 100% custom animations for transitions between pages navigated to both internally and externally. And it&amp;#39;s really not all that much work; just a lot if indirection. It always amazes me how much a layer of abstraction can affect any system. The Silverlight Navigation Framework fools the browser into thinking it&amp;#39;s loading different pages. My custom navigation content loader fools the page into thinking it&amp;#39;s loading different controls. At this point, the poor user has no idea what&amp;#39;s going on behind the scenes (which is a good thing, probably, as lengthy and stunning animations can buy us up to two seconds (anything longer won&amp;#39;t fly) to load data). A colleague of mine always quotes the famous &lt;a target="_blank" class="Link"&gt;David Wheeler&lt;/a&gt; saying &amp;quot;All problems in computer science can be solved by another level of indirection.&amp;quot; This is good stuff; it is why, for example, I named my navigation content loader &amp;quot;NavigationListner&amp;quot; - it does just that: listens. It uses the navigation frame as a puppet to fire the events our UI needs to animate to new controls. It abstracts a layer of abstraction. &lt;/p&gt;
&lt;p class="Text"&gt;Have fun navigating! (Or, more accurately, &amp;quot;navigating.&amp;quot;) &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.rightpoint.com/community/aggbug.aspx?PostID=2828" width="1" height="1"&gt;</description><enclosure url="http://www.rightpoint.com" length="535923" type="application/x-zip-compressed" /><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Navigation/default.aspx">Navigation</category></item><item><title>The SUESS Lifecycle: Stage 1 - Upload</title><link>http://www.rightpoint.com/community/blogs/viewpoint/archive/2010/07/17/the-suess-lifecycle-stage-1-upload.aspx</link><pubDate>Sat, 17 Jul 2010 05:57:00 GMT</pubDate><guid isPermaLink="false">f7450ba4-a08e-465a-831a-f9a15c21b696:2809</guid><dc:creator>Chris Domino</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.rightpoint.com/community/blogs/viewpoint/rsscomments.aspx?PostID=2809</wfw:commentRss><comments>http://www.rightpoint.com/community/blogs/viewpoint/archive/2010/07/17/the-suess-lifecycle-stage-1-upload.aspx#comments</comments><description>&lt;p class="Text"&gt;
&lt;p class="Text"&gt;
&lt;p class="Text"&gt;&lt;span class="Underline"&gt;The SUESS Series&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" href="http://chrisdomino.com/blog/post/SUESS-A-Silverlight-Uploader-Encoder-and-Smooth-Streamer" class="Link"&gt;Introduction&lt;/a&gt; &lt;br /&gt;&lt;span class="Bold"&gt;Stage 1 - Upload&lt;/span&gt; &lt;br /&gt;&lt;a target="_blank" href="http://chrisdomino.com/blog/post/The-SUESS-Lifecycle-Stage-2-Encode" class="Link"&gt;Stage 2 - Encode&lt;/a&gt; &lt;br /&gt;&lt;a target="_blank" href="http://chrisdomino.com/blog/post/The-SUESS-Lifecycle-Stage-3-SmoothStreaming" class="Link"&gt;Stage 3 - SmoothStreaming&lt;/a&gt; &lt;/p&gt;
&lt;p class="Text"&gt;Our in-depth media adventure begins, well, at the beginning of the SUESS &amp;quot;lifecycle&amp;quot; with Uploading. This stage contains two sub-components: the Uploader Silverlight control, and the WCF service on the Web Server that facilitates the file upload process. The only prerequisite required here is to have your data tier (Component 3) in place (which can simply be a folder on the Web Server). &lt;/p&gt;
&lt;p class="Text"&gt;Of course, there is nothing new about a file upload control; it&amp;#39;s been in HTML longer than I have. Over the years, I&amp;#39;ve seen a lot of modifications to the familiar read only textbox and &amp;quot;Browse...&amp;quot; button to get the effects people are starting to expect in this whole Web 2.0 craze: progress bars, client-side file type filtering, large file support, etc. &lt;/p&gt;
&lt;p class="Text"&gt;To achieve these nice features, a lot of magic needs to happen client side. If you&amp;#39;ve read anything I&amp;#39;ve written before, you&amp;#39;ll know that I don&amp;#39;t consider AJAX to be magic; it&amp;#39;s voodoo at best compared to the wizardry of Silverlight. The argument remains the Silverlight needs to be installed on the client&amp;#39;s machine while AJAX comes down for free from the server along with the rest of the page. However, when it comes to programmatic benefits such as a first-class development experience (IntelliSense, compilation, UI designer, etc.), robustness of code, and extent of possibilities of what you can build, you cannot argue against Silverlight. &lt;/p&gt;
&lt;p class="Text"&gt;&lt;span class="Rant"&gt;&amp;lt;RANT&amp;gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Now don&amp;#39;t get me wrong: AJAX is a really cute technology that has a lot of niche uses. The difference, as far as I&amp;#39;m concerned, falls in the mindset of the developer. Take animating progress bars for example. In AJAX/HTML, you&amp;#39;d need to arrange a few nested divs, set all their widths and background colors, and then when the upload mechanism reports progress, update the width of the inner-most div. To me, that&amp;#39;s not really a true &lt;span class="Italic"&gt;progress bar&lt;/span&gt;; it&amp;#39;s HTML kludginess. &lt;/p&gt;
&lt;p class="Text"&gt;Now, in Silverlight, you see, you literally just &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc189090(VS.95).aspx" class="Link"&gt;animate&lt;/a&gt; a &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.progressbar(VS.95).aspx" class="Link"&gt;ProgressBar&lt;/a&gt;. &lt;/p&gt;
&lt;p class="Text"&gt;THAT&amp;#39;S the point. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;span class="Rant"&gt;&amp;lt;/RANT&amp;gt;&lt;/span&gt; &lt;/p&gt;
&lt;p class="Text"&gt;The example Uploader control I&amp;#39;ll show you shortly lacks all the bells and whistles with which it could be adorned to truly make the life of a content manager much better. These features include drag and drop support, multi-file uploads, a slick UI, etc. However, the big ones, like progress bars and cancellation, will demonstrate how uploading large files (such as media) can be a pleasant experience for a user. &lt;/p&gt;
&lt;p class="Text"&gt;First of all, what does it look like? Well, not much, unfortunately. A pretty admin UI was not a requirement of the project through which I came up with SUESS, since this was all back end functionality. But here&amp;#39;s what we have: &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;p class="Image"&gt;&lt;img src="http://chrisdomino.com/content/images/The-SUESS-Lifecycle-Stage-1-Upload/Uploader.png" class="Image" alt="" /&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;The title and description fields are watermarked textboxes with some gradient borders to implement the comps of the project. I really don&amp;#39;t want to bore you with the details of the code that updates the visual state of the UI; it&amp;#39;s hard to make hiding buttons and displaying error messages sexy. You&amp;#39;ll be able to download SUESS in its entirety and comb through all the details yourself. Instead, let&amp;#39;s take a quick trip through it, and then dive into the cool stuff. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;The only input we actually need from the user is the file itself. Depending on your data tier, you could accept more metadata. (SUESS was actually born into SharePoint, so the sky was the limit for metadata.) But for now, we&amp;#39;ll just have two optional textboxes for the name of the media and a description. If the name is blank, we&amp;#39;ll use the file name. (As you&amp;#39;ll see later, with the way Encoder outputs its SmoothStreaming formatted files, we don&amp;#39;t have to worry about filename collisions; it&amp;#39;s only a consideration during uploading.) &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Next we have the &amp;quot;Encoding Quality&amp;quot; drop down. Once again, this is optional, and included only as an example to show another aspect of what you can do with SUESS in terms of explicitly controlling a myriad of Encoder options. (You&amp;#39;ll see what I&amp;#39;m talking about in the Encoding post about SUESS.) These are hard-coded (barf, I know) values mimicking the Video Complexity (no documentation available) enumeration in the Encoder SDK. This is the best we can do to this extent, since we can&amp;#39;t actually reference the DLL in our Silverlight project and reflect each enum member. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;The purpose of including this in the example Uploader is to allow the user the ability to &amp;quot;throttle&amp;quot; the encoding process, which, as previously mentioned, could be very processor (and, of course, time) intensive. Unfortunately, I don&amp;#39;t have a lot of metrics regarding just how much quality is sacrificed in terms of time taken to encode. However, I can say that media encoded with the highest quality settings indeed takes much longer than with the lowest. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Finally, we have the media itself. Silverlight gives us the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.openfiledialog(VS.95).aspx" class="Link"&gt;OpenFileDialog&lt;/a&gt; control that is more or less identical to what you&amp;#39;d find in Windows Forms. The one immediate advantage it gives us over what is available in the HTML version is the ability to filter the file types (by extension) that the user is allowed to select in the dialog. This not only gives us a more elegant user experience (since we can &amp;quot;label&amp;quot; our filter with something like &amp;quot;Media Files,&amp;quot;) but also makes the development much easier, since we don&amp;#39;t have to go through the &amp;quot;hand slapping&amp;quot; input validation experience. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&lt;span class="Rant"&gt;&amp;lt;RANT&amp;gt;&lt;/span&gt; &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Back in the HTML/AJAX version of a file upload control, if you need to enforce a certain type (or types) of file(s), the best you can do is inspect the file the user selected, check its extension, and display an error message, forcing the user to have to go through the entire exercise again. Instead, with Silverlight, we can simply hide invalid file extensions in the folders they navigate within the dialog via the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.openfiledialog.filter(v=VS.95).aspx" class="Link"&gt;Filter&lt;/a&gt; property. This probably doesn&amp;#39;t seem like a big deal, but I think it&amp;#39;s huge: small UX improvements like these are what Web 2.0 is all about; with Silverlight, you are really using an application, not just a webpage. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&lt;span class="Rant"&gt;&amp;lt;/RANT&amp;gt;&lt;/span&gt; &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Let&amp;#39;s talk about a few of the more interesting code samples. The first one simply sets the OpenFileDialog to only allow the files that Encoder supports to be uploaded. It also has a hard coded value (which can easily be made to be configurable) to disallow files over 1GB (purely for sanity purposes). &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;private&lt;/span&gt; &lt;span class="Keyword"&gt;void&lt;/span&gt; btnSelectFile_Click&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;object&lt;/span&gt; sender&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;RoutedEventArgs&lt;/span&gt; e&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//initialization&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;OpenFileDialog&lt;/span&gt; ofd &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;OpenFileDialog&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//show open file dialog&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;ofd&lt;span class="Operator"&gt;.&lt;/span&gt;Multiselect &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;false&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;ofd&lt;span class="Operator"&gt;.&lt;/span&gt;Filter &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;Media Files|*.asf;*.avi;*.bmp;*.gif;*.jpg;*.jpeg;*.m2t;*.m2ts;*.mov;*.mp4;*.mpeg;*.mpg;*.png;*.tif;*.tiff;*.ts;*.vob;*.wmv;&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;bool&lt;/span&gt;&lt;span class="Operator"&gt;?&lt;/span&gt; fileSelected &lt;span class="Operator"&gt;=&lt;/span&gt; ofd&lt;span class="Operator"&gt;.&lt;/span&gt;ShowDialog&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//check for file&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;fileSelected&lt;span class="Operator"&gt;.&lt;/span&gt;HasValue &lt;span class="Operator"&gt;&amp;amp;&lt;/span&gt;&lt;span class="Operator"&gt;&amp;amp;&lt;/span&gt; fileSelected&lt;span class="Operator"&gt;.&lt;/span&gt;Value&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//check legth&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;ofd&lt;span class="Operator"&gt;.&lt;/span&gt;File&lt;span class="Operator"&gt;.&lt;/span&gt;Length &lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt; &lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_maxFileSize&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//(omitted UI code)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//file too large&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;tbProgress&lt;span class="Operator"&gt;.&lt;/span&gt;Text &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;You cannot upload a file larger than 500 MB.&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//(omitted UI code)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//start upload&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;StartUpload&lt;span class="Operator"&gt;(&lt;/span&gt;ofd&lt;span class="Operator"&gt;.&lt;/span&gt;File&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Line #7 above sets the Filter property of the OpenFileDialog to the Encoder 3 supported file types. This is what ensures that Encoder will be able to handle whatever the user throws at it. Line #15 shows that &amp;quot;UI&amp;quot; code has been omitted. You&amp;#39;ll see this in a lot the code samples throughout SUESS. Like I said, I don&amp;#39;t want to bore you with the details of dealing with &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.visualstate(VS.95).aspx" class="Link"&gt;VisualStates&lt;/a&gt; in the application. Here are some more action shots: &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;p class="Image"&gt;&lt;img src="http://chrisdomino.com/content/images/The-SUESS-Lifecycle-Stage-1-Upload/Uploading.png" class="Image" alt="" /&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;p class="Image"&gt;&lt;img src="http://chrisdomino.com/content/images/The-SUESS-Lifecycle-Stage-1-Upload/Analyzing.png" class="Image" alt="" /&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;p class="Image"&gt;&lt;img src="http://chrisdomino.com/content/images/The-SUESS-Lifecycle-Stage-1-Upload/Encoding.png" class="Image" alt="" /&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Next let&amp;#39;s look at the logic that implements the recursive &amp;quot;chunky&amp;quot; upload. If we send the entire file up to the server, we can&amp;#39;t show progress bars, and really don&amp;#39;t take advantage of client side functionality at all. Instead, the SUESS Uploader sends 1MB of the file up to the server at a time. After each call, the UI is updated with the current progress, and then the next &amp;quot;chunk&amp;quot; is uploaded. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Since all Silverlight service communication is done asynchronously, we need to daisy chain the &amp;quot;Completed&amp;quot; callback for each of these calls so that they are executed serially within it. Normally, if service calls can be done in parallel (such as downloading images or assembling the content of unselected tabs), you can kick off them all off at the same time; when they&amp;#39;re done, they&amp;#39;re done, and the corresponding part of the UI lights up. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Otherwise, if you need to call service A and then pass its result on to service B (or a subsequent call back to A, like the Uploader), then there will be some chaining going on. Here&amp;#39;s a quick diagram that demonstrates these two paradigms. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;p class="Image"&gt;&lt;img src="http://chrisdomino.com/content/images/The-SUESS-Lifecycle-Stage-1-Upload/Services.png" class="Image" alt="" /&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;In the top half, where we show &amp;quot;parallel&amp;quot; calls, all of the service references are explicit. We invoke a service, and when the associated completed event handler is fired, we do something back on the UI. What if we need to call the same service multiple (and in an unknowable amount of) times in a specific order? This is the case with the Uploader. Since we obviously can&amp;#39;t know the size of the file, then we further don&amp;#39;t know how many chunks we&amp;#39;ll be dealing with. We need to make these calls serially. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;The answer is recursion, as shown in the bottom half of the diagram. (Of course, this is only logical recursion, since the same physical method isn&amp;#39;t actually calling itself.) I experimented with some crazy iterative algorithms, but they got real messy real quick, and were all ultimately besmirched by the asynchronousity of Silverlight. Instead, I created a method that uploads a chunk (array of bytes) of a file, and when it&amp;#39;s done, increments a counter and progress bars. Finally, the same service is called again with the next chunk. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;This algorithm, other than being sweet at uploading files, makes two additional features of the Uploader trivial: real time progress bars and upload cancellation. We&amp;#39;ll discuss those next. First, however, let&amp;#39;s look at this code. This piece is the StartUpload method that the above code block calls to kick off the recursion. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;private&lt;/span&gt; &lt;span class="Keyword"&gt;void&lt;/span&gt; StartUpload&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;FileInfo&lt;/span&gt; file&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//(omitted UI code that resets progress bars, clears errors, etc.)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//start recursive upload&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_index &lt;span class="Operator"&gt;=&lt;/span&gt; 0&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_fileName &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Format&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;{0}-{1}&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;Guid&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;NewGuid&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; file&lt;span class="Operator"&gt;.&lt;/span&gt;Name&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;UploadFile&lt;span class="Operator"&gt;(&lt;/span&gt;file&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;true&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;The Boolean passed as the second parameter to UploadFile in Line #7 simply tells the algorithm this is the first chunk. UploadFile actually doesn&amp;#39;t care; it just passes this along to the service so that it knows whether to create a new file on the data tier or open an existing one. This can probably be inferred on the server rather than made explicit, but I didn&amp;#39;t want to have to burn an extra trip to the disk for each chunk if I didn&amp;#39;t have to. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Here&amp;#39;s the algorithm: &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;private&lt;/span&gt; &lt;span class="Keyword"&gt;void&lt;/span&gt; UploadFile&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;FileInfo&lt;/span&gt; file&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;bool&lt;/span&gt; isFirstChunk&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//initialization&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;byte&lt;/span&gt;&lt;span class="Operator"&gt;[&lt;/span&gt;&lt;span class="Operator"&gt;]&lt;/span&gt; buffer &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="Keyword"&gt;byte&lt;/span&gt;&lt;span class="Operator"&gt;[&lt;/span&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_bufferSize&lt;span class="Operator"&gt;]&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;MediaServiceSoapClient&lt;/span&gt; svc &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;Utilities&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;GetMediaClient&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//get chunk&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;using&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Stream&lt;/span&gt; data &lt;span class="Operator"&gt;=&lt;/span&gt; file&lt;span class="Operator"&gt;.&lt;/span&gt;OpenRead&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//write to buffer&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;data&lt;span class="Operator"&gt;.&lt;/span&gt;Seek&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_index&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;SeekOrigin&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Begin&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;data&lt;span class="Operator"&gt;.&lt;/span&gt;Read&lt;span class="Operator"&gt;(&lt;/span&gt;buffer&lt;span class="Operator"&gt;,&lt;/span&gt; 0&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_bufferSize&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//upload chunk&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;svc&lt;span class="Operator"&gt;.&lt;/span&gt;UploadFileChunkAsync&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_fileName&lt;span class="Operator"&gt;,&lt;/span&gt; buffer&lt;span class="Operator"&gt;,&lt;/span&gt; isFirstChunk&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;svc&lt;span class="Operator"&gt;.&lt;/span&gt;UploadFileChunkCompleted &lt;span class="Operator"&gt;+&lt;/span&gt;&lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;sender&lt;span class="Operator"&gt;,&lt;/span&gt; args&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;=&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//determine result&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;args&lt;span class="Operator"&gt;.&lt;/span&gt;Cancelled &lt;span class="Operator"&gt;|&lt;/span&gt;&lt;span class="Operator"&gt;|&lt;/span&gt; args&lt;span class="Operator"&gt;.&lt;/span&gt;Error &lt;span class="Operator"&gt;!&lt;/span&gt;&lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt; &lt;span class="Operator"&gt;|&lt;/span&gt;&lt;span class="Operator"&gt;|&lt;/span&gt; &lt;span class="Operator"&gt;!&lt;/span&gt;&lt;span class="Keyword"&gt;string&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;IsNullOrEmpty&lt;span class="Operator"&gt;(&lt;/span&gt;args&lt;span class="Operator"&gt;.&lt;/span&gt;Result&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//(error code very much truncated here; the above if statement should check each OR&amp;#39;ed condition separately and update the UI appropriately)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;else&lt;/span&gt; &lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_index &lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt; &lt;span class="Operator"&gt;-&lt;/span&gt;1&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//update text progress&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;double&lt;/span&gt; progress &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Convert&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;ToDouble&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_index&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;/&lt;/span&gt; &lt;span class="ClassName"&gt;Convert&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;ToDouble&lt;span class="Operator"&gt;(&lt;/span&gt;file&lt;span class="Operator"&gt;.&lt;/span&gt;Length&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;*&lt;/span&gt; 100&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;pbUpload&lt;span class="Operator"&gt;.&lt;/span&gt;IsIndeterminate &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;false&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;tbProgress&lt;span class="Operator"&gt;.&lt;/span&gt;Text &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Format&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;{0} / {1} MB uploaded...&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;Convert&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;ToDouble&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_index&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;/&lt;/span&gt; &lt;span class="ClassName"&gt;Convert&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;ToDouble&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_bufferSize&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;GetTotalSize&lt;span class="Operator"&gt;(&lt;/span&gt;file&lt;span class="Operator"&gt;.&lt;/span&gt;Length&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//animate value&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;Storyboard&lt;/span&gt; sb &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;Storyboard&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;DoubleAnimation&lt;/span&gt; da &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;DoubleAnimation&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;Storyboard&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;SetTarget&lt;span class="Operator"&gt;(&lt;/span&gt;da&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;pbUpload&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;Storyboard&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;SetTargetProperty&lt;span class="Operator"&gt;(&lt;/span&gt;da&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;PropertyPath&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;Value&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;sb&lt;span class="Operator"&gt;.&lt;/span&gt;Children&lt;span class="Operator"&gt;.&lt;/span&gt;Add&lt;span class="Operator"&gt;(&lt;/span&gt;da&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;da&lt;span class="Operator"&gt;.&lt;/span&gt;To &lt;span class="Operator"&gt;=&lt;/span&gt; progress&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//determine if we&amp;#39;ve reached the end of the file&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;file&lt;span class="Operator"&gt;.&lt;/span&gt;Length &lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt; &lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_index&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//pause and upload next chunk&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;Thread&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Sleep&lt;span class="Operator"&gt;(&lt;/span&gt;200&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_index &lt;span class="Operator"&gt;+&lt;/span&gt;&lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_bufferSize&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//recurse&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;UploadFile&lt;span class="Operator"&gt;(&lt;/span&gt;file&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;false&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//(omitted UI code)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//we&amp;#39;re done - start encoding&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;EncodeCompletedFile&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//animate progress&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;sb&lt;span class="Operator"&gt;.&lt;/span&gt;Begin&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//update canceled&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;ShowCancel&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;The first thing to point out here is the utility method in Line #5. This method is a nice Silverlight helper that alleviates the need to have to deal with the &amp;quot;ServiceReferences.ClientConfig&amp;quot; files that store the Service URLs and other WCF settings. Using this method allows you to promote your control from development through production without having to worry about maintaining it. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="Keyword"&gt;static&lt;/span&gt; &lt;span class="ClassName"&gt;MediaServiceSoapClient&lt;/span&gt; GetMediaClient&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//return&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;MediaServiceSoapClient&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Utilities&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;GetBinding&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;Utilities&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;GetAddress&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;Media&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Here are the two internal methods that build the WCF binding and get the URL of the service dynamically: &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;private&lt;/span&gt; &lt;span class="Keyword"&gt;static&lt;/span&gt; &lt;span class="ClassName"&gt;BasicHttpBinding&lt;/span&gt; GetBinding&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//initialization&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;BasicHttpBinding&lt;/span&gt; binding &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;BasicHttpBinding&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;BasicHttpSecurityMode&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;None&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//set timeout&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;binding&lt;span class="Operator"&gt;.&lt;/span&gt;SendTimeout &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;TimeSpan&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;FromHours&lt;span class="Operator"&gt;(&lt;/span&gt;1&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;binding&lt;span class="Operator"&gt;.&lt;/span&gt;OpenTimeout &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;TimeSpan&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;FromHours&lt;span class="Operator"&gt;(&lt;/span&gt;1&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;binding&lt;span class="Operator"&gt;.&lt;/span&gt;CloseTimeout &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;TimeSpan&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;FromHours&lt;span class="Operator"&gt;(&lt;/span&gt;1&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;binding&lt;span class="Operator"&gt;.&lt;/span&gt;ReceiveTimeout &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;TimeSpan&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;FromHours&lt;span class="Operator"&gt;(&lt;/span&gt;1&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//set messags sizes&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;binding&lt;span class="Operator"&gt;.&lt;/span&gt;MaxBufferSize &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;int&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;MaxValue&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;binding&lt;span class="Operator"&gt;.&lt;/span&gt;MaxReceivedMessageSize &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;int&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;MaxValue&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//return&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; binding&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;And the piece to get the service endpoint. (Note that since this example was lifted from a SharePoint implementation of SUESS, I had to be a bit creative with the URL.) &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;private&lt;/span&gt; &lt;span class="Keyword"&gt;static&lt;/span&gt; &lt;span class="ClassName"&gt;EndpointAddress&lt;/span&gt; GetAddress&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;string&lt;/span&gt; name&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//window.location.href&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;Uri&lt;/span&gt; uri &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;Uri&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;ScriptObject&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;HtmlPage&lt;span class="Operator"&gt;.&lt;/span&gt;Window&lt;span class="Operator"&gt;.&lt;/span&gt;GetProperty&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;location&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;GetProperty&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;href&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;ToString&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//return&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ClassName"&gt;EndpointAddress&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;string&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Format&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;{0}://{1}/_vti_bin/{2}Service.asmx&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; uri&lt;span class="Operator"&gt;.&lt;/span&gt;Scheme&lt;span class="Operator"&gt;,&lt;/span&gt; uri&lt;span class="Operator"&gt;.&lt;/span&gt;Host&lt;span class="Operator"&gt;,&lt;/span&gt; name&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;The rest of the main algorithm is actually pretty straight forward. The recursiveness happens in lines 39 through 42. We pause a bit in Line #39 so that Silverlight doesn&amp;#39;t try to open the file from a new thread before the previous one properly closed it, increment the index of where we &amp;quot;are&amp;quot; in the file, and then recursively call the service. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;How do we break out of the recursion? Three things can happen. First of all, if something goes terribly wrong on the server or some other exception is thrown, it will be caught on Line #20, handled, and then we&amp;#39;ll hard return out of the method. (Again, since this isn&amp;#39;t physical recursion, we don&amp;#39;t have any stack trace &amp;quot;depth&amp;quot; to worry about.) Otherwise, we use the index. If it&amp;#39;s greater than or equal to the length of the file, we know we&amp;#39;ve uploaded all the bytes: break out here, and start encoding. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;The final way is through cancelation, which is one of the big features the Uploader. I know this isn&amp;#39;t anything amazing, but it&amp;#39;s another example of something that&amp;#39;s pretty easy in Silverlight and probably pretty tough in HTML. As someone who&amp;#39;s been in and around SharePoint for years, I&amp;#39;ve seen a lot of large file uploads quietly timeout after watching the page spin for ten minutes. That sort of behavior is not good enough; we need a big red self-destruct button to make sure we can cleanly stop an upload. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;So as all this asynchronous uploading is happening on background threads, how do we cancel it from the click event of a cancel button on the UI thread? It turns out that it just works. Silverlight will automatically fire the completed event for a service call on the correct thread, alleviating the need for any dispatching. Since we don&amp;#39;t have to worry about any cross threading, we can jump right in with the logic. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;The Uploader cancel button click does two things. First, it simply sets the aforementioned index to -1, which basically throws a wrench in the recursive gears. Since all of our calls are on the same thread, we can check this index, see that we&amp;#39;ve been cancelled, and, well, stop making calls. This is all the housekeeping we need on the client. But what about the server? &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;The second cancellation task is to make one more call that tells the server that this upload has been cancelled so it can clean up the file. This is one of the reasons for the intermediate &amp;quot;upload&amp;quot; folder on the server: we never had to worry about IIS serving fragments of files. Other than cancellation, dropped connections will also leave broken files on the server. If the upload connections die, then we obviously won&amp;#39;t be able to make another call to tell the server to clean up this file. Here is where the cleanup job finishes up for us. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;This is a good transition to start looking at server code. We&amp;#39;ll begin with the CancelFile method: &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;[&lt;/span&gt;&lt;span class="ClassName"&gt;WebMethod&lt;/span&gt;&lt;span class="Operator"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt; CancelFile&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;string&lt;/span&gt; path&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//initialization&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;string&lt;/span&gt; result &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Empty&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;path &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;Path&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Combine&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;GetTempUploadPath&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; path&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//impersonation&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;SPSecurity&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;RunWithElevatedPrivileges&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;=&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//delete&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;File&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Exists&lt;span class="Operator"&gt;(&lt;/span&gt;path&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;File&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Delete&lt;span class="Operator"&gt;(&lt;/span&gt;path&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;catch&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Exception&lt;/span&gt; ex&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//(error code omitted)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//return&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; result&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;The interesting thing going on here is in Line #8 where I elevate to run as the SharePoint app pool account. This is important for two reasons (neither of which, of course, are what the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spsecurity.runwithelevatedprivileges.aspx" class="Link"&gt;RunWithElevatedPrivileges&lt;/a&gt; delegate is designed to do). First of all, we don&amp;#39;t have to assign &amp;quot;Everyone&amp;quot; permissions on our folders. Second, it gets us around a potential &lt;a target="_blank" href="http://blogs.iis.net/owscott/archive/2008/08/22/iis-windows-authentication-and-the-double-hop-issue.aspx" class="Link"&gt;IIS double hop&lt;/a&gt; issue, in case the GetTempUploadPath method (which is a wrapper around a config file call) returns a UNC path. (Kerberos is the right way to deal with IIS double hops, but that seems to be more configuration than most people - including me - are willing to deal with). &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Next we have the method that accepts a chunk from the client and builds a file on the destination server: &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;[&lt;/span&gt;&lt;span class="ClassName"&gt;WebMethod&lt;/span&gt;&lt;span class="Operator"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt; UploadFileChunk&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;string&lt;/span&gt; path&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;byte&lt;/span&gt;&lt;span class="Operator"&gt;[&lt;/span&gt;&lt;span class="Operator"&gt;]&lt;/span&gt; data&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;bool&lt;/span&gt; isFirstChunk&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//initialization&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;string&lt;/span&gt; result &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Empty&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;Action&lt;/span&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ClassName"&gt;&lt;span class="Keyword"&gt;object&lt;/span&gt;&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt; uploadCode &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;path &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;Path&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Combine&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;GetTempUploadPath&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; path&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//impersonation&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;SPSecurity&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;RunWithElevatedPrivileges&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;=&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//determine if this is the first request&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;isFirstChunk&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//delete&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;File&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Exists&lt;span class="Operator"&gt;(&lt;/span&gt;path&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:50px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;File&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Delete&lt;span class="Operator"&gt;(&lt;/span&gt;path&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//determine if file exits&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;File&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Exists&lt;span class="Operator"&gt;(&lt;/span&gt;path&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//add chunk to existing file&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;uploadCode &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;o&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;=&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:50px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//open file&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:50px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;using&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;FileStream&lt;/span&gt; fs &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;File&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Open&lt;span class="Operator"&gt;(&lt;/span&gt;path&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;FileMode&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Open&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:50px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:60px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//write chunk&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:60px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;WriteChunk&lt;span class="Operator"&gt;(&lt;/span&gt;fs&lt;span class="Operator"&gt;,&lt;/span&gt; data&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:50px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//create new file&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;uploadCode &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;o&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;=&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:50px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//open file&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:50px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;using&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;FileStream&lt;/span&gt; fs &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;File&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Create&lt;span class="Operator"&gt;(&lt;/span&gt;path&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:50px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:60px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//write chunk&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:60px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;WriteChunk&lt;span class="Operator"&gt;(&lt;/span&gt;fs&lt;span class="Operator"&gt;,&lt;/span&gt; data&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:50px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//upload&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;Utils&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;ForceRetryFunction&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;object&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;Exception&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;=&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt; &lt;span class="Operator"&gt;{&lt;/span&gt; uploadCode&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt; &lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt; &lt;span class="Operator"&gt;}&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;&amp;quot;MediaService.UploadFileChunk&amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Concat&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Constant"&gt;&amp;quot;The following error occured while uploading &amp;quot;&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; path&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;catch&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Exception&lt;/span&gt; ex&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//(error code omitted)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//return&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; result&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;There are a couple of things to note here. First of all, you&amp;#39;ll notice that I use an &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/018hxwa8.aspx" class="Link"&gt;Action&lt;/a&gt; delegate to pass the blocks of code that do the file writing (WriteChunk will be displayed shortly) to a method in Line #48 called ForceRetryFunction. This method takes in a &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/bb534960.aspx" class="Link"&gt;Func&lt;/a&gt; (that is passed via an anonymous method in the invocation) which is basically processed in a while loop until it doesn&amp;#39;t throw the type of exception (that is generically passed in as well). There are few other operations in the system that spawned SUESS, so I refactored it into ForceRetryMethod. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;But WHY? Simply because certain operations need to be kicked in the ass to work. In this example, with I/O happening on several threads really fast, .NET can step on itself and open the file before it&amp;#39;s properly closed (just like on the client). I&amp;#39;ll put the code here for fun because it&amp;#39;s a pretty cool algorithm, but the details are outside the scope of SUESS. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="Keyword"&gt;static&lt;/span&gt; &lt;span class="ClassName"&gt;T&lt;/span&gt; ForceRetryFunction&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ClassName"&gt;T&lt;/span&gt;&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;E&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Func&lt;/span&gt;&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ClassName"&gt;T&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt; code&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt; sender&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt; description&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Keyword"&gt;where&lt;/span&gt; &lt;span class="ClassName"&gt;E&lt;/span&gt; &lt;span class="Operator"&gt;:&lt;/span&gt; &lt;span class="ClassName"&gt;Exception&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//initialization&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;int&lt;/span&gt; sleep &lt;span class="Operator"&gt;=&lt;/span&gt; 500&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;bool&lt;/span&gt; worked &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;false&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;T&lt;/span&gt; result &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;default&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;T&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;DateTime&lt;/span&gt; now &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;DateTime&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;UtcNow&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//keep trying&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;while&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;!&lt;/span&gt;worked&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//run the code&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;result &lt;span class="Operator"&gt;=&lt;/span&gt; code&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//code successful&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;worked &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;true&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;catch&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;E&lt;/span&gt; ex&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//only try for one minute&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;DateTime&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;UtcNow&lt;span class="Operator"&gt;.&lt;/span&gt;Subtract&lt;span class="Operator"&gt;(&lt;/span&gt;now&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;TotalMinutes &lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt; 1&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//unable to save&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//(error code omitted)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;worked &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;true&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//method blew up: sleep and try again&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;lock&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Utils&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_random&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:50px;"&gt;&lt;span class="Code"&gt;sleep &lt;span class="Operator"&gt;*&lt;/span&gt;&lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="ClassName"&gt;Convert&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;ToInt32&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;1&lt;span class="Operator"&gt;.&lt;/span&gt;5 &lt;span class="Operator"&gt;+&lt;/span&gt; &lt;span class="ClassName"&gt;Utils&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;_random&lt;span class="Operator"&gt;.&lt;/span&gt;NextDouble&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//sleep exponentially&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:40px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;Thread&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Sleep&lt;span class="Operator"&gt;(&lt;/span&gt;sleep&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:30px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//return&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; result&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;After all the trying, retrying, locking, and checking, the actual &lt;span class="Italic"&gt;work&lt;/span&gt; that the server performs can be boiled down the simplest method in this section: WriteChunk. Here&amp;#39;s the little guy: &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;private&lt;/span&gt; &lt;span class="Keyword"&gt;void&lt;/span&gt; WriteChunk&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;FileStream&lt;/span&gt; fs&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;byte&lt;/span&gt;&lt;span class="Operator"&gt;[&lt;/span&gt;&lt;span class="Operator"&gt;]&lt;/span&gt; buffer&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//seek to end of the file&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;fs&lt;span class="Operator"&gt;.&lt;/span&gt;Seek&lt;span class="Operator"&gt;(&lt;/span&gt;0&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="ClassName"&gt;SeekOrigin&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;End&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//write chunk&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;fs&lt;span class="Operator"&gt;.&lt;/span&gt;Write&lt;span class="Operator"&gt;(&lt;/span&gt;buffer&lt;span class="Operator"&gt;,&lt;/span&gt; 0&lt;span class="Operator"&gt;,&lt;/span&gt; buffer&lt;span class="Operator"&gt;.&lt;/span&gt;Length&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Very straight forward, and unfortunately, a rather anticlimactic way to end our discussion of the SUESS Uploader. Once the file is up on the server, the Uploader&amp;#39;s only remaining task is to kick off the Encoder stage. This is where all the really cool stuff happens, so stay tuned for the next post! &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Have fun! &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.rightpoint.com/community/aggbug.aspx?PostID=2809" width="1" height="1"&gt;</description><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/IIS+SmoothStreaming/default.aspx">IIS SmoothStreaming</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Expression+Encoder/default.aspx">Expression Encoder</category></item><item><title>SUESS: A Silverlight Uploader, Encoder, and Smooth Streamer</title><link>http://www.rightpoint.com/community/blogs/viewpoint/archive/2010/06/13/suess-a-silverlight-uploader-encoder-and-smooth-streamer.aspx</link><pubDate>Sun, 13 Jun 2010 19:18:00 GMT</pubDate><guid isPermaLink="false">f7450ba4-a08e-465a-831a-f9a15c21b696:2801</guid><dc:creator>Chris Domino</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.rightpoint.com/community/blogs/viewpoint/rsscomments.aspx?PostID=2801</wfw:commentRss><comments>http://www.rightpoint.com/community/blogs/viewpoint/archive/2010/06/13/suess-a-silverlight-uploader-encoder-and-smooth-streamer.aspx#comments</comments><description>&lt;p class="Text"&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&lt;span class="Underline"&gt;The SUESS Series&lt;/span&gt; &lt;/p&gt;
&lt;p class="Text"&gt;&lt;span class="Bold"&gt;Introduction&lt;/span&gt; &lt;/p&gt;
&lt;p class="Text"&gt;&lt;a target="_blank" href="http://chrisdomino.com/blog/post/The-SUESS-Lifecycle-Stage-1-Upload" class="Link"&gt;Stage 1 - Upload&lt;/a&gt; &lt;/p&gt;
&lt;p class="Text"&gt;&lt;a target="_blank" href="http://chrisdomino.com/blog/post/The-SUESS-Lifecycle-Stage-2-Encode" class="Link"&gt;Stage 2 - Encode&lt;/a&gt; &lt;/p&gt;
&lt;p class="Text"&gt;&lt;a target="_blank" href="http://chrisdomino.com/blog/post/The-SUESS-Lifecycle-Stage-3-SmoothStreaming" class="Link"&gt;Stage 3 - SmoothStreaming&lt;/a&gt; &lt;/p&gt;
&lt;p class="Text"&gt;When Silverlight first came out, I was initially excited simply because, as I told my colleagues, &amp;quot;Now, we can do all that Flashy stuff too!&amp;quot; Growing up a .NET developer, my task lists contained to-do items such as building reports, optimizing algorithms, and modeling business objects; designing animations, playing videos, and encoding media were simply not part of my life. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;I remember when media first started popping up on websites years ago. &amp;quot;How the &lt;span class="Italic"&gt;hell&lt;/span&gt; do you write a &lt;span class="Italic"&gt;movie&lt;/span&gt; player?&amp;quot; I thought to myself, mesmerized by whatever banner ad first showed off the possibilities of the technology to me. Little did I ever think that the ability to do cool stuff like that (back when people actually tried to shoot the dancing monkey in ads to win a free XBox) would find its way to the Microsoft stack upon which I teetered uncomfortably, at times, looking out at an uninterrupted future of stored procedures and service references. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Oh but it did! And in true Microsoft fashion, they not only made this stuff &lt;span class="Italic"&gt;possible&lt;/span&gt;, they made it &lt;span class="Italic"&gt;easy&lt;/span&gt;. So what&amp;#39;s the answer to the exasperated question I asked above? It takes one little line of XAML to write a movie player. I was almost disappointed at how simple it was; the ease of such an implementation was a little anticlimactic. When I first learned basic programming concepts such as OO and recursion in high school, it was hard! When I taught myself SharePoint (2003), for example, I felt as though I had really endured a rite of passage. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;But one line of XAML? Ok, I guess. Looks like I&amp;#39;m a Web 2.0 developer now... &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;How quickly I forget what it really means to be in the Microsoft development paradigm. Version (n) of a technology makes the old selling points of version (n-1) trivial, and the future selling points of version (n+1) possible. So now that playing media is easy, we can spend more time solving the ancillary problems that are now feasibly solvable. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Where do the movies that we can now play come from? Where do we put them? Does Silverlight support them? How do we make the viewing experience decent for all users across the Internet? Once we make it possible to &lt;span class="Italic"&gt;play&lt;/span&gt; media, we need to keep right on going and implement every step of what I call &lt;span class="Bold"&gt;SUESS&lt;/span&gt; or the Silverlight Uploader, Encoder, and Smooth Streamer. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;SUESS is a process that handles not only playing media, but uploading and encoding it as well. It takes advantage of several cutting edge technologies to do this: Silverlight 4, WCF, Expression Encoder, and IIS Media Services (both of the later were in version 3 at the time of this writing). The details of building each piece of SUESS are scattered around the Internet in various blogs and forums. My goal here is to bring them all together and show how these technologies interoperate to deliver a true, full featured media solution. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Architecturally speaking, SUESS has a lot of moving parts, but they all fit together very nicely. Let&amp;#39;s start with everyone&amp;#39;s favorite Visio architecture diagram: &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;p class="Image"&gt;&lt;img src="http://chrisdomino.com/content/images/SUESS-A-Silverlight-Uploader-Encoder-and-Smooth-Streamer/Architecture.png" class="Image" alt="" /&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Following is a description of all of SUESS&amp;#39;s constituent components, and the interactions among them. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&lt;span class="Underline"&gt;Components&lt;/span&gt; &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;The &amp;quot;components&amp;quot; section describes the system from the perspective of each machine&amp;#39;s logical role. Grammatically, these are the nouns, where the following &amp;quot;interactions&amp;quot; section outlines the verbs. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;ul class="Text"&gt;
&lt;li class="Text"&gt;&lt;span class="Bold"&gt;Component 1: Client&lt;/span&gt; - The Client obviously is the user&amp;#39;s machine, where all Silverlight code runs. SUESS begins and ends here, starting with the file upload, and ending with viewing the media. The Uploader control is straight Silverlight and .NET on the client, using WCF to communicate with the Web and Media Servers. Both of these interactions (uploading and encoding) could be very long running, and employ progress bars to keep user&amp;#39;s blood pressures down. The later uses Silverlight 4&amp;#39;s new support for the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/ms731064.aspx" class="Link"&gt;WCF Polling Duplex&lt;/a&gt; (bi-directional) binding, enabling the server to initiate calls and beam data down to the client!&lt;br /&gt;The media viewer is another story. The out-of-the-box &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement(VS.95).aspx" class="Link"&gt;MediaElement&lt;/a&gt; does not support the IIS SmoothStreaming format. I was pretty surprised to discover that, after building this entire infrastructure to convert media into a format that was designed &lt;span class="Italic"&gt;specifically for Silverlight&lt;/span&gt;, Silverlight didn&amp;#39;t even support it out-of-the-box! The answer is actually part of the IIS SmoothStreaming SDK, which gives us the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/microsoft.web.media.smoothstreaming.smoothstreamingmediaelement(VS.90).aspx" class="Link"&gt;SmoothStreamingMediaElement&lt;/a&gt;. It&amp;#39;s currently still in beta, and I&amp;#39;ll talk about this more later. Click &lt;a target="_blank" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=2b1ce605-3b99-49ad-8a26-1250f2acbbf6&amp;amp;displaylang=en" class="Link"&gt;here&lt;/a&gt; to download it (this page has some links to other great resources for ramping up on IIS SmoothStreaming).&lt;br /&gt;As with any other Silverlight solution, the Silverlight 4 plugin needs to be installed on the user&amp;#39;s browser. This requirement is of course the fuel for many heated Silverlight vs. Flash debates, but that is a topic for a different thought.&lt;/li&gt;
&lt;li class="Text"&gt;&lt;span class="Bold"&gt;Component 2: Web Server&lt;/span&gt; - The Web Server hosts the actual web site, as well as the WCF services that are used to upload the file from the client. This server has a pretty typical configuration, requiring only IIS, ASP.NET, and WCF. Basically, once the Client initiates an upload, the file is sent over the wire in 1 MB chunks (which is easily configurable depending on your infrastructure). The Web Server then creates a new file on the File Server, and simply accumulates each chunk into it until the file is completely uploaded. &amp;quot;Chunking&amp;quot; files not only makes progress bars easy to implement, but also doesn&amp;#39;t crush the bandwidth between the server and client. I also have some tricks in the code that harden it against periodic network burps, allowing large files to upload uninterrupted.&lt;br /&gt;In addition, these services also facilitate file cancellation, which is concurrently easy within the chunking paradigm. A separate call is made to the server that stops the upload, deletes the temp file, and resets the progress bar. Finally, (and this is out of scope for this article but well worth mentioning) we could implement an optional clean up job to delete any file fragments resulting from uploads that do fail (since, let&amp;#39;s face it, Internet connections still go down).&lt;/li&gt;
&lt;li class="Text"&gt;&lt;span class="Bold"&gt;Component 3: File Server&lt;/span&gt; - Regardless of how your site is hosted, this is your data tier. Although there&amp;#39;s no reason why the uploaded files couldn&amp;#39;t live in SQL server, I prefer to store them on the file system for both performance and ease of serving purposes. To this end, the File Server has two shared folders: one for temp uploads and one for encoded files ready to be served. Basically, all file chunks are routed through the Web Server and end up in the temp folder.&lt;br /&gt;Once a file is completely uploaded, the client turns around and calls the Media Server, directing it to grab the file from its temp location on the Files Server, and encode it. The new IIS SmoothStreaming-encoded version is saved in the final destination folder and the original file is deleted from the temp folder. The aforementioned clean up job runs at night (when no one is presumably uploading media) and deletes all files from the temp folder.&lt;/li&gt;
&lt;li class="Text"&gt;&lt;span class="Bold"&gt;Component 4: Media Server&lt;/span&gt; - Here is where the magic happens. This server has IIS Media Services 3.0 installed, which enables IIS SmoothStreaming. A virtual directory in IIS is mapped to the file destination folder on the File Server, and serves these files to Silverlight 4 clients. Additionally, Expression Encoder 3 (the &amp;quot;full&amp;quot; version with IIS SmoothStreaming support) is installed here. In order the use the SDK, the product must be licensed and installed. The Encoder SDK is hosted in a WCF service and does the actual work to encode native media into the SmoothStreaming format.&lt;br /&gt;You might be wondering why we have two IIS servers in this farm. The main reason is because media encoding is super processor-intensive, and will suck up every last CPU cycle it can find, spiking all cores. In order to keep your web site humming along, it&amp;#39;s a good idea to offload this work if at all possible. A dedicated Media Server also gives us a nice separation of concerns: your Web Server deals with many concurrent users consuming your site&amp;#39;s pages; your Media Server deals with fewer people viewing movies and fewer yet uploading and encoding content. However, if you are constrained by physical (or virtual) hardware, there&amp;#39;s no technical reason (other than performance) why SUESS couldn&amp;#39;t grow very decent media tomatoes in a web garden.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;&lt;span class="Underline"&gt;Interactions&lt;/span&gt; &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Before diving deeply into each component&amp;#39;s details and code in SUESS, I&amp;#39;d like to make another pass through architecture from the perspective of each interaction. As with any distributed system, there is a lot of communication that needs to happen to facilitate each server&amp;#39;s role. For example, the client needs to tell the Media Server when a file is done uploading, which it can&amp;#39;t know until the Web Server informs it that it&amp;#39;s properly been copied to the File Server. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;
&lt;ul class="Text"&gt;
&lt;li class="Text"&gt;&lt;span class="Bold"&gt;Interaction A: File Upload&lt;/span&gt; - The &amp;quot;media conversation&amp;quot; begins when the client&amp;#39;s Uploader control has a valid file selected. It calls a WCF service on the Web Server and sends the first &amp;quot;chunk&amp;quot; (which is an array of bytes) of the file, as well as the file name with a uniqueness-enforcing &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.guid.aspx" class="Link"&gt;Guid&lt;/a&gt; appended to it.&lt;br /&gt;The Web Server then reads the File Server&amp;#39;s temp upload path from a config file, builds the full file name, and simply checks if such a file already exists. If so, it opens it, seeks to the end, and writes the chunk to the file; otherwise it creates a new file with the uploaded chunk.&lt;br /&gt;The fact that Silverlight service calls are asynchronous does some favors for us, but makes the rest of the uploading algorithm more difficult. The favor is making progress bars easy. When each async call finishes, we know exactly how much of the file we&amp;#39;ve uploaded, (chunk size times number of chunks uploaded over total file size) and can simply use a &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.media.animation.storyboard.aspx" class="Link"&gt;Storyboard&lt;/a&gt; to animate a &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.progressbar(VS.95).aspx" class="Link"&gt;ProgressBar&lt;/a&gt;, since we&amp;#39;ll always be on the UI thread.&lt;br /&gt;However, being asynchronous, we can&amp;#39;t simply &amp;quot;loop&amp;quot; through the file, and upload the next chunk when the current one finishes. So what the Uploader does is keeps track of the position in the file we are in, then recursively uploads the next chunk in the completed event of each pervious chunk&amp;#39;s service call. This way, we don&amp;#39;t keep the Browser&amp;#39;s UI thread locked up, and can maintain a very accurate progress bar. We&amp;#39;ll go into more detail about this algorithm when we look at the code for the Uploader later.&lt;/li&gt;
&lt;li class="Text"&gt;&lt;span class="Bold"&gt;Interaction B: File Storage / Cancellation / Clean Up Job&lt;/span&gt; - The File Upload interaction is pretty straight forward. On the surface, it would appear that File Storage is as well. After the Web Server finishes copying the last chunk to the File Server, the client then kicks off the Encoding process. It&amp;#39;s the same story with cancellation. The client breaks the recursion on its end to stop uploading, and tells the Web Server to delete the file from the File Server. Pretty easy, right?&lt;br /&gt;Well, there&amp;#39;s one little (huge) problem: the IIS double hop issue. If it weren&amp;#39;t for this, there would be no reason to break this interaction out into its own discussion. Basically, under NTLM, IIS cannot be a client and a server at the same time. What this means is that the code behind a service call (IIS being the &amp;quot;server&amp;quot;) cannot then turn around and make a call of its own (making IIS a &amp;quot;client&amp;quot;) using the same credentials it was passed. This plugs a security hole in which your credentials could otherwise be used to access resources elsewhere on the network you don&amp;#39;t explicitly have rights to.&lt;br /&gt;To get around this (as circumventing security continues to accumulate an obnoxiously high percentage of time in my career) we need to either implement a delegation-based security model such as &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Kerberos_(protocol)" class="Link"&gt;Kerberos&lt;/a&gt;, or, more realistically, explicitly impersonate the calls to the File Server. So from this interaction-based perspective, the Uploader is free to call the Web Server or Media Server directly, but these calls cannot be propogated along to the File Server without suffering though a second hop. (It is with great restrain that I did not include pictures of rabbits jumping around the servers in my architectural diagram above: an image the double hop issue always puts in my head.) So make sure you plan out your security model carefully (unless you are using anonymous access or a web garden, in which case this isn&amp;#39;t a problem). You&amp;#39;ll appreciate this when it&amp;#39;s 1 AM, you have all kinds of access denied exception red ink in your Event Viewer, and are staring cross-eyed at the security tab of your upload folder and wondering how giving &amp;quot;Everyone&amp;quot; &amp;quot;Owner&amp;quot; permissions couldn&amp;#39;t possibly be working!&lt;/li&gt;
&lt;li class="Text"&gt;&lt;span class="Bold"&gt;Interaction C: File Encoding&lt;/span&gt; - The next step is to encode the media into IIS&amp;#39;s SmoothStreaming format. In order for SUESS to be successful, we cannot constrain users into a narrow array of files they can upload. To this end, we can use the Expression Encoder SDK to convert almost any native media a user might have into the proprietary IIS SmoothStreaming format. Interaction-wise, all we need to do is make a service call to the Media Server and tell it which file in the temp uploads path to encode. I&amp;#39;ll defer the more in depth discussion about SmoothStreaming for now; there is, however, one important technical footnote to this interaction.&lt;br /&gt;Since the Encoder SDK is 32 bit only, we need to be careful on Windows Server 2008 R2, which is 64 bit (or any 64 bit OS). Although your code will compile just fine, the 64 bit wpw3 process cannot call the 32 bit Encoder DLLs. This will happen even if you compile against the &amp;quot;Any CPU&amp;quot; platform in Visual Studio. To work around this, make sure your app pool in IIS runs in 32 bit mode. (To set this, right click an app pool in IIS, select &amp;quot;Advanced Properties,&amp;quot; and set &amp;quot;Enable 32 Bit Applications&amp;quot; to &lt;span class="Bold"&gt;True&lt;/span&gt; in the &amp;quot;(General)&amp;quot; section.)&lt;/li&gt;
&lt;li class="Text"&gt;&lt;span class="Bold"&gt;Interaction D: Media Encoding Process&lt;/span&gt; - The final interaction is the actual encoding process, which is kicked off in the previous section. Our Media Server&amp;#39;s WCF encoder service is basically a wrapper around the Encoder SDK. The way it works is that the encoder service takes the file name from the client (along with other optional metadata, such as video quality) and creates an Encoder Job (which is the main workhorse of the SDK).&lt;br /&gt;The Job object has a few events that we can hook, primarily &amp;quot;EncodeProgress.&amp;quot; This, combined with WCF duplexing, allows a truly bi-directional communication for this interaction. The Job object fires the event when the percentage complete changes, and WCF actually calls a method on the Silverlight Uploader down on the client, which uses the information to update a progress bar! This is huge for this interaction for several reasons. First of all, encoding in general is slow, and real time progress bars give users a visual indicator that things are indeed chugging along on the server. Also, Silverlight 4&amp;#39;s native support for the WCF Polling Duplex binding means no kuldges for accurately reporting progress. I&amp;#39;ve seen (and experimented with myself) a lot different polling schemes to simulate bi-directional communication between WCF and Silverlight. Now that it&amp;#39;s all wrapped up nicely for us, we can present our users with a much richer experiment &lt;span class="Italic"&gt;much&lt;/span&gt; easier. Finally, there&amp;#39;s also a performance benefit on the network side, since, like the chunky upload, we don&amp;#39;t have one massive service call sucking up all our bandwidth.&lt;br /&gt;The rest of this interaction is between the Media Server and the File Server. The IIS SmoothStreaming format isn&amp;#39;t just a single file with a particular encoding; it&amp;#39;s an entire file structure with manifests, data files, etc. So after Encoder reads the source file from the File Server, it does its thing and dumps all the resultant files into the destination folder. Finally, when it&amp;#39;s done, it deletes the originally uploaded file, and fires the &amp;quot;EncodeCompleted&amp;quot; event on the client. Since the destination folder on the File Server is already mapped to a virtual directory under the Media Server&amp;#39;s IIS with Media Services installed, the new SmoothStreaming media is automatically ready to be smoothly streamed to Silverlight clients!&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;That does it for the architectural overview of SUESS. Like I said, the main goal here is to wrap all aspects of media serving on the web into one system: uploading, encoding, storing, and viewing. The Microsoft stack of IIS Media Services, Silverlight, WCF, and Expression Encoder provides an unprecedented media platform to deliver rich, &amp;quot;Web 2.0&amp;quot; content to our users. SUESS is merely the glue that sticks all these technologies together. &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="Text"&gt;Look for future posts from me (and soon, I promise!) that will dive into each component with deep technical discussions and code samples. Until then! &lt;/p&gt;
&lt;p class="Text"&gt;&amp;nbsp;&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.rightpoint.com/community/aggbug.aspx?PostID=2801" width="1" height="1"&gt;</description><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/WCF/default.aspx">WCF</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/IIS+SmoothStreaming/default.aspx">IIS SmoothStreaming</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Expression+Encoder/default.aspx">Expression Encoder</category></item><item><title>Silverlight vs. Flash: An SEO Perspective</title><link>http://www.rightpoint.com/community/blogs/viewpoint/archive/2010/06/06/silverlight-vs-flash.aspx</link><pubDate>Sun, 06 Jun 2010 20:53:00 GMT</pubDate><guid isPermaLink="false">f7450ba4-a08e-465a-831a-f9a15c21b696:2799</guid><dc:creator>rfreedman</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.rightpoint.com/community/blogs/viewpoint/rsscomments.aspx?PostID=2799</wfw:commentRss><comments>http://www.rightpoint.com/community/blogs/viewpoint/archive/2010/06/06/silverlight-vs-flash.aspx#comments</comments><description>&lt;p&gt;Microsoft has done a great job with&amp;nbsp;Silverlight&amp;nbsp;4, but many people don&amp;#39;t know what the primary differences are, specifically as it relates to search engine optimization (SEO).&amp;nbsp; The purpose of this blog post is to illustrate&amp;nbsp;the primary differences between Silverlight and Flash&amp;nbsp;(from an SEO perspective).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The bottom line is that Silverlight is more SEO Friendly&amp;nbsp;than Adobe Flash&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Silverlight 3 is&amp;nbsp;more SEO friendly becasue it permits deep linking URLs to point to places within the application or website.&amp;nbsp; To make things even more exciting for search engine crawlers, an ASP add-on mirrors dynamic content into HTML for easy indexing.&amp;nbsp; Microsoft has included an XML presentation layer in Silverlight to address a major problem with Flash.&amp;nbsp; With Flash, you need to use the SWFObject to provide copy to search bots. Google chooses to overlook XML that is application-specific, as would be the case with Silverlight XML.&lt;/p&gt;
&lt;p&gt;Silverlight treats text as a separate entity on a web server, and subsequently applications are fully searchable and indexed by search engines.&amp;nbsp;Though Flash has traditionally not been very SEO friendly, Adobe is working in conjunction with Google and Yahoo, have had some success in making Flash more friendly to search engines. But for now, Silverlight is the clearn winner.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.rightpoint.com/community/aggbug.aspx?PostID=2799" width="1" height="1"&gt;</description><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/flash/default.aspx">flash</category><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/seo/default.aspx">seo</category></item><item><title>Programmatically Consuming Silverlight Styles</title><link>http://www.rightpoint.com/community/blogs/viewpoint/archive/2010/04/28/programmatically-consuming-silverlight-styles.aspx</link><pubDate>Thu, 29 Apr 2010 00:38:00 GMT</pubDate><guid isPermaLink="false">f7450ba4-a08e-465a-831a-f9a15c21b696:2794</guid><dc:creator>Chris Domino</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.rightpoint.com/community/blogs/viewpoint/rsscomments.aspx?PostID=2794</wfw:commentRss><comments>http://www.rightpoint.com/community/blogs/viewpoint/archive/2010/04/28/programmatically-consuming-silverlight-styles.aspx#comments</comments><description>&lt;p class="Text"&gt;Hard coding, as anyone who has been development software for more than 20 minutes knows, is bad news. Yet it happens over and over, but probably more as a result of laziness than anything else. And I&amp;#39;m not afraid to say that I&amp;#39;ve been guilty too. A lot of times, for example, when building a new web site, I am extremely diligent at putting as much styling as possible in my CSS files; my pages&amp;#39; HTML is so pristine that they won&amp;#39;t even have style tags! &lt;/p&gt;
&lt;p class="Text"&gt;But then, after staying up all night to meet a dead line, or when a persistent bug regarding an IE 6 compatibility issue refuses to go away, or basically if anything else among the myriad of challenges that building software deals with comes up, it&amp;#39;s easy to say &amp;quot;Screw it; I&amp;#39;m hard coding.&amp;quot; But for the most part, I think developers are pretty good about using configuration files, style sheets, XSLT; anything that doesn&amp;#39;t need to be compiled to keep our software nice and flexible. &lt;/p&gt;
&lt;p class="Text"&gt;These mechanisms are great as long as we can easily pull data out of them. Of course, with components like config files, .NET has the means to consume them, very easily, baked right in. But when it comes to style sheets, things aren&amp;#39;t so easy. In fact, I&amp;#39;ve never needed to programmatically &amp;quot;consume&amp;quot; a style sheet before; it&amp;#39;s always simply been welded to my page&amp;#39;s HTML. &lt;/p&gt;
&lt;p class="Text"&gt;But with Silverlight, I&amp;#39;ve started to need this functionality, mainly because we can do so much more with it than HTML. But as is the case whenever code runs on the client, the more we &lt;span class="Italic"&gt;can&lt;/span&gt; do means the more we &lt;span class="Italic"&gt;have&lt;/span&gt; to do. For example, in the site I&amp;#39;m working on now, I built a pager control that automatically creates buttons for each page, and dynamically resizes itself to fit nicely along with the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.canvas(VS.95).aspx" class="Link"&gt;Canvas&lt;/a&gt; it is paging. &lt;/p&gt;
&lt;p class="Text"&gt;One of the problems I had to solve was to show horizontal scrolling for my pager if the number of pager buttons would be beyond the Silverlight control&amp;#39;s content region. Here&amp;#39;s what it looks like: &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;p class="Image"&gt;&lt;img src="http://chrisdomino.com/content/images/Programmatically-Consuming-Silverlight-Styles/Pager.png" class="Image" alt="" /&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;If the horizontal scroll bar is visible, I need to make the pager taller. Normally, I would just use &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.scrollviewer.computedhorizontalscrollbarvisibility.aspx" class="Link"&gt;ScrollViewer.ComputedHorizontalScrollBarVisibility&lt;/a&gt; to do the job. However, with all the padding, dynamic controls, and resizing I do, this property didn&amp;#39;t always return value I was expecting. So instead of kludging it, I decided to compute the width myself. This at first sounded daunting, but the logic wasn&amp;#39;t too bad. Basically, I sum the widths of all the button controls, and add on the left and right &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.margin(VS.95).aspx" class="Link"&gt;Margin&lt;/a&gt; and &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.control.padding(VS.95).aspx" class="Link"&gt;Padding&lt;/a&gt; for each. &lt;/p&gt;
&lt;p class="Text"&gt;The problem is that the margins and paddings were set in styles. (The widths had to be calculated dynamically, since page &amp;quot;10&amp;quot; is wider than page &amp;quot;9&amp;quot; - &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/bb980095(VS.95).aspx" class="Link"&gt;TextBlock.ActualWidth&lt;/a&gt; came to the rescue here.) Now of course this isn&amp;#39;t a problem because I could always iterate and accumulate the controls in my pager and get the &amp;quot;actual&amp;quot; width of the control (and therefore determine the need to have a horizontal scrollbar) that way. &lt;/p&gt;
&lt;p class="Text"&gt;However, meh, I thought I could do something a little more elegant. Besides, all it would take is one little UI tweak that could change the behavior of my calculation. So instead, I decided to &amp;quot;pull&amp;quot; these values from the style used on the button one time, store them globally, and then reuse them as needed. This way, the style &amp;quot;owned&amp;quot; these values, and if they ever changed, my logic would continue to work just fine. Yay me. &lt;/p&gt;
&lt;p class="Text"&gt;But then, Silverlight punched me in the face. Basically, the way &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.style.aspx" class="Link"&gt;Style&lt;/a&gt; and &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.setter.aspx" class="Link"&gt;Setter&lt;/a&gt; objects work internally is sort of kludged. I stopped researching when I discovered that my idea wasn&amp;#39;t going to work. (Basically Setters only ever set their values on the objects they style exactly one time in the control&amp;#39;s lifespan. I believe this is performance enhancement - like how you can&amp;#39;t databind to the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.media.mediaplayer.position.aspx" class="Link"&gt;Position&lt;/a&gt; property of a &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement.aspx" class="Link"&gt;MediaElement&lt;/a&gt; even though it&amp;#39;s a &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.dependencyproperty.aspx" class="Link"&gt;DependencyProperty&lt;/a&gt;.) So to enforce these performance gains, the Style and Setter classes expose very little to us in the API. The Silveright team won&amp;#39;t let us hurt ourselves; it&amp;#39;s like a child being forced to wear a safety helmet in a dodge ball game. &lt;/p&gt;
&lt;p class="Text"&gt;So did I stop at that? Well, yeah, but it stayed in the back of mind, bothering me all the while I built my pager control. When I finished it early, I decided to use my extra time to go back and try to figure out a way to programmatically access a style in Silverlight. &lt;/p&gt;
&lt;p class="Text"&gt;And I got it! My idea was to use the fact that there is nothing magical AT ALL about styles! You can tell by the XAML and the names of the Setter object&amp;#39;s properties (&amp;quot;&lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.setter.property.aspx" class="Link"&gt;Property&lt;/a&gt;&amp;quot; and &amp;quot;&lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.setter.value.aspx" class="Link"&gt;Value&lt;/a&gt;&amp;quot;) that all they do is reflectively set properties on objects. That&amp;#39;s why you can put attached properties and other junk in a style - not just &amp;quot;style&amp;quot; attribute values like in HTML and CSS. &lt;/p&gt;
&lt;p class="Text"&gt;So I wrote a little diddy that, well, basically just uses styles! You give me a style and a property, and I&amp;#39;ll instantiate on object of the Style&amp;#39;s &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.style.targettype.aspx" class="Link"&gt;TargetType&lt;/a&gt; type, (until now I&amp;#39;ve been annoyed that you have to tell a XAML Style what type of object it styles, but this makes my code work!), apply a style, and just reflectively grab that object&amp;#39;s property value! &lt;/p&gt;
&lt;p class="Text"&gt;Here&amp;#39;s what it looks like: &lt;/p&gt;
&lt;p class="Text"&gt;
&lt;table cellpadding="0" cellspacing="0" class="CodeLayout"&gt;
&lt;tbody&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellTopLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellTopRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellMiddleLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleMiddle"&gt;
&lt;div class="CodeContainer"&gt;
&lt;div class="CodeLayout"&gt;&lt;ol class="Code"&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;public&lt;/span&gt; &lt;span class="Keyword"&gt;static&lt;/span&gt; &lt;span class="ClassName"&gt;T&lt;/span&gt; GetStylePropertyValue&lt;span class="Operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ClassName"&gt;T&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;Application&lt;/span&gt; app&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt; styleName&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;string&lt;/span&gt; propertyName&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//get style&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;Style&lt;/span&gt; style &lt;span class="Operator"&gt;=&lt;/span&gt; app&lt;span class="Operator"&gt;.&lt;/span&gt;Resources&lt;span class="Operator"&gt;[&lt;/span&gt;styleName&lt;span class="Operator"&gt;]&lt;/span&gt; &lt;span class="Keyword"&gt;as&lt;/span&gt; &lt;span class="ClassName"&gt;Style&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;style &lt;span class="Operator"&gt;=&lt;/span&gt;&lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;default&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;T&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//instantiate an obejct that is the type of this style&amp;#39;s target type&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;FrameworkElement&lt;/span&gt; element &lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;FrameworkElement&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;style&lt;span class="Operator"&gt;.&lt;/span&gt;TargetType&lt;span class="Operator"&gt;.&lt;/span&gt;Assembly&lt;span class="Operator"&gt;.&lt;/span&gt;CreateInstance&lt;span class="Operator"&gt;(&lt;/span&gt;style&lt;span class="Operator"&gt;.&lt;/span&gt;TargetType&lt;span class="Operator"&gt;.&lt;/span&gt;FullName&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;element &lt;span class="Operator"&gt;=&lt;/span&gt;&lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;default&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;T&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//apply this style to the new object&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;element&lt;span class="Operator"&gt;.&lt;/span&gt;Style &lt;span class="Operator"&gt;=&lt;/span&gt; style&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//use reflection to get the value of the property&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="ClassName"&gt;PropertyInfo&lt;/span&gt; pi &lt;span class="Operator"&gt;=&lt;/span&gt; element&lt;span class="Operator"&gt;.&lt;/span&gt;GetType&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;GetProperties&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;Where&lt;span class="Operator"&gt;(&lt;/span&gt;p &lt;span class="Operator"&gt;=&lt;/span&gt;&lt;span class="Operator"&gt;&amp;gt;&lt;/span&gt; p&lt;span class="Operator"&gt;.&lt;/span&gt;Name&lt;span class="Operator"&gt;.&lt;/span&gt;Equals&lt;span class="Operator"&gt;(&lt;/span&gt;propertyName&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;.&lt;/span&gt;FirstOrDefault&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;pi &lt;span class="Operator"&gt;=&lt;/span&gt;&lt;span class="Operator"&gt;=&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:20px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Keyword"&gt;default&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;T&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Comment"&gt;//return&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:10px;"&gt;&lt;span class="Code"&gt;&lt;span class="Keyword"&gt;return&lt;/span&gt; &lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="ClassName"&gt;T&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;pi&lt;span class="Operator"&gt;.&lt;/span&gt;GetValue&lt;span class="Operator"&gt;(&lt;/span&gt;element&lt;span class="Operator"&gt;,&lt;/span&gt; &lt;span class="Keyword"&gt;null&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;&lt;span class="Operator"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="Code" style="padding-left:0px;"&gt;&lt;span class="Code"&gt;&lt;span class="Operator"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class="CodeCellMiddleSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellMiddleRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="CodeRow"&gt;
&lt;td class="CodeCellBottomLeft"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomMiddle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomSpacer"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="CodeCellBottomRight"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p class="Text"&gt;Basically, &amp;quot;T&amp;quot; is the .NET type of the property, &amp;quot;app&amp;quot; is usually App.Current, and along with the name of the style and property, I&amp;#39;ve got it. So for my pager situation, &amp;quot;T&amp;quot; is &amp;quot;Thickness&amp;quot; and &amp;quot;propertyName&amp;quot; is &amp;quot;Margin.&amp;quot; Finally, consuming the margin&amp;#39;s dimensions gives me what I need to calculate the total &amp;quot;actual&amp;quot; width of my pager. &lt;/p&gt;
&lt;p class="Text"&gt;Have fun! &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.rightpoint.com/community/aggbug.aspx?PostID=2794" width="1" height="1"&gt;</description><category domain="http://www.rightpoint.com/community/blogs/viewpoint/archive/tags/Silverlight/default.aspx">Silverlight</category></item></channel></rss>