<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.wintellect.com/CS/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>Sergio Loscialo's Blog</title><link>http://www.wintellect.com/CS/blogs/sloscialo/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.2)</generator><item><title>Working with PivotViewer and the CxmlCollectionSource</title><link>http://www.wintellect.com/CS/blogs/sloscialo/archive/2011/10/17/working-with-pivotviewer-and-the-cxmlcollectionsource.aspx</link><pubDate>Mon, 17 Oct 2011 22:39:14 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:20301</guid><dc:creator>sloscialo</dc:creator><slash:comments>0</slash:comments><comments>http://www.wintellect.com/CS/blogs/sloscialo/comments/20301.aspx</comments><wfw:commentRss>http://www.wintellect.com/CS/blogs/sloscialo/commentrss.aspx?PostID=20301</wfw:commentRss><description>&lt;p&gt;Microsoft’s PivotViewer control is an amazing tool for visualizing data and creating a unique UI for your application.&amp;#160; The one issue everyone seems to have with it, however, is its lack of styling capability.&amp;#160; In fact, working with PivotViewer in Expression Blend yields little in the way of styling or templating.&amp;#160; There are only a few color settings one can make, and some generic overall changes.&amp;#160;&amp;#160; Replacing the filter panel or info panel is not currently supported.&lt;/p&gt;  &lt;p&gt;What to do?&lt;/p&gt;  &lt;p&gt;Since we cannot style the filter panel, we need to hide it and put our own in.&amp;#160; Hiding the panel is relatively simple and straight-forward.&amp;#160; Simply put, you need to subclass the PivotViewer and override the OnApplyTemplates() method, then walk the tree until you find the filter panel.&amp;#160; Fortunately, tools like Snoop or Mole can help you determine where the filter panel resides.&amp;#160; Below is a snippet of code showing where the filter panel resides in the Silverlight 5 version of the PivotViewer.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; OnApplyTemplate()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;.OnApplyTemplate();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;     Grid partContainer = (Grid)&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.GetTemplateChild(&lt;span style="color:#006080;"&gt;&amp;quot;PART_Container&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;     CollectionViewerView cvv = ((CollectionViewerView)(partContainer).Children[2]);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;     Grid container = cvv.Content &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; Grid;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;     Border viewerBorder = container.Children[1] &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; Border;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;     Grid viewerGrid = viewerBorder.Child &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; Grid;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;// Filter Panel&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;     viewerGrid.Children[2].Visibility = System.Windows.Visibility.Collapsed;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;NOTE: This is very brittle code and will most likely fail when Microsoft releases a new version of the PivotViewer.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Now that the filter panel is gone, we need to create our own.&amp;#160; If you’re manually creating the facets and data in code, then you should have no trouble binding a new Filter control to your data structures.&amp;#160; But what if you’re using the CxmlCollectionSource and loading your data from a cxml external file?&lt;/p&gt;

&lt;p&gt;As anyone who’s worked with the CxmlCollectionSource can tell you, the facets and their filter values aren’t readily available for consumption.&amp;#160; In order to build up a collection of facets and filters, you to perform a little preprocessing.&amp;#160; The Items collection off the CxmlCollectionSource is the dataset you’re working with, however, getting values and properties for the items isn’t immediately apparent.&lt;/p&gt;

&lt;p&gt;My solution was to create a small class to hold the facet information I required:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Facet&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Category { get; set; }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Value { get; set; }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; IsChecked { get; set; }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;In order to iterate through the Items collection, you need to wait until the CxmlCollectionSource finishes processing the .cxml document.&amp;#160; Since it occurs asynchronously, you can start your processing in the event handler for the StateChanged event.&amp;#160; That can look something like this (I’m not implementing an MVVM pattern for simplicity’s sake.&amp;#160; This is just part of the code-behind for the MainPage.xaml).&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; OnLoaded(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (_cxml == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;         _cxml = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; CxmlCollectionSource(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Uri(HtmlPage.Document.DocumentUri, &lt;span style="color:#006080;"&gt;&amp;quot;/Data/PivotViewerData.cxml&amp;quot;&lt;/span&gt;));&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;         _cxml.StateChanged += CxmlStateChanged;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt; }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; CxmlStateChanged(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, CxmlCollectionStateChangedEventArgs e)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (e != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; e.NewState == CxmlCollectionState.Loaded)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt;         MyPivot.PivotProperties = _cxml.ItemProperties.ToList();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt;         MyPivot.ItemTemplates = _cxml.ItemTemplates;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum18"&gt;  18:&lt;/span&gt;         MyPivot.ItemsSource = _cxml.Items;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum19"&gt;  19:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum20"&gt;  20:&lt;/span&gt;         ProcessFacets();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum21"&gt;  21:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum22"&gt;  22:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.DataContext = _facetData;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum23"&gt;  23:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum24"&gt;  24:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum25"&gt;  25:&lt;/span&gt;     _cxml.StateChanged -= CxmlStateChanged;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum26"&gt;  26:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The next step is to iterate over the Items of the CxmlCollectionSource and build a dictionary of Facets and their properties.&amp;#160; The Items collection is a collection of PivotViewerItems that do not contain the actual values of the data elements.&amp;#160; Instead, you need to call a method, GetPropertyValue(id) in order to get the list of properties that particular data elements contains.&amp;#160; &lt;/p&gt;

&lt;p&gt;The ProcessFacets() method below simply iterates over each item in the data set and determines which properties it contains that are filterable and what the acceptable values are for each.&amp;#160; For example if your data has two filterable properties, such as “Ingredients” and “Serving Size”, these two facets could have a wide range of acceptable values for each data element.&amp;#160; The call to GetPropertyValue for “Ingredients” for an particular item may return “Oil” and “Vinegar”, while another item may return “Milk”, “Oil” and “Peanuts.”&amp;#160; The dictionary built by ProcessFacets will create a Key for “Ingredients” and add a List of four strings representing the four unique values.&lt;/p&gt;

&lt;p&gt;I think it may be clearer just to read the code below:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ProcessFacets()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;// Iterate through all the PivotViewerItems.&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var item &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; _cxml.Items)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;// Determine what Propeties it has that are filterable.&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;         var facets = from f &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; item.Properties&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;                      &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;                          (PivotViewerPropertyOptions.CanFilter ==&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;                           (f.Options &amp;amp; PivotViewerPropertyOptions.CanFilter))&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;                      select f;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;// For each facet, get its values.&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var f &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; facets)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;         {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt;             &lt;span style="color:#008000;"&gt;// create a new facet if it doesn't exist.&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!_facetData.Facets.ContainsKey(f.Id))&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum18"&gt;  18:&lt;/span&gt;                 _facetData.Facets.Add(f.Id, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; List&amp;lt;Facet&amp;gt;());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum19"&gt;  19:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum20"&gt;  20:&lt;/span&gt;             &lt;span style="color:#008000;"&gt;// get the facet values.&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum21"&gt;  21:&lt;/span&gt;             var props = item.GetPropertyValue(f.Id);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum22"&gt;  22:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum23"&gt;  23:&lt;/span&gt;             &lt;span style="color:#008000;"&gt;// there can be more than one value per facet.&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum24"&gt;  24:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var p &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; props)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum25"&gt;  25:&lt;/span&gt;             {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum26"&gt;  26:&lt;/span&gt;                 &lt;span style="color:#008000;"&gt;// don't add the same one more than once.&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum27"&gt;  27:&lt;/span&gt;                 &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!_facetData.Facets[f.Id].Any(o =&amp;gt; o.Value.Equals(p)))&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum28"&gt;  28:&lt;/span&gt;                     _facetData.Facets[f.Id].Add(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Facet()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum29"&gt;  29:&lt;/span&gt;                                                     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum30"&gt;  30:&lt;/span&gt;                                                         Category = f.Id,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum31"&gt;  31:&lt;/span&gt;                                                         Value = p.ToString(),&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum32"&gt;  32:&lt;/span&gt;                                                         IsChecked = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum33"&gt;  33:&lt;/span&gt;                                                     });&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum34"&gt;  34:&lt;/span&gt;             }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum35"&gt;  35:&lt;/span&gt;         }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum36"&gt;  36:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum37"&gt;  37:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;So, there you have it.&amp;#160; &lt;/p&gt;

&lt;p&gt;Armed with this data, you can now create your own filter panel and programmatically control the PivotViewer independently of the built-in panel.&amp;#160; All you would need to do from this point on is write the Xaml for your Filter view and bind the Facet data to it.&amp;#160; Finally, call SetViewerState on the PivotViewer and pass in the filter string built by your new view.&amp;#160; Note, however, that the filter string is a mini-language of a sorts and will require some processing in code to generate the appropriate parameter.&amp;#160; To get you started, I iterate over the dictionary like so:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;[] filters = _facetData.Values&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt;   .SelectMany(facet =&amp;gt; facet.Where(prop =&amp;gt; prop.IsChecked))&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;   .Select(prop =&amp;gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;{0}=EQ.{1}&amp;quot;&lt;/span&gt;, prop.Category, prop.Value))&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;   .ToArray();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; filterString = &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Join(&lt;span style="color:#006080;"&gt;&amp;quot;&amp;amp;&amp;quot;&lt;/span&gt;, filters.ToArray());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt; MyPivotViewer.SetViewerState(filters.Length &amp;gt; 0 ? filterString : &lt;span style="color:#006080;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;The PivotViewer is an extremely powerful tool to have in your arsenal, but it is not very customizable.&amp;#160; With a small hack and some understanding of the data set, some of its limitations can be overcome.&amp;#160;&amp;#160; I hope this post gets you on the road to creating your own custom PivotViewer applications.&lt;/p&gt;&lt;img src="http://www.wintellect.com/CS/aggbug.aspx?PostID=20301" width="1" height="1"&gt;</description></item><item><title>The Cascade Game: From Silverlight to HTML5 (part 2)</title><link>http://www.wintellect.com/CS/blogs/sloscialo/archive/2011/09/15/the-cascade-game-from-silverlight-to-html5-part-2.aspx</link><pubDate>Thu, 15 Sep 2011 22:02:36 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:20222</guid><dc:creator>sloscialo</dc:creator><slash:comments>0</slash:comments><comments>http://www.wintellect.com/CS/blogs/sloscialo/comments/20222.aspx</comments><wfw:commentRss>http://www.wintellect.com/CS/blogs/sloscialo/commentrss.aspx?PostID=20222</wfw:commentRss><description>&lt;h3&gt;Game Loops and Timer-Based Animations&lt;/h3&gt;  &lt;blockquote&gt;   &lt;p&gt;Previous Entries in Series&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;&lt;a href="http://www.wintellect.com/CS/blogs/sloscialo/archive/2011/09/08/the-cascade-game-from-silverlight-to-html5-part-1.aspx"&gt;Part 1 – Introduction and Game Layout&lt;/a&gt; &lt;/li&gt;   &lt;/ul&gt; &lt;/blockquote&gt;  &lt;p&gt;My next short term goal was to get some of spheres to show and animate. And that was going to entail using HTML5’s new &amp;lt;canvas&amp;gt; tag. I saw two ways of going about animating the spheres. The first way would be to manually draw the spheres on a single canvas and animate them by clearing the canvas and redrawing at every game cycle. The second way would be to create a separate canvas for each sphere and use CSS3 to animate them. The latter method would allow the GPU to help accelerate the graphics processing and seems to be the best choice for animations of this type in HTML5 (see this blog &lt;a href="http://www.wintellect.com/CS/blogs/jprosise/archive/2011/04/03/canvas-animations-in-html5.aspx"&gt;entry&lt;/a&gt; from &lt;a href="http://www.wintellect.com/Company/Bios/Jeff-Prosise"&gt;Jeff Prosise&lt;/a&gt;).&lt;/p&gt;  &lt;p&gt;In the Silverlight version of this game, I created several classes that managed the spheres, levels, scores, and whatnot. I wanted to mimic that structure as closely as possible in Javascript to make the conversion less painful. Since Javascript doesn’t really have any type-safety without writing a lot of support code, I knew this task was going to be a bit frustrating until I became re-acclimated to Javascript again (I confess, it’s been some time). &lt;/p&gt;  &lt;p&gt;As in the Silverlight version of the game, I’m going to rely on a game timer to run my main game loop.&amp;#160; In Silverlight I used a simple &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchertimer(v=VS.95).aspx"&gt;DispatcherTimer&lt;/a&gt; to control the animation.&amp;#160; In HTML/Javascript, there aren’t too many choices: setInterval and setTimeout.&amp;#160; The setInterval method will execute a callback at a specified interval, while setTimeout will execute a callback in a specified time span.&amp;#160; In essence, setInterval will continue running the callback while setTimeout will run it once.&amp;#160; In the setTimeout methodology, the callback will usually call setTimeout again in order to keep the animation timer going.&amp;#160; Both these animation techniques have been in use for a long time…and they both suffer from performance issues.&amp;#160; Namely, they continually run whether or not the tab containing the HTML page is visible or not.&lt;/p&gt;  &lt;p&gt;The solution in HTML5 is to use the new requestAnimationFrame method.&amp;#160; However, this API is still in the development stages and is not supported by all modern browsers (once again Internet Explorer 9.0 falls behind, but the API is supported in IE 10).&amp;#160; Paul Irish has a very good &lt;a href="http://paulirish.com/2011/requestanimationframe-for-smart-animating/"&gt;explanation&lt;/a&gt; and a workable fallback routine that I will be using for Cascade Html5.&lt;/p&gt;  &lt;p&gt;The animation heart of Cascade looks essentially like most traditional game loops, like this:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; window.requestAnimFrame = (function () {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; window.requestAnimimationFrame ||&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;            window.webkitRequestAnimationFrame ||&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;            window.mozRequestAnimationFrame ||&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;            window.oRequestAnimationFrame ||&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;            window.msRequestAnimationFrame ||&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;            function (callback, element) {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;                 window.setTimeout(callback, 1000 / 60);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;            };&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;      })();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;      &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt; function startLevel(level) {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;     instantiateSpheres(level.maximumSpheres);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;     startTimer();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt; }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum18"&gt;  18:&lt;/span&gt; function startTimer() {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum19"&gt;  19:&lt;/span&gt;     requestAnimFrame(startTimer);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum20"&gt;  20:&lt;/span&gt;     gameLoop();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum21"&gt;  21:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The startLevel() function is called by the main application and dynamically creates the game resources (i.e. the spheres) for a particular game level before starting the game timer.&lt;/p&gt;

&lt;p&gt;The gameLoop() function is the routine that animates each sphere in relation to the others.&amp;#160;&amp;#160; This method is responsible for two things during each animation cycle: 1) move each sphere, and 2) check for collisions with an explosion.&amp;#160; I’m using a rather basic loop to iterate through all the spheres and avoiding double-checking collisions.&amp;#160; Here’s the code:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; function gameLoop() {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;// move and check for collisions.&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (var i = 0; i &amp;lt; _spheres.length; i++) {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;         _spheres[i].move();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (var j = i + 1; j &amp;lt; _spheres.length; j++) {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (_spheres[i].isColliding(_spheres[j])) {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;                 &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (_spheres[i].isExploding) { _spheres[j].explode(_spheres[i]); }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;                 &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (_spheres[j].isExploding) { _spheres[i].explode(_spheres[j]); }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;                 &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (USE_COLLISIONS)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;                     _spheres[i].collide(_spheres[j]);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;             }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;         }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The USE_COLLISIONS variable is a simple boolean that I can use to globally turn off the rudimentary physics in the game.&amp;#160; The sphere class encapsulates the logic for all movement and collision detection.&amp;#160; The gameLoop() routine simply tells to each sphere to move itself and then determine if they collide with each other.&amp;#160; Remember the gameLoop() routine should be running approximately 60 times every second.&lt;/p&gt;

&lt;p&gt;So far, the animations are proceeding exactly as they did in the Silverlight version since both rely on a clock tick to perform their calculations.&amp;#160; At this point, I was quite happy with the migration from Silverlight since I was able to take the C# code and only slightly modify it to Javascript.&amp;#160; For example, here the same game loop in C#:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; OnTimerTick(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;// Move and check for collisions.&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; spheres.Count; i++)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;         spheres[i].Move();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; j = i + 1; j &amp;lt; spheres.Count; j++)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;         {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (spheres[i].IsColliding(spheres[j]))&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;             {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;                 &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (spheres[i].IsExploding) { spheres[j].Explode(spheres[i]); }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;                 &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (spheres[j].IsExploding) { spheres[i].Explode(spheres[j]); }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;                 &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.IsCollisionOff)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt;                     spheres[i].Collide(spheres[j]);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt;             }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum18"&gt;  18:&lt;/span&gt;         }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum19"&gt;  19:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum20"&gt;  20:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Some of the smaller problems I incurred during this portion of the conversion was color manipulation, points, and vectors.&amp;#160; Obviously, Silverlight and .Net in general has strong color manipulation capabilities; Javascript, not so much.&amp;#160; I ended up passing colors around as arrays of 4 bytes (R, G, B, and A) for easier manipulation.&amp;#160; The other issues stemmed from core libraries available in C# that deal with points and vectors but simply don’t exist at all in Javascript.&amp;#160; While I may have been able to find some external libraries for these pieces, they weren’t too difficult to reproduce.&lt;/p&gt;

&lt;p&gt;However, I’m a bit concerned with next piece of the conversion: the explosions.&amp;#160; I used Silverlight’s key-frame animations in storyboards along with data-binding to easily create animations that explode the sphere to a multiple of its initial radius, pause for moment, and then contract to nothingness.&amp;#160; I’m anticipating issues attempting to use CSS3 and HTML5 to provide the same ease of animation development.&amp;#160; However, that’s a topic for the next part of this blog series.&lt;/p&gt;&lt;img src="http://www.wintellect.com/CS/aggbug.aspx?PostID=20222" width="1" height="1"&gt;</description><category domain="http://www.wintellect.com/CS/blogs/sloscialo/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://www.wintellect.com/CS/blogs/sloscialo/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://www.wintellect.com/CS/blogs/sloscialo/archive/tags/CSS3/default.aspx">CSS3</category></item><item><title>The Cascade Game: From Silverlight to HTML5 (part 1)</title><link>http://www.wintellect.com/CS/blogs/sloscialo/archive/2011/09/08/the-cascade-game-from-silverlight-to-html5-part-1.aspx</link><pubDate>Thu, 08 Sep 2011 21:39:51 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:20181</guid><dc:creator>sloscialo</dc:creator><slash:comments>1</slash:comments><comments>http://www.wintellect.com/CS/blogs/sloscialo/comments/20181.aspx</comments><wfw:commentRss>http://www.wintellect.com/CS/blogs/sloscialo/commentrss.aspx?PostID=20181</wfw:commentRss><description>&lt;p&gt;A few years ago I played a game on Facebook that had a simple premise, but became quite addictive for a while.&amp;#160; It consisted of progressing levels of spheres in which the player was tasked with exploding by initiating a chain-reaction.&amp;#160; You had one shot.&amp;#160; Placement, timing, and luck determined how well you scored.&amp;#160; At the time, I was learning Silverlight and thought it would be a good sample project to duplicate the fundamentals of this game in Silverlight, and thus &lt;a href="http://demo.wintellect.com/cascade/"&gt;Cascade&lt;/a&gt; was born.&lt;/p&gt;  &lt;p&gt;Now, with the advent of Html5 and Javascript poised to reclaim the virtual landscape, I decided that it may be a beneficial learning experience to rewrite Cascade as an HTML5 application.&amp;#160;&amp;#160; The next series of posts will outline my progression in converting the Silverlight version of Cascade into a workable Html5 game. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.wintellect.com/CS/blogs/sloscialo/image_1204A224.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;float:left;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" align="left" src="http://www.wintellect.com/CS/blogs/sloscialo/image_thumb_58155F37.png" width="465" height="394" /&gt;&lt;/a&gt;The first thing I started with in the conversion was the shell for the game, a simple HTML5 page.&amp;#160; At this point, it’s still in the rough sketch phase (I’ll add more finalized artwork later).&amp;#160; Below is a picture of the game board with very little in the graphics department.&amp;#160;&amp;#160; The HTML5 markup is pretty basic, but I wanted to put a gradient in the header.&amp;#160;&amp;#160; With HTML5 and CSS3, gradients are very simple to implement without having to use a repeating graphic image.&amp;#160; So, while still possible to achieve this affect with either a large image or a small, repeated one, the new gradient effects in HTML5 /CSS3 are better for two reasons: they look good at all resolutions and are smaller in download size.&lt;/p&gt;  &lt;p&gt;Unfortunately, Internet Explorer 9 does not support gradients.&amp;#160; However, it does support Scalable Vector Graphics (SVG), as do all the other mainstream browsers.&amp;#160; So, while it’s not quite pure HTML5, the SVG background scales just as nicely and is minimal in size: see Robert Biggs’ blog at&amp;#160; &lt;a title="http://css3wizardry.com/2010/10/29/css-gradients-for-ie9/" href="http://css3wizardry.com/2010/10/29/css-gradients-for-ie9/"&gt;http://css3wizardry.com/2010/10/29/css-gradients-for-ie9/&lt;/a&gt; for more information.&amp;#160; I borrowed and slightly tweaked the Robert’s SVG gradient for my project.&amp;#160; And while he mentions customizing the code to only show the SVG for IE9, I’m inclined to let the other browsers use the SVG as well.&lt;/p&gt;  &lt;p&gt;There is a good case to be made to support SVG only in Internet Explorer and use the HTML5/CSS3 gradients for all other browsers.&amp;#160; However, for the purposes of this project, I’m going to stick with the one method; in a production application, I’d follow Robert’s advice and create the customization since IE will eventually support the feature.&lt;/p&gt;  &lt;p&gt;The HTML is rather straight-forward and simplistic: it consists of a few CSS3 styles, a handful of HTML tags, and some Javascript.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;body&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;style&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;margin: 0&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;header&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;id&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;scoreBoard&amp;quot; &lt;font color="#ff0000"&gt;class&lt;/font&gt;=&amp;quot;boxSizing&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;article&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;class&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;box&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;CASCADE&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;powered by Wintellect&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;id&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;headerControls&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;style&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;display: box&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;                 &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;input&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;type&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;checkbox&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;Turn off collisions.&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;input&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;                 &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;a&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;href&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;#&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;style&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;align: right&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;Help&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;a&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;article&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;article&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;style&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;margin-top: 15px; vertical-align: bottom&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;class&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;fixedWidthColumn&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;Score: &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;span&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;id&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;score&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;class&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;fixedWidthColumn&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;Level: &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;span&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;id&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;level&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;class&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;fixedWidthColumn&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;Goal: &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;span&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;id&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;goalObtained&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt; / &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;span&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;id&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;goalTarget&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;class&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;fixedWidthColumn&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;Total: &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;span&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;id&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;total&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;article&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;header&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum18"&gt;  18:&lt;/span&gt;     &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum19"&gt;  19:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;id&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;playingBoard&amp;quot; &lt;span style="color:#0000ff;"&gt;&lt;font color="#ff0000"&gt;class&lt;/font&gt;=&amp;quot;boxSizing&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum20"&gt;  20:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;body&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;As you can see, there’s not too much to it.&amp;#160; In fact, there isn’t much that’s HTML5 specific (the article and header tags could easily be replaced by standard divs).&amp;#160; Also, I’m using&amp;#160; a div to represent the playing board, and not a canvas (the reason is that the I’ll be dynamically creating canvases to hold the spheres and animating them individually instead of painting and clearing a single canvas…more on that in the next post).&lt;/p&gt;

&lt;p&gt;The elements are styled through CSS3 to provide the image you see in the snapshot above.&amp;#160; &lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#006080;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;style&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt;     &lt;span style="color:#cc6633;"&gt;&lt;font color="#000000"&gt;.boxSizing&lt;/font&gt;&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;         -moz-box-sizing: &lt;span style="color:#0000ff;"&gt;border&lt;/span&gt;&lt;span style="color:#006080;"&gt;-box;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;         -webkit-box-sizing: &lt;span style="color:#0000ff;"&gt;border&lt;/span&gt;&lt;span style="color:#006080;"&gt;-box;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;         -o-box-sizing: &lt;span style="color:#0000ff;"&gt;border&lt;/span&gt;&lt;span style="color:#006080;"&gt;-box;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;         box-sizing: &lt;span style="color:#0000ff;"&gt;border&lt;/span&gt;&lt;span style="color:#006080;"&gt;-box;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;     &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;     #scoreBoard {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;background-image&lt;/span&gt;: url('&lt;span style="color:#0000ff;"&gt;background&lt;/span&gt;&lt;span style="color:#cc6633;"&gt;&lt;font color="#0000ff"&gt;.svg&lt;/font&gt;&lt;/span&gt;');&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;border&lt;/span&gt;: &lt;span style="color:#006080;"&gt;1px solid gray;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;width&lt;/span&gt;: &lt;span style="color:#006080;"&gt;800px;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;height&lt;/span&gt;: &lt;span style="color:#006080;"&gt;120px;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;         &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt;     article {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;font-family&lt;/span&gt;: &lt;span style="color:#006080;"&gt;verdana;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum18"&gt;  18:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;font-size&lt;/span&gt;: &lt;span style="color:#006080;"&gt;14pt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum19"&gt;  19:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum20"&gt;  20:&lt;/span&gt;     &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum21"&gt;  21:&lt;/span&gt;     &lt;span style="color:#cc6633;"&gt;&lt;strong&gt;&lt;font color="#000000"&gt;.fixedWidthColumn&lt;/font&gt;&lt;/strong&gt;&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum22"&gt;  22:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;border&lt;/span&gt;: &lt;span style="color:#006080;"&gt;1px dotted white;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum23"&gt;  23:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;float&lt;/span&gt;: &lt;span style="color:#006080;"&gt;left;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum24"&gt;  24:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;width&lt;/span&gt;: &lt;span style="color:#006080;"&gt;24%;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum25"&gt;  25:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;margin&lt;/span&gt;-&lt;span style="color:#0000ff;"&gt;left&lt;/span&gt;: &lt;span style="color:#006080;"&gt;0.5%;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum26"&gt;  26:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;margin&lt;/span&gt;-&lt;span style="color:#0000ff;"&gt;right&lt;/span&gt;: &lt;span style="color:#006080;"&gt;0.5%;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum27"&gt;  27:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;padding&lt;/span&gt;: &lt;span style="color:#006080;"&gt;2px;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum28"&gt;  28:&lt;/span&gt;         -moz-box-sizing: &lt;span style="color:#0000ff;"&gt;border&lt;/span&gt;&lt;span style="color:#006080;"&gt;-box;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum29"&gt;  29:&lt;/span&gt;         -webkit-box-sizing: &lt;span style="color:#0000ff;"&gt;border&lt;/span&gt;&lt;span style="color:#006080;"&gt;-box;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum30"&gt;  30:&lt;/span&gt;         -o-box-sizing: &lt;span style="color:#0000ff;"&gt;border&lt;/span&gt;&lt;span style="color:#006080;"&gt;-box;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum31"&gt;  31:&lt;/span&gt;         box-sizing: &lt;span style="color:#0000ff;"&gt;border&lt;/span&gt;&lt;span style="color:#006080;"&gt;-box;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum32"&gt;  32:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum33"&gt;  33:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum34"&gt;  34:&lt;/span&gt;     #playingBoard &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum35"&gt;  35:&lt;/span&gt;     {  &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum36"&gt;  36:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;border&lt;/span&gt;: &lt;span style="color:#006080;"&gt;4px solid gray;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum37"&gt;  37:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;background&lt;/span&gt;: &lt;span style="color:#006080;"&gt;black;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum38"&gt;  38:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;width&lt;/span&gt;: &lt;span style="color:#006080;"&gt;800px;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum39"&gt;  39:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;height&lt;/span&gt;: &lt;span style="color:#006080;"&gt;480px;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum40"&gt;  40:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;position&lt;/span&gt;:&lt;span style="color:#006080;"&gt;fixed;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum41"&gt;  41:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum42"&gt;  42:&lt;/span&gt; &lt;span style="color:#006080;"&gt;&amp;lt;&lt;/span&gt;/&lt;span style="color:#0000ff;"&gt;style&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;For both the Silverlight game and this one, I fixed the size of the game to be 800x600.&amp;#160; My reasoning was that game’s difficulty is dependent upon the number, size,&amp;#160; and speed of spheres flying around.&amp;#160;&amp;#160; Perhaps I’ll adjust the size of the spheres in this version to be proportional to the size of the game board and see how that affects the playability of the game.&lt;/p&gt;

&lt;p&gt;One other note is the use of the box-sizing attributes set to border-box.&amp;#160; HTML5 allows the developer to change the way boxes are measured.&amp;#160;&amp;#160; The simplistic answer is that the default method, called content-box (HTML4 and earlier) don’t include the margins and border when you define the width and height.&amp;#160; Meaning if you create a 100px&amp;#160; wide and 50px tall element and put a 2px border around it, the element would actually appear to take up 104px by 54px on the screen.&amp;#160; By setting the box-sizing to border-box, I’m telling the browser to render the border, padding, and margins inside the element.&amp;#160; I prefer box sizing since I know that the total space taken by the visual element is what I set it to.&lt;/p&gt;

&lt;p&gt;After getting the basic UI of the game in place, I set up the game’s programming framework: basically initialization, start logic, game timing loop, and cleanup.&amp;#160; Part 2 of the this blog series will dive into the level initialization and the animation of the spheres.&lt;/p&gt;&lt;img src="http://www.wintellect.com/CS/aggbug.aspx?PostID=20181" width="1" height="1"&gt;</description><category domain="http://www.wintellect.com/CS/blogs/sloscialo/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://www.wintellect.com/CS/blogs/sloscialo/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://www.wintellect.com/CS/blogs/sloscialo/archive/tags/Game/default.aspx">Game</category><category domain="http://www.wintellect.com/CS/blogs/sloscialo/archive/tags/CSS3/default.aspx">CSS3</category></item><item><title>Where’s my DataContext?</title><link>http://www.wintellect.com/CS/blogs/sloscialo/archive/2011/07/26/where-s-my-datacontext.aspx</link><pubDate>Tue, 26 Jul 2011 15:51:30 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:20076</guid><dc:creator>sloscialo</dc:creator><slash:comments>0</slash:comments><comments>http://www.wintellect.com/CS/blogs/sloscialo/comments/20076.aspx</comments><wfw:commentRss>http://www.wintellect.com/CS/blogs/sloscialo/commentrss.aspx?PostID=20076</wfw:commentRss><description>&lt;p&gt;Every now and then a question comes up concerning a missing DataContext.&amp;#160; The questions usually center around a ViewModel being set to a View properly, but then developer can not bind some command or property to a FrameworkElement.&amp;#160; And typically the FrameworkElement in question is nested within an ItemsControl’s ItemTemplate or other similar structure.&lt;/p&gt;  &lt;p&gt;First things first, once a DataContext is set, it is available for every child and all nested children until another DataContext is set.&amp;#160; That’s why the following Xaml snippet works, and we don’t need to set the DataContext on both TextBlocks.&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:99.02%;padding-right:4px;font-family:'Consolas', courier, monospace;direction:ltr;height:109px;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &amp;lt;Grid DataContext=&lt;span style="color:#006080;"&gt;&amp;quot;{StaticResource MyViewModel}&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt;     &amp;lt;StackPanel&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;         &amp;lt;TextBlock Text=&lt;span style="color:#006080;"&gt;&amp;quot;{Binding SomeText}&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;         &amp;lt;TextBlock Text=&lt;span style="color:#006080;"&gt;&amp;quot;{Binding SomeMoreText}&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;     &amp;lt;/StackPanel&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt; &amp;lt;/Grid&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This is basic data-binding and is at the heart of WPF, Silverlight and Windows Phone 7 development.&amp;#160; So, no matter how many elements we nest within the Grid, they all will have access to the DataContext until an element is assigned its own DataContext.&lt;/p&gt;

&lt;p&gt;The question of the lost DataContext usually arises when the Xaml is slightly more complex.&amp;#160; For example,&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &amp;lt;Grid DataContext=&lt;span style="color:#006080;"&gt;&amp;quot;{StaticResource MyViewModel}&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt;     &amp;lt;ItemsControl ItemsSource=&lt;span style="color:#006080;"&gt;&amp;quot;{Binding MyItems}&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;         &amp;lt;ItemsControl.ItemTemplate&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;             &amp;lt;DataTemplate&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;                 &amp;lt;Grid&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;                     &amp;lt;StackPanel Orientation=&lt;span style="color:#006080;"&gt;&amp;quot;Horizontal&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;                         &amp;lt;TextBlock Text=&lt;span style="color:#006080;"&gt;&amp;quot;{Binding MyItemText}&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;                         &amp;lt;Button Content=&lt;span style="color:#006080;"&gt;&amp;quot;Delete&amp;quot;&lt;/span&gt; Command=&lt;span style="color:#006080;"&gt;&amp;quot;{Binding DeleteItemCommand}&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;                     &amp;lt;/StackPanel&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;                 &amp;lt;/Grid&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;             &amp;lt;/DataTemplate&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;         &amp;lt;/ItemsControl.ItemTemplate&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;     &amp;lt;/ItemsControl&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt; &amp;lt;/Grid&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This can tend to trip up developers new to WPF and Silverlight.&amp;#160; Why?&amp;#160; &lt;/p&gt;

&lt;p&gt;The first reason is that Grid on line 5 has had its DataContext changed transparently; the DataContext of the ItemsControl is still MyViewModel, but the internal grid has its DataContext set to an object in the bound collection (seen in line 2 as the ItemsSource).&amp;#160; In other words, the DataContext of the grid inside the ItemTemplate is an instance of an object in the collection MyItems.&amp;#160; For the above binding to work, the objects in MyItems would need have a property named MyItemText and a property called DeleteItemCommand.&lt;/p&gt;

&lt;p&gt;The second reason is even if a developer realizes that the DataContext of the ItemTemplate is an instance of an object in the list, they still want to bind to a property on the original ViewModel.&amp;#160; Most likely, the main ViewModel contains the consolidated business logic necessary for the requested task.&amp;#160; Or perhaps the list of items contains basic objects pulled from a RESTful service, so adding additional properties (especially ICommands) is too prohibitive.&lt;/p&gt;

&lt;p&gt;So, what can we do?&lt;/p&gt;

&lt;p&gt;As with most development, there are multiple ways to accomplish this task.&amp;#160; I’m going to show several of the more common solutions for obtaining a reference to what I call the main ViewModel.&amp;#160; In the two snippets I showed above, I’m assuming a StaticResource contains an instance of the ViewModel I’m concerned with.&amp;#160; However, that’s typically not the best practice for setting a ViewModel on a view.&amp;#160; More than likely, the main ViewModel will be set in code or through dependency injection.&lt;/p&gt;

&lt;p&gt;For the sake of completeness, if you did have a StaticResource pointing to your ViewModel, then you would change line 8 to read:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &amp;lt;Button Content=&lt;span style="color:#006080;"&gt;&amp;quot;Delete&amp;quot;&lt;/span&gt; Command=&lt;span style="color:#006080;"&gt;&amp;quot;{Binding Source={StaticResource MyViewModel}, Path=DeleteItemCommand}&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;If, however, your ViewModel is set in code, what can you do?&amp;#160; Well, the ItemsControl’s DataContext would still be set to the main ViewModel in this instance and there are several ways you can get to it.&lt;/p&gt;

&lt;p&gt;The first way uses element-to-element binding.&amp;#160; In order to use this, you’ll have to explicitly name your ItemsControl, then use a slightly different binding syntax to reference it:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &amp;lt;ItemsControl x:Name=&lt;span style="color:#006080;"&gt;&amp;quot;MyItemsControl&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt;   ...&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     &amp;lt;Button Content=&lt;span style="color:#006080;"&gt;&amp;quot;Delete&amp;quot;&lt;/span&gt; Command=&lt;span style="color:#006080;"&gt;&amp;quot;{Binding ElementName=MyItemsControl, Path=DataContext.DeleteItemCommand}&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;   ...&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt; &amp;lt;/ItemsControl&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Another method would to use the RelativeSource option for the binding.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &amp;lt;ItemsControl&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt;     ...&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     &amp;lt;Button Content=&lt;span style="color:#006080;"&gt;&amp;quot;delete&amp;quot;&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;             Command=&lt;span style="color:#006080;"&gt;&amp;quot;{Binding RelativeSource={RelativeSource AncestorType=ItemsControl}, Path=DataContext.DeleteItemCommand}&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;     ...&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt; &amp;lt;/ItemsControl&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;My personal preference is to use the RelativeSource option so that I don’t need to sync the element names.&amp;#160; The only caveat with RelativeSource would be multiple nesting of ItemsControls (or your container of choice) and then requiring access all the way back to the original ViewModel.&amp;#160; &lt;/p&gt;

&lt;p&gt;One last thing.&amp;#160; While my example is contrived, the DeleteItemCommand will need to know what item to delete.&amp;#160; Since we are not changing the DataContext on the button, we still have access to the forced DataContext the ItemsControl imposed on us, namely an instance of an item in the bound collection.&amp;#160; Therefore, we could also include a CommandParameter so that the delete command knows what to delete.&amp;#160; In all three cases presented above, you would add the following property to the delete button:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; CommandParameter=&lt;span style="color:#006080;"&gt;&amp;quot;{Binding}&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;So there you have it.&amp;#160; In certain surprisingly common scenarios, mainly involving the ItemTemplate of ItemsControl and its derived classes such as ListBox, the DataContext you get may not be the one you’re expecting.&amp;#160; However, with element-to-element and RelativeSource bindings you can easily obtain the references you need.&lt;/p&gt;&lt;img src="http://www.wintellect.com/CS/aggbug.aspx?PostID=20076" width="1" height="1"&gt;</description><category domain="http://www.wintellect.com/CS/blogs/sloscialo/archive/tags/WPF/default.aspx">WPF</category><category domain="http://www.wintellect.com/CS/blogs/sloscialo/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://www.wintellect.com/CS/blogs/sloscialo/archive/tags/DataContext/default.aspx">DataContext</category><category domain="http://www.wintellect.com/CS/blogs/sloscialo/archive/tags/DataTemplate/default.aspx">DataTemplate</category></item><item><title>Yet another way to attach ViewModels to Views</title><link>http://www.wintellect.com/CS/blogs/sloscialo/archive/2011/05/19/yet-another-way-to-attach-viewmodels-to-views.aspx</link><pubDate>Thu, 19 May 2011 17:45:57 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:19896</guid><dc:creator>sloscialo</dc:creator><slash:comments>0</slash:comments><comments>http://www.wintellect.com/CS/blogs/sloscialo/comments/19896.aspx</comments><wfw:commentRss>http://www.wintellect.com/CS/blogs/sloscialo/commentrss.aspx?PostID=19896</wfw:commentRss><description>&lt;p&gt;Throughout the short history of the MVVM design pattern, several methods have originated for populating Views with their ViewModels.&amp;#160; One of the most common methods is to use one of the frameworks (&lt;a href="http://compositewpf.codeplex.com/"&gt;PRISM&lt;/a&gt;, &lt;a href="http://www.galasoft.ch/mvvm/"&gt;MVVM Light&lt;/a&gt;, &lt;a href="http://jounce.codeplex.com/"&gt;Jounce&lt;/a&gt;, among others).&amp;#160; Typically, the ViewModel is registered with an IOC container and retrieved when needed.&amp;#160;&amp;#160; One of the more outstanding issues is when to take the ViewModel and assign it to a View’s DataContext.&amp;#160; In many cases, the connection occurs in the constructor of the View with the View requesting the ViewModel from the IOC container.&amp;#160; In other cases, a locator is used as a static resource in the View’s Xaml, and using DataBinding a property of the locator is bound to the DataContext.&amp;#160; In the latter case, the locator requests the ViewModel from the IOC container.&lt;/p&gt;  &lt;p&gt;In a recent project, I discovered (or rediscovered) another method for binding a ViewModel to a View.&amp;#160;&amp;#160; Using Unity’s IOC Container, I registered both the View and the ViewModel together.&amp;#160; Granted this method will not work for every scenario, but in the cases where you create Views programmatically, I believe this method works perfectly.&lt;/p&gt;  &lt;p&gt;Unity will allow you to register a type with a key which becomes important when registering different configurations of the same type.&amp;#160;&amp;#160; But&amp;#160; more importantly, Unity supports configuration via InjectionProperties (and other methods as well).&amp;#160; InjectionProperties will enable Unity to resolve your Type and inject additional values into the generated class.&amp;#160; InjectionProperties work like this:&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Consolas', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; expectedInt = 8;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; container.RegisterType&amp;lt;MyClass&amp;gt;(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; InjectionProperty(&lt;span style="color:#006080;"&gt;&amp;quot;IntProperty&amp;quot;&lt;/span&gt;, expectedInt));&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="codeSnippetWrapper"&gt;&lt;/div&gt;

&lt;p&gt;Basically, Unity will create an instance of MyClass and set the property “IntProperty” to 8, when the container resolves the type.&lt;/p&gt;

&lt;p&gt;For a View to be registered with its ViewModel, several steps must be taken .&amp;#160; The steps are simple, first register the ViewModel with Unity, then register the View with an InjectionProperty, optionally adding a key if you need to register the view multiple times with different configurations.&amp;#160; &lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Consolas', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; RegisterDialog&amp;lt;TView, TViewModel&amp;gt;(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; dialogName)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; TView : IDialogView&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; TViewModel : IDialogViewModel&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.IsNullOrEmpty(dialogName)) &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span style="color:#006080;"&gt;&amp;quot;dialogName&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!_container.IsRegistered&amp;lt;TViewModel&amp;gt;())&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;         _container.RegisterType&amp;lt;TViewModel&amp;gt;();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;     _container.RegisterType&amp;lt;IDialogView, TView&amp;gt;(dialogName, &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; InjectionProperty(&lt;span style="color:#006080;"&gt;&amp;quot;DataContext&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ResolvedParameter&amp;lt;TViewModel&amp;gt;()));&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;In the code above, I geared the method to support some dialogs, but it’s easily modified to support any type of view you’d like.&amp;#160; I use Unity’s ability to name the registrations so I can register multiple views of the same type but with different ViewModels.&amp;#160; One item to note is the use of the ResolvedParameter class.&amp;#160; The ResolvedParameter instructs Unity to only create the type when it is requested.&amp;#160; If I “newed” up a ViewModel instead, Unity would keep around an instance of the ViewModel to inject into all resolved views.&lt;/p&gt;

&lt;p&gt;In my Bootstrapper.cs file, where you’d normally register your classes in an IOC container,, I simply make calls to this method for any dialogs I want to create in the application.&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Consolas', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; RegisterDialog&amp;lt;DialogView DialogViewModel&amp;gt;(DialogNames.OkCancelDialog);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; RegisterDialog&amp;lt;DialogView, LoginDialogViewModel&amp;gt;(DialogNames.LoginDialog);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Here I am registering two dialogs of type DialogView with two different ViewModels and assigning them a key.&amp;#160; Now, it’s trivial to gain a reference to them in the application:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Consolas', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.User.IsLoggedIn) {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt;     IDialogView dialog = _dialogContainer.Resolve&amp;lt;IDialogView&amp;gt;(DialogNames.LoginDialog);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     dialog.Show();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Consolas', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;That’s all there is to it.&amp;#160; Of course, I’ll leave the whole Dialog framework implementation up to you.&lt;/p&gt;

&lt;p&gt;Unity is a complex framework with many features.&amp;#160; InjectionProperties are only one tool to enhance the configuration of your registrations.&amp;#160; Unity will even allow you to call a method on your object when it’s instantiated with or without parameters.&lt;/p&gt;&lt;img src="http://www.wintellect.com/CS/aggbug.aspx?PostID=19896" width="1" height="1"&gt;</description><category domain="http://www.wintellect.com/CS/blogs/sloscialo/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://www.wintellect.com/CS/blogs/sloscialo/archive/tags/Unity/default.aspx">Unity</category></item><item><title>Silverlight Memory Leaks and AutomationPeers</title><link>http://www.wintellect.com/CS/blogs/sloscialo/archive/2011/04/13/silverlight-memory-leaks-and-automationpeers.aspx</link><pubDate>Wed, 13 Apr 2011 18:09:48 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:19768</guid><dc:creator>sloscialo</dc:creator><slash:comments>2</slash:comments><comments>http://www.wintellect.com/CS/blogs/sloscialo/comments/19768.aspx</comments><wfw:commentRss>http://www.wintellect.com/CS/blogs/sloscialo/commentrss.aspx?PostID=19768</wfw:commentRss><description>&lt;p&gt;Using a memory profiling tool such as ANTS Memory Profiler from Red-Gate or MemProfiler from SciTech Software (I’m sure there others, but those were the only two I found that can profile a Silverlight Out-Of-Browser application) is a good idea.&amp;#160; By using such a tool, developers can discover a myriad of memory leaks and fix them before releasing their code.&amp;#160; These leaks usually stem from classes that attach event handlers to other classes.&amp;#160; In fact, in my opinion, I’ve seen more memory leaks in Silverlight (and WPF) stemming from poor event handler management than anything else.&lt;/p&gt;  &lt;p&gt;However, every once in a while, you’ll see something that appears to be unexplainable.&lt;/p&gt;  &lt;p&gt;After profiling an application for a client, I discovered the usual gambit of event-handlers and strong-references between objects.&amp;#160; In fact, an initial object retention graph (in this case, produced by the ANTS Memory Profiler) was almost indecipherable.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.wintellect.com/CS/blogs/sloscialo/image_4AD9146F.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://www.wintellect.com/CS/blogs/sloscialo/image_thumb_552A38CF.png" width="438" height="223" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This is intentionally unreadable for two reasons: 1) to protect the innocent, and 2) because that graph is so big, there’s no way to actually show it in it’s entirety without massive scrolling (I could probably whip up a Deep Zoom for it, but that’s over kill for the purposes of this discussion).&lt;/p&gt;  &lt;p&gt;The faint black box above the unreadable red “Start Here” box is the class I was researching, and the other boxes are classes in the hierarchy all the back to a GC root.&amp;#160; So, you can see that there were a lot.&amp;#160; After days of tracking down each strong reference and removing them, I ended up with a single chain.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.wintellect.com/CS/blogs/sloscialo/image_746CDFA2.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;float:left;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" align="left" src="http://www.wintellect.com/CS/blogs/sloscialo/image_thumb_3A7D9CB6.png" width="345" height="467" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This picture showed a ListBoxAutomationPeer as the last entity before being stuffed into the ManagedPeerTable.&lt;/p&gt;  &lt;p&gt;My original object (the dark gray box) was never released and since this was one child view inside a parent container, multiple copies stayed in memory never to be garbage collected.&lt;/p&gt;  &lt;p&gt;As far as memory consumption goes, it wasn’t too bad.&amp;#160; And since all the event handlers were removed, and all messages unsubscribed to, the object just floated in the ether being unobtrusive.&amp;#160; But, after spending days trying to clean up memory leaks, this was still unacceptable, especially since there were literally hundreds of these objects floating around.&lt;/p&gt;  &lt;p&gt;The Automation framework was created as a method for adding accessibility or automated testing to your applications.&amp;#160; The AutomationPeers are the way your application can communicate with Automation clients, or the way the Automation clients can communicate with your application.&lt;/p&gt;  &lt;p&gt;If an Automation Client is running, it can and will ask your application if it supports automation.&amp;#160; For both Silverlight and WPF this happens automatically (no pun intended).&amp;#160; Sometimes the client is nice about it and requires that you attach it to your application (like most automated testing frameworks).&lt;/p&gt;  &lt;p&gt;In my case, I wasn’t running an automated testing framework.&amp;#160; I wasn’t creating an Automation Client at all and attaching it to my application.&amp;#160; But AutomationPeers were being created, nonetheless.&lt;/p&gt;  &lt;p&gt;So, I tested this application on a co-workers machine to see if there was something environmental causing the problem.&amp;#160; As fate would have it, there was.&amp;#160; His computer was not showing this memory leak.&lt;/p&gt;  &lt;p&gt;After a day or two of digging around I realized that my computer was running Tablet PC Input Services (I have a Wacom tablet and the Tablet PC Input Services was installed when Windows figured out I had pen-enabled computer).&lt;/p&gt;  &lt;p&gt;Turning off the Tablet PC Input Services removed the AutomationPeers from the object retention graph and the memory leak was plugged.&lt;/p&gt;  &lt;p&gt;Unfortunately, nothing in the ANTS Memory Profiler or MemProfiler indicated that Tablet PC Input Services was the culprit causing the AutomationPeers to be created.&amp;#160; Additionally, while it seems like I’m pointing a finger at TIPS, any AutomationClient would probably cause the same issues within the application. &lt;/p&gt;  &lt;p&gt;In conclusion, when looking for memory leaks, be aware that the automation API can keep your objects alive for longer than you expect.&amp;#160;&amp;#160; You can mitigate bugs this may cause by properly detaching objects from external events and removing strong references to existing objects when you dispose or unload them.&amp;#160; Finally, profile your application frequently as lots of things can show up that may help you fix issues before they escalate into week-long bug hunts.&lt;/p&gt;&lt;img src="http://www.wintellect.com/CS/aggbug.aspx?PostID=19768" width="1" height="1"&gt;</description></item><item><title>Resumable downloads in Silverlight Out-Of-Browser applications</title><link>http://www.wintellect.com/CS/blogs/sloscialo/archive/2011/03/21/resumable-downloads-in-silverlight-out-of-browser-applications.aspx</link><pubDate>Mon, 21 Mar 2011 23:52:29 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:19681</guid><dc:creator>sloscialo</dc:creator><slash:comments>0</slash:comments><comments>http://www.wintellect.com/CS/blogs/sloscialo/comments/19681.aspx</comments><wfw:commentRss>http://www.wintellect.com/CS/blogs/sloscialo/commentrss.aspx?PostID=19681</wfw:commentRss><description>&lt;p&gt;The task facing us is simple.&amp;#160; In fact, it has been done before.&amp;#160; Many download management tools already have the ability to resume downloading a file if, for some reason, the process was interrupted.&amp;#160; There is no built-in facility for resuming an interrupted download within a Silverlight applications.&amp;#160; Silverlight does provide some tools for working around this limitation, but only while running under elevated privileges in an out-of-browser application.&lt;/p&gt;  &lt;h1&gt;A little background&lt;/h1&gt;  &lt;p&gt;The HTTP/1.1 specification defines an Accept-Ranges response header.&amp;#160; This header is not required by servers and therefore is not guaranteed to be there whenever a file needs to be downloaded.&amp;#160; Servers that do support it will typically send back a header that includes the following header fields:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&lt;strong&gt;Accept-Ranges: bytes | none          &lt;br /&gt;&lt;/strong&gt;&lt;/font&gt;&lt;strong&gt;&lt;font size="2" face="Consolas"&gt;Content-Length: xxxx&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The Accept-Ranges field will equal “bytes” if the server supports byte range on GET commands.&amp;#160;&amp;#160; Additionally, the Content-Length field will equal the total size of the file being downloaded. &lt;/p&gt;  &lt;p&gt;Once a server has been determined to support byte ranges, HTTP GET requests can include an additional header field to retrieve a block of data.&amp;#160; The size of the block is defined by the application by sending start and end indices.&amp;#160; The following header field request the first 1024 bytes from the server.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&lt;strong&gt;Ranges: bytes=0-1023&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h1&gt;Silverlight Implementation&lt;/h1&gt;  &lt;p&gt;With that background, the process for creating a resumable downloader in Silverlight OOB is rather straight-forward.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Check to see if the file has not finished downloading &lt;/li&gt;    &lt;li&gt;Assuming it’s not finished, request next chunk of data and append to the existing partial file. &lt;/li&gt;    &lt;li&gt;Continue requesting chunks and appending until finished. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Several implementations are possible: for example, a temporary file can be used to hold the partial file and its existence lets the implementation know that the download is not finished.&amp;#160; An alternative method could be to compare the length of the file on disk with the length returned from the HEAD Http request.&amp;#160; &lt;/p&gt;  &lt;p&gt;The purpose of the following code snippets are to convey the concepts behind creating a resumable downloader rather than provide a complete implementation.&amp;#160; A full-featured resumable downloader may be posted at future data, time permitting.&amp;#160; But there should be enough here to get you going.&lt;/p&gt;  &lt;h5&gt;Creating an Http/1.1 HEAD request&lt;/h5&gt;  &lt;p&gt;In order to get started we need to know two things: whether the server supports the Range header and the size of the file we want to download.&amp;#160; The HEAD request will enable us, in essence, to query the capabilities of the server and determine the size of the file in one round-trip.&amp;#160; Using the HttpWebRequest class is necessary to make the HEAD request.&amp;#160; We use the asynchronous BeginGetResponse() method to initiate the communication with the server.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;font face="Consolas"&gt;&lt;span style="color:#ffc66d;"&gt;WebRequest&lt;/span&gt;&lt;span style="color:white;"&gt;.RegisterPrefix(&lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;http://&amp;quot;&lt;/span&gt;&lt;span style="color:white;"&gt;, &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;WebRequestCreator&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;.ClientHttp);
&lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;WebRequest&lt;/span&gt;&lt;span style="color:white;"&gt;.RegisterPrefix(&lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;https://&amp;quot;&lt;/span&gt;&lt;span style="color:white;"&gt;, &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;WebRequestCreator&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;.ClientHttp);

&lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;HttpWebRequest &lt;/span&gt;&lt;span style="color:white;"&gt;webRequest = (&lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;HttpWebRequest&lt;/span&gt;&lt;span style="color:white;"&gt;)&lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;WebRequest&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;.Create(downloadUri);
webRequest.Method = &lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;HEAD&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;span style="color:white;"&gt;&lt;font face="Consolas"&gt;;

webRequest.BeginGetResponse(OnHttpCheckHeadersResponse, webRequest);&lt;/font&gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;By setting the request method to “HEAD”, only the relevant header information will be returned and the actual download will not start.&amp;#160; In the callback, the header can be processed and the download can be started based on the results. Below is a sample of what the callback may look like.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font face="Consolas"&gt;&lt;span style="color:#cc7832;"&gt;private void &lt;/span&gt;&lt;span style="color:white;"&gt;OnHttpCheckHeadersResponse(&lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IAsyncResult &lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;result)
{
    &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;HttpWebRequest &lt;/span&gt;&lt;span style="color:white;"&gt;request = result.AsyncState &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;as &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;HttpWebRequest&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;;
    &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;if &lt;/span&gt;&lt;span style="color:white;"&gt;(request == &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;null&lt;/span&gt;&lt;span style="color:white;"&gt;) &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;throw new &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;Exception&lt;/span&gt;&lt;span style="color:white;"&gt;(&lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;There was a problem with the web request.&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;span style="color:white;"&gt;&lt;font face="Consolas"&gt;);

    &lt;/font&gt;&lt;/span&gt;&lt;span style="color:#cc7832;"&gt;&lt;font face="Consolas"&gt;try
    &lt;/font&gt;&lt;/span&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;{
        &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;var &lt;/span&gt;&lt;span style="color:white;"&gt;response = (&lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;HttpWebResponse&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;)request.EndGetResponse(result);
        &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;var &lt;/span&gt;&lt;span style="color:white;"&gt;acceptsRange = response.Headers[&lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;Accept-Ranges&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;];

        &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;if &lt;/span&gt;&lt;span style="color:white;"&gt;(acceptsRange.Equals(&lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;bytes&amp;quot;&lt;/span&gt;&lt;span style="color:white;"&gt;, &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;StringComparison&lt;/span&gt;&lt;/font&gt;&lt;span style="color:white;"&gt;&lt;font face="Consolas"&gt;.CurrentCultureIgnoreCase))
        {
            &lt;/font&gt;&lt;/span&gt;&lt;font face="Consolas"&gt;&lt;span style="color:#6a9768;"&gt;// Accepts partial downloads.
            &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;string &lt;/span&gt;&lt;span style="color:white;"&gt;sizeString = response.Headers[&lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;Content-Length&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;];
            &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;if &lt;/span&gt;&lt;span style="color:white;"&gt;(&lt;/span&gt;&lt;span style="color:#cc7832;"&gt;long&lt;/span&gt;&lt;span style="color:white;"&gt;.TryParse(sizeString, &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;out &lt;/span&gt;&lt;/font&gt;&lt;span style="color:white;"&gt;&lt;font face="Consolas"&gt;_length))
            {
                ResumableDownload();
            }
        }
        &lt;/font&gt;&lt;/span&gt;&lt;span style="color:#cc7832;"&gt;&lt;font face="Consolas"&gt;else
        &lt;/font&gt;&lt;/span&gt;&lt;span style="color:white;"&gt;&lt;font face="Consolas"&gt;{
            &lt;/font&gt;&lt;/span&gt;&lt;span style="color:#6a9768;"&gt;&lt;font face="Consolas"&gt;// Download the whole thing at once and hope for the best.
            &lt;/font&gt;&lt;/span&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;NonResumableDownload();
        }
    }
    &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;catch &lt;/span&gt;&lt;span style="color:white;"&gt;(&lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;Exception &lt;/span&gt;&lt;/font&gt;&lt;span style="color:white;"&gt;&lt;font face="Consolas"&gt;e)
    {
        &lt;/font&gt;&lt;/span&gt;&lt;font face="Consolas"&gt;&lt;span style="color:#6a9768;"&gt;// Possibly a 404 error.
        &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;throw &lt;/span&gt;&lt;/font&gt;&lt;span style="color:white;"&gt;&lt;font face="Consolas"&gt;e;
    }
}&lt;/font&gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Of course, the actual implementation may differ.&amp;#160; For example, header information could be stored in a separate structure, firing events or using messages to signal completion of the header parsing are all viable options.&lt;/p&gt;

&lt;p&gt;The remainder of the implementation requires downloading the actual file one piece at a time.&amp;#160; Assuming that the downloader may be in a state where a portion of the file was downloaded earlier, a check is needed to determine where to begin.&amp;#160; If we’re using a temporary file, the downloader can first determine if the file exists, and if it does, determine its current size.&amp;#160; That code may look something like the following, where DownloadBlockSize is a constant used to define the size of the block to download:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:#cc7832;"&gt;&lt;font face="Consolas"&gt;string &lt;/font&gt;&lt;/span&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;destinationFile = CreateDestinationFileFromUri(downloadUri);
&lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;FileInfo &lt;/span&gt;&lt;span style="color:white;"&gt;tempFile = &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;new &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;FileInfo&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;(destinationFile + &lt;span style="color:#a5c25c;"&gt;&amp;quot;.tmp&amp;quot;&lt;/span&gt;);

&lt;/span&gt;&lt;span style="color:#cc7832;"&gt;if &lt;/span&gt;&lt;/font&gt;&lt;span style="color:white;"&gt;&lt;font face="Consolas"&gt;(!tempFile.Exists)
{
    StartBytesIndex = 0;
    EndBytesIndex = DownloadBlockSize;
}
&lt;/font&gt;&lt;/span&gt;&lt;span style="color:#cc7832;"&gt;&lt;font face="Consolas"&gt;else
&lt;/font&gt;&lt;/span&gt;&lt;span style="color:white;"&gt;&lt;font face="Consolas"&gt;{
    StartBytesIndex = tempFile.Length;
    EndBytesIndex = StartBytesIndex + DownloadBlockSize;
}&lt;/font&gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;At this point, the downloader now has a starting and ending index to request a portion of the file from the server.&amp;#160; The final piece of the puzzle simply sets up a loop to continually download chunks of data from the server until there is no more data.&amp;#160; Once again, an HttpWebRequest is used to create a GET request with the Range header property set to the appropriate block of data by simply using the StartByteIndex and EndByteIndex discovered when resuming the download.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:#cc7832;"&gt;&lt;font face="Consolas"&gt;public void &lt;/font&gt;&lt;/span&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;ResumableDownload()
{
    &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;WebRequest&lt;/span&gt;&lt;span style="color:white;"&gt;.RegisterPrefix(&lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;http://&amp;quot;&lt;/span&gt;&lt;span style="color:white;"&gt;, &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;WebRequestCreator&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;.ClientHttp);
    &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;WebRequest&lt;/span&gt;&lt;span style="color:white;"&gt;.RegisterPrefix(&lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;https://&amp;quot;&lt;/span&gt;&lt;span style="color:white;"&gt;, &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;WebRequestCreator&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;.ClientHttp);

    &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;HttpWebRequest &lt;/span&gt;&lt;span style="color:white;"&gt;webRequest = (&lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;HttpWebRequest&lt;/span&gt;&lt;span style="color:white;"&gt;)&lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;WebRequest&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;.Create(downloadUri);
    webRequest.Method = &lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;HEAD&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;;

    webRequest.Headers[&lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;Range&amp;quot;&lt;/span&gt;&lt;span style="color:white;"&gt;] = &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;string&lt;/span&gt;&lt;span style="color:white;"&gt;.Format(&lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;bytes={0}-{1}&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;, 
        StartBytesIndex, 
        (EndBytesIndex &amp;lt;= Length) ? EndBytesIndex.ToString() : &lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;span style="color:white;"&gt;&lt;font face="Consolas"&gt;);

    webRequest.BeginGetResponse(OnHttpGetRangeResponse, webRequest);
}&lt;/font&gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Like the HEAD request implementation, the majority of the GET request resides in the asynchronous callback.&amp;#160; In the code snippet below, the object, partialFileStream is a previously opened writeable stream to the temporary file.&amp;#160; Since the downloader will attempt to download as much as possible, it should not close and reopen the file with each range received from the server.&amp;#160; The Flush() method will insure that the block of data is written to the temporary file.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font face="Consolas"&gt;&lt;span style="color:#cc7832;"&gt;private void &lt;/span&gt;&lt;span style="color:white;"&gt;OnHttpGetRangeResponse(&lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IAsyncResult &lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;result)
{
    &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;HttpWebRequest &lt;/span&gt;&lt;span style="color:white;"&gt;request = result.AsyncState &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;as &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;HttpWebRequest&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;;
    &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;if &lt;/span&gt;&lt;span style="color:white;"&gt;(request == &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;null&lt;/span&gt;&lt;span style="color:white;"&gt;) &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;throw new &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;Exception&lt;/span&gt;&lt;span style="color:white;"&gt;(&lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;There was a problem with the web request.&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;);

    &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;var &lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;response = request.EndGetResponse(result);

    &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;using &lt;/span&gt;&lt;span style="color:white;"&gt;(&lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;Stream &lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;responseStream = response.GetResponseStream())
    {
        CopyStream(responseStream, partialFileStream);
        responseStream.Close();
    }

    partialFileStream.Flush();
    OnDownloadRangeComplete();

    &lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;StartBytesIndex += DownloadBlockSize + 1;
    &lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;span style="color:white;"&gt;EndBytesIndex = StartBytesIndex + DownloadBlockSize;

    &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;if &lt;/span&gt;&lt;/font&gt;&lt;span style="color:white;"&gt;&lt;font face="Consolas"&gt;(RemainingBytes &amp;gt; 0)
        ResumableDownload();
    &lt;/font&gt;&lt;/span&gt;&lt;span style="color:#cc7832;"&gt;&lt;font face="Consolas"&gt;else
        &lt;/font&gt;&lt;/span&gt;&lt;span style="color:white;"&gt;&lt;font face="Consolas"&gt;FinishDownload();
}&lt;/font&gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;To finish the implementation, all that needs to be done is close the open file handle and possibly rename any temporary files.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:#cc7832;"&gt;&lt;font face="Consolas"&gt;private void &lt;/font&gt;&lt;/span&gt;&lt;span style="color:white;"&gt;&lt;font face="Consolas"&gt;FinishDownload()
{
    partialFileStream.Close();

    RenameTemporaryFile();
    OnDownloadComplete();
}&lt;/font&gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;h1&gt;&amp;#160;&lt;/h1&gt;

&lt;h1&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;The capability for writing a resumable downloader resides within the Http/1.1 specification.&amp;#160; Implementing the specification in Silverlight requires that Silverlight runs out-of-browser and has elevated privileges.&amp;#160; Silverlight applications not running with these caveats will not be able to query the file system for the existing of the partially downloaded file or arbitrarily write to files.&amp;#160; Silverlight requires explicit permission from the user to begin writing to the file system (this would eliminate using temporary files).&amp;#160; Theoretically, there may be an implementation that will allow for resumable downloads in vanilla Silverlight, but the usability will probably be questionable.&amp;#160; Of course, this may change in a future version of Silverlight.&lt;/p&gt;

&lt;p&gt;As always, constructive feedback is welcome.&lt;/p&gt;&lt;img src="http://www.wintellect.com/CS/aggbug.aspx?PostID=19681" width="1" height="1"&gt;</description></item><item><title>WPF – Animating multiple elements simultaneously</title><link>http://www.wintellect.com/CS/blogs/sloscialo/archive/2009/08/06/wpf-animating-multiple-elements-simultaneously.aspx</link><pubDate>Thu, 06 Aug 2009 15:57:00 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:8471</guid><dc:creator>sloscialo</dc:creator><slash:comments>1</slash:comments><comments>http://www.wintellect.com/CS/blogs/sloscialo/comments/8471.aspx</comments><wfw:commentRss>http://www.wintellect.com/CS/blogs/sloscialo/commentrss.aspx?PostID=8471</wfw:commentRss><description>&lt;p&gt;A question appeared on StackOverflow asking how to animate a property on multiple elements from one or more trigger mechanisms (i.e. a button click or list box selection).&amp;#160; The traditional approach (for brevity’s sake, I omitted the Xaml comprising the actual UI elements) is rather straight-forward:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;p&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Window.Resources&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Storyboard&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;x:Key&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;OnClick1&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;DoubleAnimationUsingKeyFrames&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;BeginTime&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;00:00:00&amp;quot;&lt;/span&gt; &lt;br /&gt;                                       &lt;span style="color:#ff0000;"&gt;Storyboard&lt;/span&gt;.&lt;span style="color:#ff0000;"&gt;TargetName&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;textBlock1&amp;quot;&lt;/span&gt; &lt;br /&gt;                                       &lt;span style="color:#ff0000;"&gt;Storyboard&lt;/span&gt;.&lt;span style="color:#ff0000;"&gt;TargetProperty&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;(UIElement.Opacity)&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;SplineDoubleKeyFrame&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;KeyTime&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;00:00:00&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;SplineDoubleKeyFrame&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;KeyTime&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;00:00:00.5000000&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;DoubleAnimationUsingKeyFrames&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;DoubleAnimationUsingKeyFrames&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;BeginTime&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;00:00:00&amp;quot;&lt;/span&gt; &lt;br /&gt;                                       &lt;span style="color:#ff0000;"&gt;Storyboard&lt;/span&gt;.&lt;span style="color:#ff0000;"&gt;TargetName&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;textBlock2&amp;quot;&lt;/span&gt; &lt;br /&gt;                                       &lt;span style="color:#ff0000;"&gt;Storyboard&lt;/span&gt;.&lt;span style="color:#ff0000;"&gt;TargetProperty&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;(UIElement.Opacity)&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;SplineDoubleKeyFrame&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;KeyTime&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;00:00:00&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;SplineDoubleKeyFrame&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;KeyTime&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;00:00:00.5000000&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;DoubleAnimationUsingKeyFrames&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;DoubleAnimationUsingKeyFrames&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;BeginTime&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;00:00:00&amp;quot;&lt;/span&gt; &lt;br /&gt;                                       &lt;span style="color:#ff0000;"&gt;Storyboard&lt;/span&gt;.&lt;span style="color:#ff0000;"&gt;TargetName&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;textBlock3&amp;quot;&lt;/span&gt; &lt;br /&gt;                                       &lt;span style="color:#ff0000;"&gt;Storyboard&lt;/span&gt;.&lt;span style="color:#ff0000;"&gt;TargetProperty&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;(UIElement.Opacity)&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;SplineDoubleKeyFrame&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;KeyTime&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;00:00:00&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;SplineDoubleKeyFrame&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;KeyTime&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;00:00:00.5000000&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;DoubleAnimationUsingKeyFrames&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;DoubleAnimationUsingKeyFrames&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;BeginTime&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;00:00:00&amp;quot;&lt;/span&gt; &lt;br /&gt;                                       &lt;span style="color:#ff0000;"&gt;Storyboard&lt;/span&gt;.&lt;span style="color:#ff0000;"&gt;TargetName&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;textBlock4&amp;quot;&lt;/span&gt; &lt;br /&gt;                                       &lt;span style="color:#ff0000;"&gt;Storyboard&lt;/span&gt;.&lt;span style="color:#ff0000;"&gt;TargetProperty&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;(UIElement.Opacity)&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;SplineDoubleKeyFrame&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;KeyTime&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;00:00:00&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;SplineDoubleKeyFrame&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;KeyTime&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;00:00:00.5000000&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;DoubleAnimationUsingKeyFrames&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Storyboard&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#0000ff;"&gt;    &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Window.Triggers&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;EventTrigger&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;RoutedEvent&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;ButtonBase.Click&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;SourceName&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;button&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;BeginStoryboard&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Storyboard&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;{StaticResource OnClick1}&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;EventTrigger&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Window.Triggers&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Window.Resources&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;div&gt;The major complaint about the above solution is the repetition of the Animations.&amp;#160; Since each TextBlock implements the same animation, an easier to maintain solution would be ideal.&amp;#160; Initially, I believed a Xaml-only solution would not be possible, but StackOverflow user, kek444, put me onto a simple trick of animating a single value and DataBinding the TextBlocks to it.&amp;#160; While his solution involved setting the DataContext on an element, I believe using a placeholder element is a cleaner approach (however, I’m sure this is open to debate).&lt;/div&gt;

&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;div&gt;The updated version of the above Xaml would look as follows: 
  &lt;br /&gt;&lt;/div&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;p&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Window.Resources&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;UIElement&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;x:Key&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;AnimationPlaceholder&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Opacity&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#0000ff;"&gt;&lt;/span&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Style&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;TargetType&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;TextBlock&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Setter&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Property&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;Opacity&amp;quot;&lt;/span&gt; &lt;br /&gt;                &lt;span style="color:#ff0000;"&gt;Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;{Binding Source={StaticResource AnimationPlaceholder}, Path=Opacity}&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Style&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Storyboard&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;x:Key&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;OnClick1&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;DoubleAnimationUsingKeyFrames&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;BeginTime&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;00:00:00&amp;quot;&lt;/span&gt; &lt;br /&gt;                                       &lt;span style="color:#ff0000;"&gt;Storyboard&lt;/span&gt;.&lt;span style="color:#ff0000;"&gt;Target&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;{StaticResource AnimationPlaceholder}&amp;quot;&lt;/span&gt; &lt;br /&gt;                                       &lt;span style="color:#ff0000;"&gt;Storyboard&lt;/span&gt;.&lt;span style="color:#ff0000;"&gt;TargetProperty&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;(UIElement.Opacity)&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;SplineDoubleKeyFrame&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;KeyTime&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;00:00:00&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;SplineDoubleKeyFrame&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;KeyTime&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;00:00:00.5000000&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;DoubleAnimationUsingKeyFrames&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Storyboard&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Window.Triggers&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;EventTrigger&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;RoutedEvent&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;ButtonBase.Click&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;SourceName&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;button&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;BeginStoryboard&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Storyboard&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;{StaticResource OnClick1}&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;EventTrigger&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Window.Triggers&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Window.Resources&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;In this snippet, I’m using a UIElement to hold the animation value since it supports the Opacity property (but in fact, any property of type double, would suffice).&amp;#160; Also, if you’re not adverse to a little coding, a custom class could be created to contain the values you wish to change for a particular animation.&amp;#160; A style is created to affect all TextBoxes, but this can easily be modified to use explicit styling.&amp;#160; Finally, the Storyboard targets the placeholder object and changes its value from 0 to 1 over 0.5 seconds.&amp;#160; The style uses DataBinding to bind its Opacity property to the placeholder’s.&lt;/p&gt;

&lt;p&gt;Though Blend creates a lot of the Xaml for you when creating trigger-based animations, sometimes the result can be less than ideal.&amp;#160; Additionally, as I’ve had reinforced through this little exercise, there is more than one way to skin a cat when it comes to Xaml, so please feel free to comment with refinements or alternative solutions.&lt;/p&gt;&lt;img src="http://www.wintellect.com/CS/aggbug.aspx?PostID=8471" width="1" height="1"&gt;</description><category domain="http://www.wintellect.com/CS/blogs/sloscialo/archive/tags/WPF/default.aspx">WPF</category><category domain="http://www.wintellect.com/CS/blogs/sloscialo/archive/tags/Animation/default.aspx">Animation</category></item></channel></rss>
