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

<channel>
	<title>Jeff Wilcox &#187; Silverlight</title>
	<atom:link href="http://www.jeff.wilcox.name/topics/dev/silverlight/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jeff.wilcox.name</link>
	<description>Silverlight, rich client apps and web development</description>
	<lastBuildDate>Wed, 18 Aug 2010 01:33:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Exploring List capacities and growth on the Windows Phone</title>
		<link>http://www.jeff.wilcox.name/2010/08/list-capacity-info/</link>
		<comments>http://www.jeff.wilcox.name/2010/08/list-capacity-info/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 01:33:15 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/08/list-capacity-info/</guid>
		<description><![CDATA[Since the generic .NET list (List&#60;T&#62; documentation) is a pretty common data structure found in phone apps, I figured it was worth a few minutes to direct everyone’s attention to how the list and its capacity works on the phone. Unlike desktop computers, where we’re often dealing with gigabytes of potential memory on a modern [...]]]></description>
			<content:encoded><![CDATA[<p>Since the generic .NET list (<a href="http://msdn.microsoft.com/en-us/library/6sh2ey19(v=VS.95).aspx">List&lt;T&gt; documentation</a>) is a pretty common data structure found in phone apps, I figured it was worth a few minutes to direct everyone’s attention to how the list and its capacity works on the phone.</p>
<p>Unlike desktop computers, where we’re often dealing with gigabytes of potential memory on a modern operating system, the phone has a number of fun and unique memory challenges that managed code developers should be cognizant of.</p>
<p>If you’re using the generic lists in your Windows Phone application, it’s OK to have a bunch sitting around – their default capacity is actually zero until you add items, but you can alter this behavior.</p>
<h3>Constructed capacity is ZERO</h3>
<p>When you create a new List&lt;T&gt;, the constructed capacity is 0. This means that the cost of creating a new list of pretty minimal, and creating one does <em>not</em> typically allocate any memory for items.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:ee0d0411-ba53-4ace-b625-7f9b03d8f281" class="wlWriterEditableSmartContent">
<pre class="c-sharp" name="code">List&lt;string&gt; myList = new List&lt;string&gt;();
// myList.Capacity == 0</pre>
</div>
<p>I’ve heard of developers who used to think that at construction the list had a large capacity, and that setting an initial size to a few digit number was a performance win. This is often not the case.</p>
<h3>First item brings the capacity to 4 items</h3>
<p>The first time that you add a single item (or a few), you’ll notice that the capacity size on the Windows Phone will be 4. This is because the internal default number of 4.</p>
<p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:0fd3b4b0-62db-4fe2-bfd5-7a8d38fca0b4" class="wlWriterEditableSmartContent">
<pre class="c-sharp" name="code">List&lt;string&gt; myList = new List&lt;string&gt;();
// myList.Capacity == 0

myList.Add("hello");
// myList.Capacity == 4</pre>
</div>
<p>You can add 4 items and the capacity will remain at 4.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:44939a17-d2ae-44f1-9da5-4d1d9a88cba8" class="wlWriterEditableSmartContent">
<pre class="c-sharp" name="code">List&lt;string&gt; myList = new List&lt;string&gt;();
// myList.Capacity == 0

myList.Add("hello");
// myList.Capacity == 4

myList.Add("world!");
// myList.Capacity == 4

myList.Add("bonjour");
// myList.Capacity == 4

myList.Add("le monde!");
// myList.Capacity == 4</pre>
</div>
<h3>Capacity + 1 grows the capacity exponentially</h3>
<p>Once the Count == Capacity, it will exponentially grow the capacity. So the capacity will move from 4 to 8 to 16 to 32, 64, 128, 256, … 1024, and so on.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:9d8d73e5-5827-4d68-afa1-024e1e72eff4" class="wlWriterEditableSmartContent">
<pre class="c-sharp" name="code">List&lt;string&gt; myList = new List&lt;string&gt;();
// myList.Capacity == 0

myList.Add("hello");
// myList.Capacity == 4

myList.Add("world!");
// myList.Capacity == 4

myList.Add("bonjour");
// myList.Capacity == 4

myList.Add("le monde!");
// myList.Capacity == 4

myList.Add("a fifth item.");
// myList.Capacity == 8</pre>
</div>
<h3>Clipping the capacity back</h3>
<p>If you’re in a situation where you’ve added say 500 names from a database, but the capacity is going to be at 1024 at this point, it might be worth clipping back the capacity. Just call the TrimExcess method on the generic list instance.</p>
<p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:d3eaaee0-459f-4178-9e4b-3707b75f3f45" class="wlWriterEditableSmartContent">
<pre class="c-sharp" name="code">myList.TrimExcess();</pre>
</div>
<h3>Initializing to a set size</h3>
<p>And if you want to keep from potentially re-allocating memory as you add a lot of items, you can always initialize your list to a smart default number that is much larger than 0 or the default capacity of 4 by providing a size in the constructor.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:f3edda01-91da-462a-ad79-f8460e550c69" class="wlWriterEditableSmartContent">
<pre class="c-sharp" name="code">List&lt;string&gt; myList = new List&lt;string&gt;(900);
// myList.Capacity == 900</pre>
</div>
<p>Note that the capacity will exactly match the number you provide – it won’t jump up to the next exponent or anything like that. Of course it’s possible that behind the scenes the CLR is allocating a specific type of memory on the heap, but as far as numbers exposed to managed code, this is what you get.</p>
<p>Hope this helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/08/list-capacity-info/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Windows Phone performance progress bar update: part 2, remember to turn IsIndeterminate off when not needed!</title>
		<link>http://www.jeff.wilcox.name/2010/08/progressbarperftips2/</link>
		<comments>http://www.jeff.wilcox.name/2010/08/progressbarperftips2/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 21:38:28 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/08/progressbarperftips2/</guid>
		<description><![CDATA[Expanded phone progress bar performance guidance: use an improved template and always toggle IsIndeterminate when not needed.]]></description>
			<content:encoded><![CDATA[<p>Your application’s progress bar should look good, but it should minimize its cost as much as possible to ensure that the available CPU cycles are spent doing your hard work – parsing code, making and processing web requests, and responding to the user’s touch input – all of which happens on the UI thread.</p>
<p>On top of my previous <a href="http://www.jeff.wilcox.name/2010/08/performanceprogressbar/">post with a high performance progress bar</a>, I’ve identified uses of progress bars where the IsIndeterminate value is hard-coded to True, and only visibility collapsing is used to show/hide the effect. This actually also has a negative effect on performance when not in use, as the animation defined when IsIndeterminate==True is continuous, forever looping, and going to have some effect on the main user interface thread just computing animation states, properties, and communicating with the core platform.</p>
<p>This came up as I was involved in a code review of a really sweet Windows Phone application that’s under development&#8230; Really sweet looking app, world class devs, and quality code – even a nicely architected lightweight model-view design. The application was using multiple indeterminate progress bars, plus my template, but was seeing performance degradation at times of 15-25 fps less than what we would hope for given the concious work to improve perf.</p>
<p>Turns out, having a bunch of progress bars on screen, with Indeterminate mode on, but collapsed, was still having a toll on the frame rates as all animations incur some cost, even if you never see them on screen.</p>
<p>This was an easy fix and I wanted to add this as guidance for having a good experience with progress bars in your phone apps.</p>
<h3>1: Use PerformanceProgressBar over the built-in ProgressBar style</h3>
<p><a href="http://www.jeff.wilcox.name/2010/08/performanceprogressbar/">Step one: please use my PerformanceProgressBar in your application.</a> It’s very easy to add in about 5 minutes and will pay dividends as your app gets faster. Progress bars as especially important to have low cost as they typically are only shown during potentially expensive operations.</p>
<p>As a recap, the <font size="2" face="Consolas">&lt;ProgressBar <strong>IsIndeterminate=”True”</strong>/&gt;</font> control built into the platform has an adverse effect on the user interface thread’s frame rate. This is because it the indeterminate animation is built up of 5 sliding rectangles, built from Slider controls with custom thumbs, and all that work needs to happen five times over every single frame on the UI stack. You can <a href="http://www.jeff.wilcox.name/2010/08/performanceprogressbar/">read more about it</a> if you like.</p>
<h3>2: Turn off IsIndeterminate when not needed</h3>
<p>When looking at this particular app, this was being used to show/hide the indeterminate progress bar. It means that the continuous animations and storyboard is <em>always</em> costing computing resources, so this is not what you want.</p>
<p><strong>Try not to do this:</strong></p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:194ce6bf-4647-4269-9dcf-fb8b96de8bf4" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;ProgressBar
    HorizontalAlignment="Left"
    VerticalAlignment="Center"
    IsIndeterminate="True"
    Style="{StaticResource PerformanceProgressBar}"
    Visibility="{Binding IsProgressBarVisible, Converter={StaticResource VisibilityConverter}}"
/&gt;</pre>
</div>
<p>Now this should have also data bound the IsIndeterminate property. Since there’s a Visibility converter being used already here, this is an easy fix – just directly bind the bool property that the converter was using as an input. So this is additive.</p>
<p><strong>Do try this:</strong></p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:cd801c38-ef35-4cec-8d47-52cc11eb6828" class="wlWriterEditableSmartContent">
<pre class="brush: xml; highlight: [4]" name="code">&lt;ProgressBar
    HorizontalAlignment="Left"
    VerticalAlignment="Center"
    IsIndeterminate="{Binding IsProgressBarVisible}"
    Style="{StaticResource PerformanceProgressBar}"
    Visibility="{Binding IsProgressBarVisible, Converter={StaticResource VisibilityConverter}}"
/&gt;</pre>
</div>
<p>So to properly “turn off” the indeterminate (continuous animation) from the progress bar, whether using the built-in progress bar or the template in my <a href="http://www.jeff.wilcox.name/2010/08/performanceprogressbar/">performance progress bar</a>, you want to:</p>
<ul>
<li>Bind or set the IsIndeterminate property: It should be False when you no longer need the continuous animations</li>
<li>Collapse the Visibility of the progress bar when not needed</li>
</ul>
<p>Hope this helps.
  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/08/progressbarperftips2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Blend tip: finding default styles using &#8220;Edit a Copy&#8221;</title>
		<link>http://www.jeff.wilcox.name/2010/08/using-blend-to-find-default-style-xaml/</link>
		<comments>http://www.jeff.wilcox.name/2010/08/using-blend-to-find-default-style-xaml/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 00:43:42 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/08/using-blend-to-find-default-style-xaml/</guid>
		<description><![CDATA[Here's a super quick tutorial on how to use Blend to find the default control styles and templates.]]></description>
			<content:encoded><![CDATA[<p>If you’ve spent much time re-templating controls in Silverlight, WPF, or the Windows Phone, it’s clear that sometimes you want to understand the essence of a control through its template… but that XAML doesn’t feel easy to find at first glance. </p>
<p>Silverlight has the <a href="http://msdn.microsoft.com/en-us/library/cc278075(v=VS.95).aspx">default styles and templates published on MSDN</a>… for example, <a href="http://msdn.microsoft.com/en-us/library/cc278062(VS.95).aspx">list boxes</a>, <a href="http://msdn.microsoft.com/en-us/library/dd334411(v=VS.95).aspx">content control</a>, and <a href="http://msdn.microsoft.com/en-us/library/dd728668(v=VS.95).aspx">auto complete box</a>. You’ll find nice documentation with the actual template parts, visual states, and then the style that is built into the control library’s <em>Themes\Generic.xaml</em> resource dictionary.</p>
<p>However if you talk to an Expression Blend voodoo master, you will learn that it’s easier than searching on MSDN. Easy as in like 10 seconds.</p>
<p>Here’s a quick tutorial to something that comes up pretty often on discussion lists. I’m going to grab the &lt;Button /&gt; default style &amp; control template from the <a href="http://windowsteamblog.com/windows_phone/b/wpdev/archive/2010/07/12/windows-phone-developer-tools-beta-released.aspx">beta Windows Phone developer tools</a>.</p>
<h3>Getting started</h3>
<p>Open Expression Blend.</p>
<p>Create a new application project.</p>
<h3>Add the control that you’d like the template or style of</h3>
<p>In my example, I’m dragging the standard Button from the Assets library on to the design surface.</p>
<h3>Use the Edit Template menu right-click option</h3>
<p>Right-click on the newly created button, then select the Edit Template menu, and “Edit a Copy…”</p>
<p><img src="http://media.jeff.wilcox.name/blog/ButtonRightClick.png" /></p>
<p>This will open up the “Create Style Resource” window. You can keep the defaults: it should place a copy of the default control style (which contains the control template) inside the current page’s resources (near the top of the file).</p>
<p>Click OK.</p>
<p><img src="http://media.jeff.wilcox.name/blog/ButtonCreateStyleResource.png" /></p>
<p>Now your button will look the same, though technically you’re in template editing mode. We’re just interested in the XAML now that will be in the resources.</p>
<h3>View the XAML</h3>
<p>To the top right of the design surface (next to Properties in the standard layout) are 3 little icons, from top to bottom they are “Design”, “XAML”, and “Split”. Click on the middle “XAML” button for our use.</p>
<p><img src="http://media.jeff.wilcox.name/blog/XamlViewButton.png" /></p>
<p>Now the page is opened, and in the resources you will see the default style for the control, with an x:Key added. Easy to see, examine, and re-use. It will have also connected the Button instance from earlier up to use that static style resource.</p>
<p><img src="http://media.jeff.wilcox.name/blog/XamlView.png" /></p>
<h3>Note: Nested styles and templates</h3>
<p>If you need to get a nested style, such as ListBoxItem within the ListBox, when you’re in the template editing mode above, you can actually select other controls and templates and edit copies of them, too.</p>
<h3>Note: Windows Phone developer tools theme XAML</h3>
<p>Another quick way to find the Windows Phone XAML is to open up the various files you will find at your 32-bit Program Files under “Microsoft SDKs\Windows Phone\v7.0\Design\”.</p>
<p>Hope this helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/08/using-blend-to-find-default-style-xaml/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Looking ahead: Panorama and Pivot controls for Windows Phone developers</title>
		<link>http://www.jeff.wilcox.name/2010/08/looking-ahead-at-panorama-and-pivot/</link>
		<comments>http://www.jeff.wilcox.name/2010/08/looking-ahead-at-panorama-and-pivot/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 05:10:42 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/08/looking-ahead-at-panorama-and-pivot/</guid>
		<description><![CDATA[Here's a preview of what to expect with the Panorama and Pivot controls that will be built into the Windows Phone Developer Tools.]]></description>
			<content:encoded><![CDATA[<p>Apps in Windows Phone 7 make it easy to explore and experience information thanks to two similar navigation controls: panorama and pivot controls. We’ve made it easy for developers to build applications with these experiences by putting these Silverlight controls and associated tooling in the next release of the free developer tools (didn’t make the beta).</p>
<p>The controls are simple &amp; easy to use, but I’ve seen enough rumbling on forums to know that developers are anxious to learn more about their capabilities. In lieu of bits, I’m going to introduce these controls and how they appear from a simple API &amp; XAML perspective, so that you’ll have what you need while planning your apps to know how these experiences can fit into your apps.</p>
<p><font color="#ff0000"><strong>Note:</strong> this post contains pre-release information and is subject to change at any time.</font></p>
<p><img src="http://s3.amazonaws.com:80/media.jeff.wilcox.name/blog/PanoramaMusicExperience.png" />     <br /><em>Panorama control inside of the Visual Studio design surface for the Windows Phone 7.</em></p>
<h2>Learning about the native experience</h2>
<p>Since phones are just beginning to trickle out, if you’d like to see what the built-in applications look like, there’s some multimedia up at <a href="http://www.WindowsPhone7.com/">WindowsPhone7.com</a>.</p>
<p>A <strong>panorama</strong> powers the <a href="http://www.windowsphone7.com/multimedia/media5">people</a>, <a href="http://www.windowsphone7.com/multimedia/media3">music + videos</a>, parts of <a href="http://www.windowsphone7.com/multimedia/media19">Office</a>, and more. Many of these have a large background and can be explored by panning and flicking between items. When you’re at one item, you will be able to see a little bit of the next item as well – a hint that there’s more to be explored. When you reach the far side of the panorama, you can keep going to wrap around to the beginning again, saving time.</p>
<p>A <strong>pivot control </strong>powers the <a href="http://www.windowsphone7.com/multimedia/media18">e-mail and calendar</a> pages, operating systems, etc. The top of the pivot control shows the headers for all the different items, and you can swipe and pan between the pages. Just like panorama, the control wraps infinitely – so when you reach the final item, instead of having to flick all the way back to the first item, you can just flick once more.</p>
<h2>Key Features</h2>
<p>Both of the controls are lightweight enough to have great performance, while visually engaging and responsive to touch. Some features:</p>
<ul>
<li>Simple XAML and application programming interfaces </li>
<li>Standard items controls that feels natural to developers, individual items are built from PanoramaItem and PivotItem content controls </li>
<li>Complete data binding support, content template properties and item container styles </li>
<li>Automatic support for light and dark phone themes </li>
<li>Built-in touch navigation: flicks move quickly, while panning past a threshold and releasing the touch will snap to the next item </li>
<li>Beautiful easing animations for sliding during navigation </li>
<li>Extensibility offered through events, visual states, and the ability to re-template </li>
<li>Great tooling comes standard, including app and page templates </li>
</ul>
<p>So let’s take a look at the two controls!</p>
<h2>Panorama</h2>
<p><img src="http://media.jeff.wilcox.name/blog/Panorama685.png" />     <br /><em>A visual depiction of the actual contents of the panorama control stretching beyond the physical size of the screen.</em></p>
<p>From the <a href="http://go.microsoft.com/?linkid=9713252">UI design and interaction guide for Windows Phone 7</a>, the UX folks say:</p>
<blockquote><p>Unlike standard applications that are designed to fit within the confines of the phone screen, these applications offer a unique way to view controls, data, and services by using a long horizontal canvas that extends beyond the confines of the screen.</p>
<p>…</p>
<p>Elements of a panoramic application serve as the starting point for more detailed experiences.</p>
<p>…</p>
<p>The background image is the lowest layer and is meant to give the panorama its rich magazine-like feel. Usually a full-bleed image, the background is potentially the most visual part of the application.</p>
</blockquote>
<p>As all things in design go, what is not on the screen is as important as what is there: the control has a lot of empty space that helps keep the eye focused on the rich experience and data.</p>
<h3>Panorama XAML</h3>
<p>The Panorama control is placed on pages of your application and accepts a title and a background. Panorama sections are defined by PanoramaItem controls, and each has a header. The Title and Header are easiest to use when you’re just inserting text, but they also have associated HeaderTemplate and TitleTemplate dependency properties for data binding scenarios.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:e1baf744-5ace-40d3-bdb9-b882b9287b25" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;controls:Panorama
        Title="my panorama"&gt;
        &lt;controls:Panorama.Background&gt;
            &lt;ImageBrush ImageSource="MyWidescreenBackground.jpg"/&gt;
        &lt;/controls:Panorama.Background&gt;

        &lt;controls:PanoramaItem
            Header="first item"&gt;

            &lt;StackPanel&gt;
                &lt;TextBlock
                    Text="This is a simple sample ..."
                    Style="{StaticResource PhoneTextLargeStyle}"
                    TextWrapping="Wrap"/&gt;
            &lt;/StackPanel&gt;

      &lt;/controls:PanoramaItem&gt;

      &lt;!-- insert other panorama items here in a real app --&gt;
&lt;/controls:Panorama&gt;</pre>
</div>
<h4>About wide horizontal sections</h4>
<p>The panorama allows for special sections that are wider than the screen. Built-in phone hubs often use this for sets of thumbnails, albums, and other displays. If this is the appropriate effect you want for a section, make sure that the PanoramaItem declares that intent by setting the orientation to horizontal. Here’s what the minimized XAML looks like:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:7a6b1486-bd7b-4b6e-b12c-64dbb4a8599b" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;controls:PanoramaItem Orientation="Horizontal"&gt;
    &lt;!-- insert thumbnails and other goods here --&gt;
&lt;/controls:PanoramaItem&gt;</pre>
</div>
<h3>Panorama APIs</h3>
<p>The key application programming interface for the Panorama builds on top of <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol(VS.95).aspx">ItemsControl</a>: so you get the standard items control properties (Items, ItemsSource, etc.), but also additional properties for setting the header, title, and reacting to the currently selected items by the user.</p>
<h4>Microsoft.Phone.Controls.Panorama</h4>
<h5>Dependency Properties</h5>
<ul>
<li>DefaultItem<br />
    <br /><em>Sets the default item that moves into display. Allows your application to store the user’s most recently used panorama item to return to it later, just like the native operating system’s built-in hubs.</em> </li>
<li>HeaderTemplate </li>
<li>SelectedIndex </li>
<li>SelectedItem </li>
<li>Title </li>
<li>TitleTemplate </li>
</ul>
<h5>Events</h5>
<ul>
<li>SelectionChanged<br />
    <br /><em>Allows the developer to hook up to selection changes (navigations from one panorama item to another).</em> </li>
</ul>
<h4>Microsoft.Phone.Controls.PanoramaItem</h4>
<h5>Dependency Properties</h5>
<ul>
<li>Header </li>
<li>HeaderTemplate </li>
<li>Orientation<br />
    <br /><em>Setting the orientation to Horizontal will allow the item to be of a larger size than the control so that the user can pan and navigate within it. By default, this property is Vertical, which means that panning or flicking should instead bring you to the next panorama section.</em> </li>
</ul>
<h2>Pivot control</h2>
<p>The pivot control is a lot like the a tab control, but designed specifically for the phone and touch interaction. The entire pivot control (often the size of the screen and the root element on a page) can be panned, flicked, and manipulated – it’s not just about those headers (though those can be touched to navigate, too).</p>
<p><img src="http://media.jeff.wilcox.name/blog/pivot377.png" /> </p>
<p><em>A simple pivot sample application running in the emulator. Notice that the phone’s theme in the emulator has been set to the light theme, and the control just works without the developer having to do anything.</em></p>
<p>From the <a href="http://go.microsoft.com/?linkid=9713252">design guidelines document</a>:</p>
<blockquote>
<p>A pivot control provides a quick way to manage views or pages within the application. This control can be used for filtering large datasets, viewing multiple data sets, or switching application views. The control places individual views horizontally next to each other, and manages the left and right navigation. Flicking or panning horizontally on the page cycles the pivot functionality.</p>
</blockquote>
<h3>Pivot XAML</h3>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:0ffe79fa-8296-4b2b-a6a0-0692b80e2952" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;controls:Pivot Title="MY APPLICATION"&gt;

    &lt;controls:PivotItem
        Header="welcome"&gt;

        &lt;StackPanel
            Margin="20"&gt;
            &lt;TextBlock
                TextWrapping="Wrap"
                Text=" This is a simple sample ..."
                Style="{StaticResource PhoneTextLargeStyle}"&gt;
            &lt;/TextBlock&gt;
        &lt;/StackPanel&gt;

    &lt;/controls:PivotItem&gt;

    &lt;!-- other pivot items --&gt;
&lt;/controls:Pivot&gt;</pre>
</div>
<h3>Pivot APIs</h3>
<h4>Microsoft.Phone.Controls.Pivot</h4>
<h5>Dependency Properties</h5>
<ul>
<li>HeaderTemplate<br />
    <br /><em>A single data template that can be used for all headers in data binding scenarios.</em> </li>
<li>SelectedIndex </li>
<li>SelectedItem </li>
<li>Title </li>
<li>TitleTemplate </li>
</ul>
<h5>Events</h5>
<ul>
<li>LoadedPivotItem </li>
<li>LoadingPivotItem </li>
<li>SelectionChanged </li>
<li>UnloadedPivotItem </li>
<li>UnloadingPivotItem </li>
</ul>
<h4>Microsoft.Phone.Controls.PivotItem</h4>
<p>Pivot item is a simple content control and does not have any other special properties.</p>
<h2>Visual Studio &amp; Expression Blend Tooling</h2>
<p>The tools are fully integrated with the design tools: if you click on an item in XAML, that item will become the one active in the design surface. There’s also an easy way to add additional items, well-defined control property editing, and so this all makes it really easy to get started building immersive apps.</p>
<h3>Start with a complete application template</h3>
<p>You can start off with an app powered by a panorama or pivot control: File &gt; New Project has built-in templates for these apps.</p>
<p><img src="http://media.jeff.wilcox.name/blog/CreateNewApp.png" /></p>
<h3>Add New Pages</h3>
<p>When you want to add a new Windows Phone page to your app, you can also add one that’s all ready to go with either a panoramic experience or pivot control, too. Just go to the Project menu and select Add New Item:</p>
<p><img src="http://media.jeff.wilcox.name/blog/AddNewItemPage.png" /></p>
<p>This makes it really easy to build out applications as quick as you can click.</p>
<h3>Blend Assets</h3>
<p>If you need to add either control to an existing app, in Blend you’ll find them in the Assets window, so they’re right where you’d expect to find them when you need ‘em.</p>
<p><img src="http://media.jeff.wilcox.name/blog/BlendAssets.png" /></p>
<h3>Easy property editing</h3>
<p>Key properties are easily accessible in the property editor. In this screen capture, you can see how easy it is to change an item to Horizontal mode, or to change the Header property:</p>
<p><img src="http://media.jeff.wilcox.name/blog/BlendCommonProperties.png" /></p>
<h3>Right-click, add new panorama item or pivot item</h3>
<p>Integrated into the design surface you can also add extra items to the controls by right-clicking.</p>
<p>&#160;<img src="http://media.jeff.wilcox.name/blog/VsAddPanoramaItem.png" /> </p>
<p><em>Visual Studio design surface</em></p>
<p>&#160;<img src="http://media.jeff.wilcox.name/blog/BlendAddNewItem.png" /> </p>
<p><em>Expression Blend</em></p>
<h2>Other notes</h2>
<p>The controls can be found in the Microsoft.Phone.Controls namespace of the Microsoft.Phone.Controls.dll assembly, installed with the official Windows Phone Developer Tools.</p>
<p>As we get closer to launch, I’m sure we will have a good list of caveats and suggestions for the controls. Here are a few things that I had in mind that I wanted to share ahead of time, in case you are designing your application experiences and pages today.</p>
<h3>Exposing scrolling data</h3>
<p>If you look at applications on the phone such as Mail, you’ll often see that the Pivot control is used to filter and sort data. So when you move to the “unread” pivot item, you have unread mail items; flicking your finger again, you’ll get to “flagged”, listing the messages that you have flagged.</p>
<p>You could easily have hundreds of items in a single pivot item.</p>
<p>If you want to enable scrolling, you must either use a scrolling control like <strong>ListBox</strong>, or add a <strong>ScrollViewer </strong>to the pivot or panorama item. Scrolling is not enabled by default. This helps ensure that items are always sized to the parent container like you’d expect in the Silverlight-powered layout system.</p>
<p>Here’s how to add a scroll viewer or list box to a pivot item. Note that you’ll only want to offer a vertical scrolling experience, since horizontal manipulations (pan or flick) are part of the navigation experience with these two controls.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:68cf1bcb-e9bc-4658-a5d7-766bcd429ac2" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;controls:Pivot Grid.Row="0"
                x:Name="Pivot1"
                Title="INBOX"&gt;
    &lt;controls:PivotItem
        Header="all"&gt;
        &lt;ListBox
            ItemTemplate="{StaticResource MyMailDataTemplate}"
            ItemsSource="{Binding Items}"&gt;
        &lt;/ListBox&gt;
    &lt;/controls:PivotItem&gt;

    &lt;controls:PivotItem
        Header="unread"&gt;
        &lt;ScrollViewer
            ScrollViewer.HorizontalScrollBarVisibility="Disabled"&gt;
            &lt;!-- Some large vertical list here --&gt;
        &lt;/ScrollViewer&gt;
    &lt;/controls:PivotItem&gt;
&lt;/controls:Pivot&gt;</pre>
</div>
<p>The example uses data binding to the data context, as well as custom-defined data templates from the application’s resources, so don’t just paste it into your app… but you get the idea I hope.</p>
<h3>Items control API</h3>
<p>These controls do both derive from ItemsControl, but they do have subtle differences.</p>
<h4>Both controls</h4>
<ul>
<li>Items can be added in XAML </li>
<li>Items can be added in code, Items.Add(new PivotItem(…)) or Items.Add(new PanoramaItem(…)) </li>
<li>ItemsSource can be used for data binding </li>
<li>Do not support alternative types of items: Pivot controls must use PivotItem, Panorama must have PanoramaItem </li>
</ul>
<h4>Differences</h4>
<ul>
<li>Panorama exposes a DefaultItem property </li>
<li>SelectedIndex and SelectedItem are settable in Pivot but not in Panorama </li>
</ul>
<h4>Migration</h4>
<p>There are a number of alternative implementations of these controls out there, so for release, we’ll be working to blog guidance on migrating from one of those other experiences to these controls if you would like to.</p>
<h4>Stay tuned!</h4>
<p>Hope this helps prepare to design and build apps. I’ll be posting again once we release so that you can get started with panorama and pivot control!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/08/looking-ahead-at-panorama-and-pivot/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>TiltContentControl for Windows Phone</title>
		<link>http://www.jeff.wilcox.name/2010/08/tiltcontentcontrol/</link>
		<comments>http://www.jeff.wilcox.name/2010/08/tiltcontentcontrol/#comments</comments>
		<pubDate>Sat, 07 Aug 2010 23:07:52 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/08/tiltcontentcontrol/</guid>
		<description><![CDATA[Here's a content control that has an implementation of the "tilt" interactive effect on the Windows Phone.]]></description>
			<content:encoded><![CDATA[<p>An enjoyable feature found in Windows Phone is a neat interactive effect that our designers have dubbed “tilt”. Tilt gives a little motion to standard controls during manipulations (when they’re being touched).</p>
<p>Although the operating system’s menus and core applications use this effect in many places, applications built for the platform by default don’t pick up any tilt effects. It’s a pretty complex problem to try and make assumptions about which controls and interface elements users would like to have a tilt added to.</p>
<p>We decided for now not to include the tilt effect for Silverlight apps on the phone, which is why you don’t see the tilt in the beta of the phone developer tools.</p>
<p>It’s a subtle effect, but you do see it when you use a device. It lets you know something’s responsive. So, if you click on the N in New Orleans in a list box like the one I have in a sample below:</p>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="TiltExample" border="0" alt="TiltExample" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/08/TiltExample.png" width="685" height="228" />    <br /><em>Tilt in effect: the New Orleans entry has been touched and has tilted in reaction to the manipulation. When the manipulation is done, it will move back to its standard position.</em></p>
<h3>Introducing Luke’s TiltContentControl</h3>
<p>So one of our excellent devs on the Silverlight mobile team, Luke Longley, went ahead and coded up this control we’re calling <a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/08/TiltContentControl.cs_.txt">TiltContentControl</a>. I’m sharing this control on his behalf today as we wanted to get this out for people to experiment with.</p>
<p>This lets you wrap any element that you’d like to have receive a tilt-like experience. You can also add it to data templates or re-template controls like Button to make it easy to apply throughout your app in a standard way.</p>
<h4>ContentControl vs Attached Property</h4>
<p>Since this control derives from ContentControl, it is designed to wrap a single control that should have the effect. It can also be placed inside of custom templates and styles to make it easy to apply, instead of having to manually wrap all controls you’d like to tilt enable with the control.</p>
<p>Another approach other than using a wrapping content control is to use an attached property. <a href="http://blogs.msdn.com/b/ptorr/archive/2010/03/23/tilt-effect-for-windows-phone-controls.aspx">Peter Torr</a> from the Windows Phone application platform team created <a href="http://blogs.msdn.com/b/ptorr/archive/2010/03/23/tilt-effect-for-windows-phone-controls.aspx">an implementation of tilt</a> that does just that.</p>
<p>Both these implementations are slightly different, so check them both out – they’re interesting lessons in the platform. This content control responds to manipulation deltas, so you’ll get a very similar effect to that of the rest of the phone controls while your finger is still on the screen.</p>
<h3>Adding the control to your project</h3>
<p>As a simple derived content control, you can add TiltContentControl to your project just by dropping this single C# file into your project.</p>
<p><strong><a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/08/TiltContentControl.cs_.txt">TiltContentControl.cs</a></strong> (code also duplicated below)</p>
<h3>How to use the control within your project</h3>
<p>So here’s how to use it in-place:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:99a63dc8-207f-4bac-92be-b0daa404e41b" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;unofficial:TiltContentControl
    VerticalAlignment="Center"
    HorizontalAlignment="Center"&gt;
    &lt;Button Content="Hello"
        Padding="40,0,40,0"/&gt;
&lt;/unofficial:TiltContentControl&gt;</pre>
</div>
<p>Here’s how to re-template something to use it – in this case I’m retemplating Button. You could put this style one time in your project, in App.xaml or a resource dictionary, then easily use it wherever without having to actually wrap the individual control instances.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:eaf31afa-efc7-4cc8-ac4c-75023e72bec9" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;!-- Re-templated button --&gt;
&lt;!--
This scenario re-templates button to contain the
tilt behavior and it can be used with any button
by applying the styled key TiltButton.
--&gt;
&lt;Style x:Key="TiltButton" TargetType="ButtonBase"&gt;
    &lt;Setter Property="Background" Value="Transparent"/&gt;
    &lt;Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/&gt;
    &lt;Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/&gt;
    &lt;Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/&gt;
    &lt;Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/&gt;
    &lt;Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/&gt;
    &lt;Setter Property="Padding" Value="10,3,10,5"/&gt;

    &lt;Setter Property="Template"&gt;
        &lt;Setter.Value&gt;
            &lt;ControlTemplate TargetType="ButtonBase"&gt;
                &lt;unofficial:TiltContentControl&gt;
                    &lt;VisualStateManager.VisualStateGroups&gt;
                        &lt;VisualStateGroup x:Name="CommonStates"&gt;
                            &lt;VisualState x:Name="Normal"/&gt;
                            &lt;VisualState x:Name="MouseOver"/&gt;
                            &lt;VisualState x:Name="Pressed"&gt;
                                &lt;Storyboard&gt;
                                    &lt;ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentContainer" Storyboard.TargetProperty="Foreground"&gt;
                                        &lt;DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneBackgroundBrush}" /&gt;
                                    &lt;/ObjectAnimationUsingKeyFrames&gt;
                                    &lt;ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Background"&gt;
                                        &lt;DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundBrush}" /&gt;
                                    &lt;/ObjectAnimationUsingKeyFrames&gt;
                                    &lt;ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="BorderBrush"&gt;
                                        &lt;DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundBrush}" /&gt;
                                    &lt;/ObjectAnimationUsingKeyFrames&gt;
                                &lt;/Storyboard&gt;
                            &lt;/VisualState&gt;
                            &lt;VisualState x:Name="Disabled"&gt;
                                &lt;Storyboard&gt;
                                    &lt;ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentContainer" Storyboard.TargetProperty="Foreground"&gt;
                                        &lt;DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}" /&gt;
                                    &lt;/ObjectAnimationUsingKeyFrames&gt;
                                    &lt;ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="BorderBrush"&gt;
                                        &lt;DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}" /&gt;
                                    &lt;/ObjectAnimationUsingKeyFrames&gt;
                                    &lt;ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Background"&gt;
                                        &lt;DiscreteObjectKeyFrame KeyTime="0" Value="Transparent" /&gt;
                                    &lt;/ObjectAnimationUsingKeyFrames&gt;
                                &lt;/Storyboard&gt;
                            &lt;/VisualState&gt;
                        &lt;/VisualStateGroup&gt;
                    &lt;/VisualStateManager.VisualStateGroups&gt;

                    &lt;Grid Background="Transparent"&gt;
                        &lt;Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="0" Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}" &gt;
                            &lt;ContentControl x:Name="ContentContainer" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Padding="{TemplateBinding Padding}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/&gt;
                        &lt;/Border&gt;
                    &lt;/Grid&gt;
                &lt;/unofficial:TiltContentControl&gt;
            &lt;/ControlTemplate&gt;
        &lt;/Setter.Value&gt;
    &lt;/Setter&gt;
&lt;/Style&gt;</pre>
</div>
<p>So to have a Button use it, just set the style to the static resource:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:4f3caaab-e1e9-44aa-bece-912f70f91ddd" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;Button Style="{StaticResource TiltButton}"
    Content="A styled button" /&gt;</pre>
</div>
<p>The XML namespace I’m using (this should go at the top of any pages or resource dictionaries you place the tilt content control in):</p>
<p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:87f59730-290b-4029-9c66-6950f5a9357c" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">xmlns:unofficial="clr-namespace:Microsoft.Phone.Controls.Unofficial"</pre>
</div>
<p>Now in the sample image above, I show a ListBox with items that all have the tilt effect enabled. Here’s how you can do the same by adding the control within a data template and setting that to the ItemTemplate of your list box. I also have ended up using ItemContainerStyle to make the entire width of the item tilt-enabled:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:cc131e41-14ae-4fc1-9faf-e1e36c0166ef" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;ListBox x:Name="ListBox1" Grid.Row="1"&gt;
    &lt;ListBox.ItemContainerStyle&gt;
        &lt;Style TargetType="ListBoxItem"&gt;
            &lt;Setter
                Property="HorizontalContentAlignment"
                Value="Stretch"/&gt;
        &lt;/Style&gt;
    &lt;/ListBox.ItemContainerStyle&gt;
    &lt;ListBox.ItemTemplate&gt;
        &lt;DataTemplate&gt;
            &lt;unofficial:TiltContentControl
                Background="Transparent"
                HorizontalAlignment="Stretch"
                HorizontalContentAlignment="Stretch"
                FontSize="{StaticResource PhoneFontSizeExtraLarge}"&gt;
                &lt;Grid HorizontalAlignment="Stretch"
                        IsHitTestVisible="True"
                        Background="Transparent"&gt;
                    &lt;ContentControl
                        HorizontalAlignment="Stretch"
                        HorizontalContentAlignment="Left"
                        Content="{Binding}"/&gt;
                &lt;/Grid&gt;
            &lt;/unofficial:TiltContentControl&gt;
        &lt;/DataTemplate&gt;
    &lt;/ListBox.ItemTemplate&gt;
&lt;/ListBox&gt;</pre>
</div>
<p>I’m sure there are other ways to do this, too. Which type of solution is really up to you.</p>
<h3>Creating and using a custom easing function</h3>
<p>The easing function defined for the tilt up operation is not a standard one found in Silverlight. As a result, the choice is either to implement a custom easing function in C#, or to find a similar one in the platform.</p>
<p>Here’s what the UX people say:</p>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="CustomEasingFunction" border="0" alt="CustomEasingFunction" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/08/CustomEasingFunction.png" width="685" height="109" /></p>
<p>Silverlight’s easing functions take in a normalized time value from 0 to 1. This means that if the double animation is really one second-long duration, then at half a second (500ms) the normalized time value will be 0.5, and at one second, 1.0. But never outside the range of [0, 1].</p>
<p>To implement a custom easing function, you just create a new class that derives from <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.animation.easingfunctionbase(VS.95).aspx">EasingFunctionBase</a> from the System.Windows.Media.Animation namespace. The tilt control has this as a nested private class, since we aren’t exposing it for use elsewhere.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:b40b1e6f-23a8-4539-ae2d-2cefd366b8ba" class="wlWriterEditableSmartContent">
<pre class="c-sharp" name="code">/// &lt;summary&gt;
/// An easing function of ln(t+1)/ln(2).
/// &lt;/summary&gt;
private class LogarithmicEase : EasingFunctionBase
{
    /// &lt;summary&gt;
    /// Constant value of ln(2) used in the easing function.
    /// &lt;/summary&gt;
    private const double NaturalLog2 = 0.693147181;

    /// &lt;summary&gt;
    /// Overrides the EaseInCore method to provide the logic portion of
    /// an ease in.
    /// &lt;/summary&gt;
    /// &lt;param name="normalizedTime"&gt;Normalized time (progress) of the
    /// animation, which is a value from 0 through 1.&lt;/param&gt;
    /// &lt;returns&gt;A double that represents the transformed progress.&lt;/returns&gt;
    protected override double EaseInCore(double normalizedTime)
    {
        return Math.Log(normalizedTime + 1) / NaturalLog2;
    }
}</pre>
</div>
<p>We’ve only overwritten the EaseIn method here. Pretty simple, you don’t need to be a mathematician!</p>
<p>In code, you can just use an instance of the LogarithmicEase type now for any animation’s EasingFunction value. You’ll see this implementation has a single static readonly instance of it that’s reused every time.</p>
<h3>Quick perf lesson #1: Avoid custom easing functions as they have a negative performance implication</h3>
<p>Custom easing functions are called per frame on the user interface thread. This is a much more expensive operation than a standard easing function which is implemented in native code by Silverlight, and able to run in the compositor thread (previously known as the render thread or independent animations thread).</p>
<p>The callback into C# is time that the user interface thread could have spent handling operating system events, handling input, letting property change notifications propagate, or the layout system to perform a full measure-arrange pass.</p>
<p>We’ve decided to use a custom easing function because the platform’s designers have explicitly designated this as the tilt-up animation’s ease.</p>
<h3>Quick perf lesson #2: Store a single static instance of property paths when creating animations in code</h3>
<p>If you look through the code, you’ll see that the storyboard and double animations are created in code. To minimize the additional number of new object allocations, the code has 3 static readonly properties for the paths.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:207f864a-1089-4b1c-9a37-d4ae97f99a9c" class="wlWriterEditableSmartContent">
<pre class="c-sharp" name="code">/// &lt;summary&gt;
/// Single instance of the Rotation X property.
/// &lt;/summary&gt;
private static readonly PropertyPath RotationXProperty = new PropertyPath(PlaneProjection.RotationXProperty);

/// &lt;summary&gt;
/// Single instance of the Rotation Y property.
/// &lt;/summary&gt;
private static readonly PropertyPath RotationYProperty = new PropertyPath(PlaneProjection.RotationYProperty);

/// &lt;summary&gt;
/// Single instance of the Global Offset Z property.
/// &lt;/summary&gt;
private static readonly PropertyPath GlobalOffsetZProperty = new PropertyPath(PlaneProjection.GlobalOffsetZProperty);</pre>
</div>
<p>This decreases the number of objects that have to be allocated, which decreases the cost of garbage collection. It’s probably a minimal improvement, but it’s something to think about.</p>
<h3>Does this tilt exactly match the OS?</h3>
<p>No, the effect doesn’t completely match.</p>
<p>The phone has an additional feature, a “global camera,” that I’m told takes into account the element’s position on screen. The global camera effect is why buttons near the bottom of the screen have an exaggerated tilt effect.</p>
<p>You won’t get that specific effect from this Silverlight implementation today. So this Silverlight implementation is more simple, but in my mind still achieves the goal of offering the tilt effect on elements.</p>
<p>We’ll see how people like it and maybe we’ll find a way to match the platform even closer in the future.</p>
<h3>Workaround note for beta tools developers</h3>
<p>There was a bug in the beta release of the platform where objects within a perspective transform that used bitmap caching would not necessarily react to the changing perspective. We’ve since fixed this internally.</p>
<p>To enable this file to be relevant to developers today (using beta tools) as well as in the future, I’ve coded in a workaround for beta tools users.</p>
<p><strong>If you are using Beta tools,</strong> you should uncomment the #define statement near the top of the file (line 13 I think).</p>
<p><strong>If you’re using post-beta tools,</strong> you can hopefully just use the file as-is.</p>
<h3>Full implementation of <a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/08/TiltContentControl.cs_.txt">TiltContentControl.cs</a></h3>
<p>Here’s the full implementation, you can just drop this into your phone project:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:e6bba0f0-3d40-437b-ae15-90864b39e5c5" class="wlWriterEditableSmartContent">
<pre class="c-sharp" name="code">// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

// ---
// Important Workaround Note for developers using the BETA:
// There is a workaround in code that removes any CacheMode from the content of
// the control. It works around a platform bug that is slated to be fixed for
// release.
//
// If you are using the beta tools, remove the comment below:
// #define WORKAROUND_BITMAP_CACHE_BUG
// ---

using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace Microsoft.Phone.Controls.Unofficial
{
    /// &lt;summary&gt;
    /// A content control designed to wrap anything in Silverlight with a user
    /// experience concept called 'tilt', applying a transformation during
    /// manipulation by a user.
    /// &lt;/summary&gt;
    public class TiltContentControl : ContentControl
    {
        #region Constants
        /// &lt;summary&gt;
        /// Maximum angle for the tilt effect, defined in Radians.
        /// &lt;/summary&gt;
        private const double MaxAngle = 0.3;

        /// &lt;summary&gt;
        /// The maximum depression for the tilt effect, given in pixel units.
        /// &lt;/summary&gt;
        private const double MaxDepression = 25;

        /// &lt;summary&gt;
        /// The number of seconds for a tilt revert to take.
        /// &lt;/summary&gt;
        private static readonly Duration TiltUpAnimationDuration = new Duration(TimeSpan.FromSeconds(.5));

        /// &lt;summary&gt;
        /// A single logarithmic ease instance.
        /// &lt;/summary&gt;
        private static readonly IEasingFunction LogEase = new LogarithmicEase();

        #endregion

        #region Static property instances
        /// &lt;summary&gt;
        /// Single instance of the Rotation X property.
        /// &lt;/summary&gt;
        private static readonly PropertyPath RotationXProperty = new PropertyPath(PlaneProjection.RotationXProperty);

        /// &lt;summary&gt;
        /// Single instance of the Rotation Y property.
        /// &lt;/summary&gt;
        private static readonly PropertyPath RotationYProperty = new PropertyPath(PlaneProjection.RotationYProperty);

        /// &lt;summary&gt;
        /// Single instance of the Global Offset Z property.
        /// &lt;/summary&gt;
        private static readonly PropertyPath GlobalOffsetZProperty = new PropertyPath(PlaneProjection.GlobalOffsetZProperty);
        #endregion

        /// &lt;summary&gt;
        /// The content element instance.
        /// &lt;/summary&gt;
        private ContentPresenter _presenter;

        /// &lt;summary&gt;
        /// The original width of the control.
        /// &lt;/summary&gt;
        private double _width;

        /// &lt;summary&gt;
        /// The original height of the control.
        /// &lt;/summary&gt;
        private double _height;

        /// &lt;summary&gt;
        /// The storyboard used for the tilt up effect.
        /// &lt;/summary&gt;
        private Storyboard _tiltUpStoryboard;

        /// &lt;summary&gt;
        /// The plane projection used to show the tilt effect.
        /// &lt;/summary&gt;
        private PlaneProjection _planeProjection;

        /// &lt;summary&gt;
        /// Overrides the method called when apply template is called. We assume
        /// that the implementation root is the content presenter.
        /// &lt;/summary&gt;
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            _presenter = GetImplementationRoot(this) as ContentPresenter;
        }

        /// &lt;summary&gt;
        /// Overrides the maniupulation started event.
        /// &lt;/summary&gt;
        /// &lt;param name="e"&gt;The manipulation event arguments.&lt;/param&gt;
        protected override void OnManipulationStarted(ManipulationStartedEventArgs e)
        {
            base.OnManipulationStarted(e);

            if (_presenter != null)
            {
#if WORKAROUND_BITMAP_CACHE_BUG
                // WORKAROUND NOTE:
                // This is a workaround for a platform bug related to cache mode
                // that should be fixed before final release of the platform.
                UIElement elementContent = _contentElement.Content as UIElement;
                if (elementContent != null &#038;&#038; elementContent.CacheMode != null)
                {
                    elementContent.CacheMode = null;
                }
#endif
                _planeProjection = new PlaneProjection();
                _presenter.Projection = _planeProjection;

                _tiltUpStoryboard = new Storyboard();
                _tiltUpStoryboard.Completed += TiltUpCompleted;

                DoubleAnimation tiltUpRotateXAnimation = new DoubleAnimation();
                Storyboard.SetTarget(tiltUpRotateXAnimation, _planeProjection);
                Storyboard.SetTargetProperty(tiltUpRotateXAnimation, RotationXProperty);
                tiltUpRotateXAnimation.To = 0;
                tiltUpRotateXAnimation.EasingFunction = LogEase;
                tiltUpRotateXAnimation.Duration = TiltUpAnimationDuration;

                DoubleAnimation tiltUpRotateYAnimation = new DoubleAnimation();
                Storyboard.SetTarget(tiltUpRotateYAnimation, _planeProjection);
                Storyboard.SetTargetProperty(tiltUpRotateYAnimation, RotationYProperty);
                tiltUpRotateYAnimation.To = 0;
                tiltUpRotateYAnimation.EasingFunction = LogEase;
                tiltUpRotateYAnimation.Duration = TiltUpAnimationDuration;

                DoubleAnimation tiltUpOffsetZAnimation = new DoubleAnimation();
                Storyboard.SetTarget(tiltUpOffsetZAnimation, _planeProjection);
                Storyboard.SetTargetProperty(tiltUpOffsetZAnimation, GlobalOffsetZProperty);
                tiltUpOffsetZAnimation.To = 0;
                tiltUpOffsetZAnimation.EasingFunction = LogEase;
                tiltUpOffsetZAnimation.Duration = TiltUpAnimationDuration;

                _tiltUpStoryboard.Children.Add(tiltUpRotateXAnimation);
                _tiltUpStoryboard.Children.Add(tiltUpRotateYAnimation);
                _tiltUpStoryboard.Children.Add(tiltUpOffsetZAnimation);
            }
            if (_planeProjection != null)
            {
                _width = ActualWidth;
                _height = ActualHeight;
                if (_tiltUpStoryboard != null)
                {
                    _tiltUpStoryboard.Stop();
                }
                DepressAndTilt(e.ManipulationOrigin, e.ManipulationContainer);
            }
        }

        /// &lt;summary&gt;
        /// Handles the manipulation delta event.
        /// &lt;/summary&gt;
        /// &lt;param name="e"&gt;The manipulation event arguments.&lt;/param&gt;
        protected override void OnManipulationDelta(ManipulationDeltaEventArgs e)
        {
            base.OnManipulationDelta(e);
            // Depress and tilt regardless of whether the event was handled.
            if (_planeProjection != null)
            {
                DepressAndTilt(e.ManipulationOrigin, e.ManipulationContainer);
            }
        }

        /// &lt;summary&gt;
        /// Handles the manipulation completed event.
        /// &lt;/summary&gt;
        /// &lt;param name="e"&gt;The manipulation event arguments.&lt;/param&gt;
        protected override void OnManipulationCompleted(ManipulationCompletedEventArgs e)
        {
            base.OnManipulationCompleted(e);
            if (_planeProjection != null)
            {
                if (_tiltUpStoryboard != null)
                {
                    _tiltUpStoryboard.Begin();
                }
                else
                {
                    _planeProjection.RotationY = 0;
                    _planeProjection.RotationX = 0;
                    _planeProjection.GlobalOffsetZ = 0;
                }
            }
        }

        /// &lt;summary&gt;
        /// Updates the depression and tilt based on position of the
        /// manipulation relative to the original origin from input.
        /// &lt;/summary&gt;
        /// &lt;param name="manipulationOrigin"&gt;The origin of manipulation.&lt;/param&gt;
        /// &lt;param name="manipulationContainer"&gt;The container instance.&lt;/param&gt;
        private void DepressAndTilt(Point manipulationOrigin, UIElement manipulationContainer)
        {
            GeneralTransform transform = manipulationContainer.TransformToVisual(this);
            Point transformedOrigin = transform.Transform(manipulationOrigin);
            Point normalizedPoint = new Point(
                Math.Min(Math.Max(transformedOrigin.X / _width, 0), 1),
                Math.Min(Math.Max(transformedOrigin.Y / _height, 0), 1));
            double xMagnitude = Math.Abs(normalizedPoint.X - 0.5);
            double yMagnitude = Math.Abs(normalizedPoint.Y - 0.5);
            double xDirection = -Math.Sign(normalizedPoint.X - 0.5);
            double yDirection = Math.Sign(normalizedPoint.Y - 0.5);
            double angleMagnitude = xMagnitude + yMagnitude;
            double xAngleContribution = xMagnitude + yMagnitude &gt; 0 ? xMagnitude / (xMagnitude + yMagnitude) : 0;
            double angle = angleMagnitude * MaxAngle * 180 / Math.PI;
            double depression = (1 - angleMagnitude) * MaxDepression;
            // RotationX and RotationY are the angles of rotations about the x-
            // or y-axis. To achieve a rotation in the x- or y-direction, the
            // two must be swapped. So a rotation to the left about the y-axis
            // is a rotation to the left in the x-direction, and a rotation up
            // about the x-axis is a rotation up in the y-direction.
            _planeProjection.RotationY = angle * xAngleContribution * xDirection;
            _planeProjection.RotationX = angle * (1 - xAngleContribution) * yDirection;
            _planeProjection.GlobalOffsetZ = -depression;
        }

        /// &lt;summary&gt;
        /// Handles the tilt up completed event.
        /// &lt;/summary&gt;
        /// &lt;param name="sender"&gt;The source object.&lt;/param&gt;
        /// &lt;param name="e"&gt;The event arguments.&lt;/param&gt;
        private void TiltUpCompleted(object sender, EventArgs e)
        {
            if (_tiltUpStoryboard != null)
            {
                _tiltUpStoryboard.Stop();
            }
            _tiltUpStoryboard = null;
            _planeProjection = null;
            _presenter.Projection = null;
        }

        /// &lt;summary&gt;
        /// An easing function of ln(t+1)/ln(2).
        /// &lt;/summary&gt;
        private class LogarithmicEase : EasingFunctionBase
        {
            /// &lt;summary&gt;
            /// Constant value of ln(2) used in the easing function.
            /// &lt;/summary&gt;
            private const double NaturalLog2 = 0.693147181;

            /// &lt;summary&gt;
            /// Overrides the EaseInCore method to provide the logic portion of
            /// an ease in.
            /// &lt;/summary&gt;
            /// &lt;param name="normalizedTime"&gt;Normalized time (progress) of the
            /// animation, which is a value from 0 through 1.&lt;/param&gt;
            /// &lt;returns&gt;A double that represents the transformed progress.&lt;/returns&gt;
            protected override double EaseInCore(double normalizedTime)
            {
                return Math.Log(normalizedTime + 1) / NaturalLog2;
            }
        }

        /// &lt;summary&gt;
        /// Gets the implementation root of the Control.
        /// &lt;/summary&gt;
        /// &lt;param name="dependencyObject"&gt;The DependencyObject.&lt;/param&gt;
        /// &lt;remarks&gt;
        /// Implements Silverlight's corresponding internal property on Control.
        /// &lt;/remarks&gt;
        /// &lt;returns&gt;Returns the implementation root or null.&lt;/returns&gt;
        public static FrameworkElement GetImplementationRoot(DependencyObject dependencyObject)
        {
            Debug.Assert(dependencyObject != null, "DependencyObject should not be null.");
            return (1 == VisualTreeHelper.GetChildrenCount(dependencyObject)) ?
                VisualTreeHelper.GetChild(dependencyObject, 0) as FrameworkElement :
                null;
        }
    }
}
</pre>
</div>
<h3>Namespace: Microsoft.Phone.Controls.Unofficial</h3>
<p>One change since the ProgressBar template I blogged about: I’m using the namespace Microsoft.Phone.Controls.Unofficial now. Unsupported sounded harsh; obviously these types of controls will be improved upon over time and they’re out in the public, so either on StackOverflow.com or Twitter or whatever there will be some place for people to talk about what’s good and bad with these controls.</p>
<p>Hope this helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/08/tiltcontentcontrol/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Creating high performance Windows Phone apps &#8211; THE WHITEPAPER</title>
		<link>http://www.jeff.wilcox.name/2010/08/windows-phone-performance/</link>
		<comments>http://www.jeff.wilcox.name/2010/08/windows-phone-performance/#comments</comments>
		<pubDate>Sat, 07 Aug 2010 18:53:24 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/08/windows-phone-performance/</guid>
		<description><![CDATA[Our performance whitepaper on Silverlight for Windows Phone applications is out. Please take a look.]]></description>
			<content:encoded><![CDATA[<p>Our perf whitepaper has made it out in the wild, please take a look at “<a href="http://www.microsoft.com/downloads/en/confirmation.aspx?familyId=3a8636bf-185f-449a-a0ce-83502b9ec0ec&amp;displayLang=en">Creating high performance Silverlight applications for Windows Phone</a>” – the download includes not only the whitepaper, but also sample applications.</p>
<p><a href="http://www.microsoft.com/downloads/en/confirmation.aspx?familyId=3a8636bf-185f-449a-a0ce-83502b9ec0ec&amp;displayLang=en"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="CreatingHighPerformanceSilverlightForWindowsPhoneApps" border="0" alt="CreatingHighPerformanceSilverlightForWindowsPhoneApps" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/08/CreatingHighPerformanceSilverlightForWindowsPhoneApps.png" width="685" height="65" /></a></p>
<p>Some of the features it covers:</p>
<ul>
<li>Compositor thread and user interface thread</li>
<li>Frame rate counter &amp; cache visualizations</li>
<li>Cache mode</li>
<li>Fill rate concepts</li>
<li>Loading images larger than 2000 x 2000</li>
<li>Navigating into pages in other assemblies</li>
</ul>
<p>Some tips it includes:</p>
<ul>
<li>Using Opacity = 0 to hide objects and reduce the fill count</li>
<li>Using images over XAML for some graphics that don’t need to be vectors</li>
<li>Minimizing the code in constructors and initialization code paths</li>
<li>Using Dispatcher.BeginInvoke at startup to get initialization work happening quickly, but after rendering the screen</li>
<li>Using async</li>
</ul>
<p>It includes sample apps that demonstrate concepts:</p>
<ul>
<li>Examples about fill rate</li>
<li>How to hide objects using Opacity = 0</li>
<li>Loading large images</li>
<li>Per-frame callback implications</li>
<li>How to split code across DLLs to improve app startup time</li>
</ul>
<p>This was created by performance experts on the phone and Silverlight teams, and even I’ve even contributed to the whitepaper – the frame rate counters image from my blog is in there.</p>
<p>I’ll also be covering many of these topics in depth on this blog going forward.</p>
<p>Hope this helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/08/windows-phone-performance/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A high performance ProgressBar for Windows Phone</title>
		<link>http://www.jeff.wilcox.name/2010/08/performanceprogressbar/</link>
		<comments>http://www.jeff.wilcox.name/2010/08/performanceprogressbar/#comments</comments>
		<pubDate>Mon, 02 Aug 2010 12:01:10 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/08/performanceprogressbar/</guid>
		<description><![CDATA[The ProgressBar template for Windows Phone can be improved upon for better performance in indeterminate mode.]]></description>
			<content:encoded><![CDATA[<p>The ProgressBar template for Silverlight that is built into the Windows Phone today looks beautiful but comes at a cost to performance in indeterminate mode (the animating dots that often indicate loading during an operation of unknown time).</p>
<p>Here I offer a workaround which is identical in looks, but with excellent performance. It uses the <strong>render thread</strong> exclusively for animation, instead of the <strong>UI (user interface) thread</strong>. I’ve touched on this previously in a post of <a href="http://www.jeff.wilcox.name/2010/07/counters/">performance and frame rate counters for the Windows Phone</a>.</p>
<h3>8/17/10 Update</h3>
<p>A quick update since I originally posted this on August 2nd: you should also take care to toggle the IsIndeterminate property through binding or code when not needed, on top of collapsing the visual of the control. This was identified through app code reviews and is another important part of speeding up your apps. <a href="http://www.jeff.wilcox.name/2010/08/progressbarperftips2/">More info in my 8/17 post</a>.</p>
<h3>The original post follows:</h3>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="IndeterminateWindowsPhoneProgressBar" border="0" alt="IndeterminateWindowsPhoneProgressBar" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/08/IndeterminateWindowsPhoneProgressBar.png" width="484" height="90" /></p>
<p>Moving the indeterminate animation to the render thread frees up the UI thread to handle application events, messages, interact with the networking stack, and otherwise keep the app running smoothly.</p>
<h2>Using the PerformanceProgressBar in your app</h2>
<p>This workaround requires you to add a simple <a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/08/RelativeAnimatingContentControl.cs_.txt">control</a> (a .cs file) to your Windows Phone project, as well as set the <a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/08/PerformanceProgressBarStyle.txt">ProgressBar style to the alternative</a>, and should take about 5 minutes. This is what you want if you want to give your users that “progress indicator” visual style while data or information is loading, and using this version will let the app continue to look responsive to your customers.</p>
<h3>Get the code</h3>
<p>Download and add the source file <a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/08/RelativeAnimatingContentControl.cs_.txt">RelativeAnimatingContentControl.cs</a> to your project (it is <a href="http://opensource.org/licenses/ms-pl.html">open source</a>)</p>
<h3>Add the PerformanceProgressBar style</h3>
<p>Open the App.xaml file in your Windows Phone project (or generic.xaml if a composite control library). Next, add the following XMLNS declaration at the top element – this is important as it tells the parser to look in your project for the code you added above:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:b02e0967-ee8d-4d6a-b0ee-db22877e8b6a" class="wlWriterEditableSmartContent">
<pre class="brush: xml">xmlns:unsupported="clr-namespace:Microsoft.Phone.Controls.Unsupported"</pre>
</div>
<p>Now, go into the Resources section of the file and add this style (you can also download as <a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/08/PerformanceProgressBarStyle.txt">PerformanceProgressBarStyle.txt</a>):</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:78e389f1-aceb-4c16-9f10-1adbd13adf9d" class="wlWriterEditableSmartContent">
<pre class="brush: xml">&lt;Style x:Key="PerformanceProgressBar" TargetType="ProgressBar"&gt;
    &lt;Setter Property="Foreground" Value="{StaticResource PhoneAccentBrush}"/&gt;
    &lt;Setter Property="Background" Value="{StaticResource PhoneAccentBrush}"/&gt;
    &lt;Setter Property="Maximum" Value="100"/&gt;
    &lt;Setter Property="IsHitTestVisible" Value="False"/&gt;
    &lt;Setter Property="Padding" Value="{StaticResource PhoneHorizontalMargin}"/&gt;
    &lt;Setter Property="Template"&gt;
        &lt;Setter.Value&gt;
            &lt;ControlTemplate TargetType="ProgressBar"&gt;
                &lt;unsupported:RelativeAnimatingContentControl HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"&gt;
                    &lt;unsupported:RelativeAnimatingContentControl.Resources&gt;
                        &lt;ExponentialEase EasingMode="EaseOut" Exponent="1" x:Key="ProgressBarEaseOut"/&gt;
                        &lt;ExponentialEase EasingMode="EaseOut" Exponent="1" x:Key="ProgressBarEaseIn"/&gt;
                    &lt;/unsupported:RelativeAnimatingContentControl.Resources&gt;
                    &lt;VisualStateManager.VisualStateGroups&gt;
                        &lt;VisualStateGroup x:Name="CommonStates"&gt;
                            &lt;VisualState x:Name="Determinate"/&gt;
                            &lt;VisualState x:Name="Indeterminate"&gt;
                                &lt;Storyboard RepeatBehavior="Forever" Duration="00:00:04.4"&gt;
                                    &lt;ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="IndeterminateRoot"&gt;
                                        &lt;DiscreteObjectKeyFrame KeyTime="0"&gt;
                                            &lt;DiscreteObjectKeyFrame.Value&gt;
                                                &lt;Visibility&gt;Visible&lt;/Visibility&gt;
                                            &lt;/DiscreteObjectKeyFrame.Value&gt;
                                        &lt;/DiscreteObjectKeyFrame&gt;
                                    &lt;/ObjectAnimationUsingKeyFrames&gt;
                                    &lt;ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DeterminateRoot"&gt;
                                        &lt;DiscreteObjectKeyFrame KeyTime="0"&gt;
                                            &lt;DiscreteObjectKeyFrame.Value&gt;
                                                &lt;Visibility&gt;Collapsed&lt;/Visibility&gt;
                                            &lt;/DiscreteObjectKeyFrame.Value&gt;
                                        &lt;/DiscreteObjectKeyFrame&gt;
                                    &lt;/ObjectAnimationUsingKeyFrames&gt;
                                    &lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00.0" Storyboard.TargetProperty="X" Storyboard.TargetName="R1TT"&gt;
                                        &lt;LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="0.1"/&gt;
                                        &lt;EasingDoubleKeyFrame KeyTime="00:00:00.5" Value="33.1" EasingFunction="{StaticResource ProgressBarEaseOut}"/&gt;
                                        &lt;LinearDoubleKeyFrame KeyTime="00:00:02.0" Value="66.1"/&gt;
                                        &lt;EasingDoubleKeyFrame KeyTime="00:00:02.5" Value="100.1" EasingFunction="{StaticResource ProgressBarEaseIn}"/&gt;
                                    &lt;/DoubleAnimationUsingKeyFrames&gt;
                                    &lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00.2" Storyboard.TargetProperty="X" Storyboard.TargetName="R2TT"&gt;
                                        &lt;LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="0.1"/&gt;
                                        &lt;EasingDoubleKeyFrame KeyTime="00:00:00.5" Value="33.1" EasingFunction="{StaticResource ProgressBarEaseOut}"/&gt;
                                        &lt;LinearDoubleKeyFrame KeyTime="00:00:02.0" Value="66.1"/&gt;
                                        &lt;EasingDoubleKeyFrame KeyTime="00:00:02.5" Value="100.1" EasingFunction="{StaticResource ProgressBarEaseIn}"/&gt;
                                    &lt;/DoubleAnimationUsingKeyFrames&gt;
                                    &lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00.4" Storyboard.TargetProperty="X" Storyboard.TargetName="R3TT"&gt;
                                        &lt;LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="0.1"/&gt;
                                        &lt;EasingDoubleKeyFrame KeyTime="00:00:00.5" Value="33.1" EasingFunction="{StaticResource ProgressBarEaseOut}"/&gt;
                                        &lt;LinearDoubleKeyFrame KeyTime="00:00:02.0" Value="66.1"/&gt;
                                        &lt;EasingDoubleKeyFrame KeyTime="00:00:02.5" Value="100.1" EasingFunction="{StaticResource ProgressBarEaseIn}"/&gt;
                                    &lt;/DoubleAnimationUsingKeyFrames&gt;
                                    &lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00.6" Storyboard.TargetProperty="X" Storyboard.TargetName="R4TT"&gt;
                                        &lt;LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="0.1"/&gt;
                                        &lt;EasingDoubleKeyFrame KeyTime="00:00:00.5" Value="33.1" EasingFunction="{StaticResource ProgressBarEaseOut}"/&gt;
                                        &lt;LinearDoubleKeyFrame KeyTime="00:00:02.0" Value="66.1"/&gt;
                                        &lt;EasingDoubleKeyFrame KeyTime="00:00:02.5" Value="100.1" EasingFunction="{StaticResource ProgressBarEaseIn}"/&gt;
                                    &lt;/DoubleAnimationUsingKeyFrames&gt;
                                    &lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00.8" Storyboard.TargetProperty="X" Storyboard.TargetName="R5TT"&gt;
                                        &lt;LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="0.1"/&gt;
                                        &lt;EasingDoubleKeyFrame KeyTime="00:00:00.5" Value="33.1" EasingFunction="{StaticResource ProgressBarEaseOut}"/&gt;
                                        &lt;LinearDoubleKeyFrame KeyTime="00:00:02.0" Value="66.1"/&gt;
                                        &lt;EasingDoubleKeyFrame KeyTime="00:00:02.5" Value="100.1" EasingFunction="{StaticResource ProgressBarEaseIn}"/&gt;
                                    &lt;/DoubleAnimationUsingKeyFrames&gt;
                                    &lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="R1"&gt;
                                        &lt;DiscreteDoubleKeyFrame KeyTime="0" Value="1"/&gt;
                                        &lt;DiscreteDoubleKeyFrame KeyTime="00:00:02.5" Value="0"/&gt;
                                    &lt;/DoubleAnimationUsingKeyFrames&gt;
                                    &lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00.2" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="R2"&gt;
                                        &lt;DiscreteDoubleKeyFrame KeyTime="0" Value="1"/&gt;
                                        &lt;DiscreteDoubleKeyFrame KeyTime="00:00:02.5" Value="0"/&gt;
                                    &lt;/DoubleAnimationUsingKeyFrames&gt;
                                    &lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00.4" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="R3"&gt;
                                        &lt;DiscreteDoubleKeyFrame KeyTime="0" Value="1"/&gt;
                                        &lt;DiscreteDoubleKeyFrame KeyTime="00:00:02.5" Value="0"/&gt;
                                    &lt;/DoubleAnimationUsingKeyFrames&gt;
                                    &lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00.6" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="R4"&gt;
                                        &lt;DiscreteDoubleKeyFrame KeyTime="0" Value="1"/&gt;
                                        &lt;DiscreteDoubleKeyFrame KeyTime="00:00:02.5" Value="0"/&gt;
                                    &lt;/DoubleAnimationUsingKeyFrames&gt;
                                    &lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00.8" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="R5"&gt;
                                        &lt;DiscreteDoubleKeyFrame KeyTime="0" Value="1"/&gt;
                                        &lt;DiscreteDoubleKeyFrame KeyTime="00:00:02.5" Value="0"/&gt;
                                    &lt;/DoubleAnimationUsingKeyFrames&gt;
                                &lt;/Storyboard&gt;
                            &lt;/VisualState&gt;
                        &lt;/VisualStateGroup&gt;
                    &lt;/VisualStateManager.VisualStateGroups&gt;
                    &lt;Grid&gt;
                        &lt;Grid x:Name="DeterminateRoot" Margin="{TemplateBinding Padding}" Visibility="Visible"&gt;
                            &lt;Rectangle x:Name="ProgressBarTrack" Fill="{TemplateBinding Background}" Height="4" Opacity="0.1"/&gt;
                            &lt;Rectangle x:Name="ProgressBarIndicator" Fill="{TemplateBinding Foreground}" HorizontalAlignment="Left" Height="4"/&gt;
                        &lt;/Grid&gt;
                        &lt;Border x:Name="IndeterminateRoot" Margin="{TemplateBinding Padding}" Visibility="Collapsed"&gt;
                            &lt;Grid HorizontalAlignment="Left"&gt;
                                &lt;Rectangle Fill="{TemplateBinding Foreground}" Height="4" IsHitTestVisible="False" Width="4" x:Name="R1" Opacity="0" CacheMode="BitmapCache"&gt;
                                    &lt;Rectangle.RenderTransform&gt;
                                        &lt;TranslateTransform x:Name="R1TT"/&gt;
                                    &lt;/Rectangle.RenderTransform&gt;
                                &lt;/Rectangle&gt;
                                &lt;Rectangle Fill="{TemplateBinding Foreground}" Height="4" IsHitTestVisible="False" Width="4" x:Name="R2" Opacity="0" CacheMode="BitmapCache"&gt;
                                    &lt;Rectangle.RenderTransform&gt;
                                        &lt;TranslateTransform x:Name="R2TT"/&gt;
                                    &lt;/Rectangle.RenderTransform&gt;
                                &lt;/Rectangle&gt;
                                &lt;Rectangle Fill="{TemplateBinding Foreground}" Height="4" IsHitTestVisible="False" Width="4" x:Name="R3" Opacity="0" CacheMode="BitmapCache"&gt;
                                    &lt;Rectangle.RenderTransform&gt;
                                        &lt;TranslateTransform x:Name="R3TT"/&gt;
                                    &lt;/Rectangle.RenderTransform&gt;
                                &lt;/Rectangle&gt;
                                &lt;Rectangle Fill="{TemplateBinding Foreground}" Height="4" IsHitTestVisible="False" Width="4" x:Name="R4" Opacity="0" CacheMode="BitmapCache"&gt;
                                    &lt;Rectangle.RenderTransform&gt;
                                        &lt;TranslateTransform x:Name="R4TT"/&gt;
                                    &lt;/Rectangle.RenderTransform&gt;
                                &lt;/Rectangle&gt;
                                &lt;Rectangle Fill="{TemplateBinding Foreground}" Height="4" IsHitTestVisible="False" Width="4" x:Name="R5" Opacity="0" CacheMode="BitmapCache"&gt;
                                    &lt;Rectangle.RenderTransform&gt;
                                        &lt;TranslateTransform x:Name="R5TT"/&gt;
                                    &lt;/Rectangle.RenderTransform&gt;
                                &lt;/Rectangle&gt;
                            &lt;/Grid&gt;
                        &lt;/Border&gt;
                    &lt;/Grid&gt;
                &lt;/unsupported:RelativeAnimatingContentControl&gt;
            &lt;/ControlTemplate&gt;
        &lt;/Setter.Value&gt;
    &lt;/Setter&gt;
&lt;/Style&gt;</pre>
</div>
<h3>Add this alternate ProgressBar control style everywhere</h3>
<p>Now, whenever you or your designers place a ProgressBar in your app, set the style to be PerformanceProgressBar and it will be picked up from the App.xaml.</p>
<p>In XAML:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:05b6aa71-5ca0-430e-a7fe-9dafce2ff2dd" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;ProgressBar IsIndeterminate="True" Style="{StaticResource PerformanceProgressBar}"/&gt;</pre>
</div>
<p>In code:</p>
<p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:d749381b-3bdf-4a2f-9e00-2e29a80a1516" class="wlWriterEditableSmartContent">
<pre class="csharp" name="code">Style style = (Style)App.Current.Resources["PerformanceProgressBar"];
if (style == null) { throw new InvalidOperationException("The style was not found."); }
ProgressBar bar = new ProgressBar
{
    IsIndeterminate = true,
    Style = style,
};
LayoutRoot.Children.Add(bar);
</pre>
</div>
<p>That’s it! Read on if you want to learn about how this all actually works, why it isn’t built into the system (there’s a good reason), and just general info about the performance-improving workflow I went through.</p>
<h2>The back story</h2>
<p>When people started seeing poor performance on applications that were using indeterminate progress bars, it was a stumper. I’m pretty sure there were hallway conversations including: “what the heck? how’s this so bad? there’s nothing happening here – it’s just animating rectangles! WTF? is there a bug in the animation system? what’s really the issue? this is a super simple animation! fix it!”</p>
<p>I jumped in and started looking at the root of the potential performance problem. It was definitely interesting because the emulator experience was pretty good (though still heavy in the UI thread), but once these same apps were on real developer devices, the issue manifested. The emulator is just that – <a href="http://www.bing.com/search?q=define+emulate&amp;go=&amp;form=QBLH&amp;qs=n&amp;sk=&amp;sc=5-10">it emulates</a>, so there will be differences.</p>
<p>Working to unpeel the onion and diagnose the indeterminate ProgressBar as the root of the performance issue, some of what was tried:</p>
<ul>
<li>Noting applications were sluggish on hardware devices when a progress bar would appear in indeterminate mode </li>
<li>Removing networking calls, commenting out any data parsing, and cutting out application logic – leaving just simple states and the progress bar </li>
<li>Building a repro application with an indeterminate ProgressBar, the UI thread was still stressed according to the <a href="http://www.jeff.wilcox.name/2010/07/counters/">frame rate counters</a> </li>
<li>Adding several progress bars compounded the problem </li>
<li>Trying to understand why the render thread frame rate was doing fine (above 50 fps), but the UI was below 10 fps at times </li>
<li>Reviewing the default control style and template’s visual state animations and code to look for complex animations or opportunities for improvement (BitmapCache was not being used for instance, but it wasn’t a big enough difference to explain the cause) </li>
<li>Identifying that the method used to move the small rectangles on the screen by animating the Value property of Slider would cause per-thread callbacks to the property change handler of the Slider control, forcing the animations to the UI thread <em>instead</em> of the independent animations render thread </li>
</ul>
<p>So there, the issue was in the animations and underlying template for the indeterminate ProgressBar and its use of Slider controls.</p>
<h3>Why Slider is in the template</h3>
<p>The default style and control template for the Windows Phone was created to meet the UX &amp; user interface guidelines that the Windows Phone team has created. A consistent and good-looking set of controls is an important part of the platform and so the progress bar has a very slick appearance.</p>
<p>In “indeterminate” mode, five small rectangles in the user’s accent color, that move into the screen one just briefly after another. It’s mesmerizing and more fun than the standard Silverlight one you may have seen on the web before.</p>
<p>Trouble is, the animation defined for the rectangles is impossible to declare in XAML markup – there’s no way to provide an animation frame description which says “at this keyframe, the rectangle should be positioned 1/3 of the width of the control”: Silverlight happily will let you define a specific fixed position (like translating 75 pixels), but not a variable or ratio-based size for the animation.</p>
<p>But wait! There’s another control in the core platform that can do this visual concept.</p>
<p>Enter <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.slider_members(v=VS.95).aspx">Slider</a>. Slider is a nice control because it calculates a position based on the width and effectively a percent (the Value divided by the Maximum provides the ratio), then uses that to update the Thumb/Track template part of the control.</p>
<p>Here’s some short XAML that helps demonstrate how this ratio works for offsetting the thumb:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:f98d1ba3-3f7f-43c2-9312-edbd83c72d95" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;Grid Width="100" Background="#33000000" Margin="5"&gt;
    &lt;Slider Value="30" Maximum="100"/&gt;
&lt;/Grid&gt;
&lt;Grid Grid.Column="1" Width="200" Background="#33000000" Margin="5"&gt;
    &lt;Slider Value="30" Maximum="100"/&gt;
&lt;/Grid&gt;</pre>
</div>
<p>And you’ll see that even though the Value is 30 in each case, the Sliders are different sizes based on their parents’ size: effectively allowing for moving the thumb based on a ratio applied to the actual width:</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="IdenticalSliders" border="0" alt="IdenticalSliders" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/08/IdenticalSliders.png" width="325" height="130" /></p>
<p>This let the designers create the ratio-based animation for the rectangles (thumbs of a slider) that makes them smoothly move in thirds. The rectangles enter to one third the width of the screen while fading in, then move at a different rate from 1/3 to 2/3 the width of the screen, and then fly and fade out.</p>
<p>So indeterminate mode progress bar was destined to use a set of Sliders to move those rectangles. The progress bar defines 5 Slider controls.</p>
<p>Here’s a snippet from the default style template in the beta release of the Windows Phone developer tools:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:a66539a3-cea5-48a7-b1d7-bef33c8f882a" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">  &lt;Border x:Name="IndeterminateRoot" Visibility="Collapsed" Margin="{TemplateBinding Padding}"&gt;
    &lt;Grid&gt;
      &lt;Slider x:Name="Slider1" Style="{StaticResource PhoneProgressBarSliderStyle}" Foreground="{TemplateBinding Foreground}"/&gt;
      &lt;Slider x:Name="Slider2" Style="{StaticResource PhoneProgressBarSliderStyle}" Foreground="{TemplateBinding Foreground}"/&gt;
      &lt;Slider x:Name="Slider3" Style="{StaticResource PhoneProgressBarSliderStyle}" Foreground="{TemplateBinding Foreground}"/&gt;
      &lt;Slider x:Name="Slider4" Style="{StaticResource PhoneProgressBarSliderStyle}" Foreground="{TemplateBinding Foreground}"/&gt;
      &lt;Slider x:Name="Slider5" Style="{StaticResource PhoneProgressBarSliderStyle}" Foreground="{TemplateBinding Foreground}"/&gt;
    &lt;/Grid&gt;
  &lt;/Border&gt;</pre>
</div>
<p>The static style resource defines a custom look for the Slider to create an accent colored rectangle, instead of looking like the normal phone Slider control you may place on the page.</p>
<p>Nesting controls within templates is how Silverlight was designed to work, so it isn’t the composition of controls that necessarily degrades performance in this case (though simplicity is always key, especially on a device that has very different computing properties than your PC).</p>
<p>Now here’s a small chunk of the Storyboard animation code that animates the Slider instances. Note the <strong>Value</strong> target property:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:4add9eae-5ead-4c8c-afdd-ecaa898b2280" class="wlWriterEditableSmartContent">
<pre class="xml" name="code"> &lt;DoubleAnimationUsingKeyFrames
    Storyboard.TargetName="Slider3"
    Storyboard.TargetProperty="Value"
    BeginTime="00:00:00.4"&gt;
&lt;!-- and so on --&gt;
 &lt;/DoubleAnimationUsingKeyFrames&gt;
 </pre>
</div>
<p>And now we are finally to the root of the problem: the trouble is that <strong>Value</strong> is a DependencyProperty defined by the nested Slider controls, and it has some performance implications.</p>
<h3>Animating the Slider::Value property means the animation happens on the UI thread (not good!)</h3>
<p>The <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.rangebase.value(v=VS.95).aspx">Value</a> DependencyProperty of Slider comes from its parent class, RangeBase. The declaration for the property shows that there is a property change callback, OnValueChanged, that is called whenever the property changes, so in our case, when the progress bar animations animate the Slider.Value target property – which will be every single frame, it’s an animation.</p>
<p>The platform allows dependency properties to optionally have these callbacks to perform logic and states changes, validation, and other operations. In real world control development, I’d guess that it’s 50/50 whether a property has that callback. So it’s not a design flaw of a property, they are there for a good reason, but can have unintended consequences to performance, especially once you start doing wild things with those properties.</p>
<p>If you open up Reflector to look at Slider, you’ll see a call to UpdateTrackLayout. This is the meat of the control that updates the size of the template’s special Grid columns or rows to simulate the movement of the Slider.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="ReflectorSlider" border="0" alt="ReflectorSlider" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/08/ReflectorSlider.png" width="685" height="371" /></p>
<p>The callback will always happen on the UI thread, as all core UI interactions on the platform need to happen on the UI thread, and the runtime guarantees this.</p>
<p>That means that the five animations for the value property cannot happen on the separate render thread.</p>
<h3>What needs to change in ProgressBar? Should we build our own?</h3>
<p>So maybe the default style on the phone is a little “heavy”; but the <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.progressbar(VS.95).aspx">ProgressBar control</a> implementation is fine. There are no code fixes or changes required to the actual control.</p>
<p>I recommend just using a special C# file and re-templating the standard ProgressBar, though it would be easy enough to package this up into an independent control library or ship with some kind of toolkit. We’ll see what people do.</p>
<h3>Why can’t MSFT update the progress bar in the platform?</h3>
<p>I’m really only talking here about the beta version of the developer tools for the Windows Phone.</p>
<p>In my opinion, changing this in the platform while matching the Windows Phone user interface guidelines is a big technical challenge (again, the lack of ratio-based translation key frames in Silverlight), so in the meantime, please use mine – I’ll make sure it continues to work through the release of the phone and will blog and <a href="http://www.twitter.com/jeffwilcox/">tweet</a> updates as necessary.</p>
<p>This could change in the future, but since this workaround doesn’t change the ProgressBar control itself, it is easy enough to pull out the workaround – just remove the custom Style setter!</p>
<h3>Shouldn’t everything just be fast and have great performance anyway?</h3>
<p>We all wish. There is a lot of give and take in application development and especially tweaking for perf.</p>
<p>On the Silverlight mobile team we’re very serious about performance, but don’t expect performance to be free: we’re doing our part to drive performance improvements through the product, but we need application developer’s help as well to optimize their applications for the phone experience.</p>
<h3>What’s this RelativeAnimatingContentControl I added to my project?</h3>
<p>I designed this custom content control that makes adjustments to the storyboards of the visual states attached to it. When the layout is updated (i.e. there is a known size), the control will go through the storyboards and update the properties that are designed to be “relative”, using its initial ratio.</p>
<p>The control has some magic number trickery to accomplish this, and only works with double animation elements and double animations with key frames. Instead of hard-coding numbers and using that, the control interprets the initial values of the animation properties as a percentage. If you’re interested in the inner workings, let me know and I am happy to post more about it. Quickly, if a From, To, or keyframe Value has an initial value ending in “.1” (such as 33.1, or 75.1, or 0.1), the property is interpreted as a percentage ratio based on the width of the control – 0 to 100. The .1 is stipped off. If the magic number decimal is instead .2, like 50.2, then the height of the control is used for the calculation instead. The idea is that a designer and coder work to define the special template with these magic numbers, but it doesn’t keep the designer from defining other animations that are not ratio-based.</p>
<p>Since the control must be the root of the ProgressBar template, it is an opt-in model and won’t affect any other uses of ProgressBar either.</p>
<p>This is all to work around the lack of ratio animation properties in Silverlight, and it’s a pretty good solution, magic numbers aside. I feel a little sick about the magic numbers part. I’m sharing this feedback with the team of course and we’ll see what the future holds.</p>
<h3>Why’s the control in the Microsoft.Phone.Controls.Unsupported namespace?</h3>
<p>I wanted to make it clear to everyone that this is not an official Microsoft control. It’s a way to work around a limitation in Silverlight, and probably not a good general-purpose solution.</p>
<p>That said, the namespace probably should be JeffWilcox.Controls.Supported: I’m always happy to look at the feedback I get on these posts and update the content to be relative and address issues.</p>
<h3>What changed in the PerformanceProgressBar style</h3>
<p>You’ll see that the ProgressBar style looks very similar. Here are some of the differences:</p>
<ul>
<li>The root of the control template is this special RelativeAnimatingContentControl. The control updates the visual state storyboards when the size of the control changes, giving the animations a ratio to the size of the control based on the initial value stored in the storyboard.</li>
<li>The 5 Slider controls have been replaced by 5 simple Rectangle instances</li>
<li>The rectangles have BitmapCache turned on</li>
<li>Each rectangle has a defined TranslateTransform which is used to move the rectangle instead of the UI animation from the standard (which animated the Value property, on the UI thread, which then made the item move after a layout pass with the underlying grid in the template)</li>
</ul>
<p>So here’s the part with the rectangles:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:b5c76af6-4a75-4732-95cb-1c94fc0bd0f2" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;Rectangle Fill="{TemplateBinding Foreground}" Height="4" IsHitTestVisible="False" Width="4" x:Name="R1" Opacity="0" CacheMode="BitmapCache"&gt;
    &lt;Rectangle.RenderTransform&gt;
        &lt;TranslateTransform x:Name="R1TT"/&gt;
    &lt;/Rectangle.RenderTransform&gt;
&lt;/Rectangle&gt;</pre>
</div>
<p>And here’s some of the animation code. Note the “magic” numbers ending in 0.1 – those tell the system it’s a ratio based on the width of the control. A hacky overload of a property, but something that can work and give us a real perf win today!</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:f6eb4232-271b-4bd0-a9fe-f81267588c50" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00.0" Storyboard.TargetProperty="X" Storyboard.TargetName="R1TT"&gt;
    &lt;LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="0.1"/&gt;
    &lt;EasingDoubleKeyFrame KeyTime="00:00:00.5" Value="33.1" EasingFunction="{StaticResource ProgressBarEaseOut}"/&gt;
    &lt;LinearDoubleKeyFrame KeyTime="00:00:02.0" Value="66.1"/&gt;
    &lt;EasingDoubleKeyFrame KeyTime="00:00:02.5" Value="100.1" EasingFunction="{StaticResource ProgressBarEaseIn}"/&gt;
&lt;/DoubleAnimationUsingKeyFrames&gt;</pre>
</div>
<h3>Feedback</h3>
<p>I hope everyone uses this ProgressBar to make their apps rock. Remember that one key to great perf is to let the UI thread “breath”: don’t bog it down, let it do its job, and especially in loading, downloading and parsing scenarios, really important to use a progress bar that won’t inhibit the progress.</p>
<p>This is pre-release information and is subject to change. I’ll try and keep the post updated. Let me know how it goes!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/08/performanceprogressbar/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Frame rate counters in Windows Phone</title>
		<link>http://www.jeff.wilcox.name/2010/07/counters/</link>
		<comments>http://www.jeff.wilcox.name/2010/07/counters/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 16:29:25 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/07/counters/</guid>
		<description><![CDATA[Information about the frame rate counters and graphics stats for analyzing Silverlight for Windows Phone applications.]]></description>
			<content:encoded><![CDATA[<p>While developing Windows Phone applications, it’s good to have some simple but important performance tips and tricks in your back pocket. Here’s a quick reference to enabling frame rate counters plus an overview of what the values represent.</p>
<h3>Enable frame rate counters in code</h3>
<p>In your App.xaml.cs or MainPage.xaml.cs, in the constructor, set the host property to true for this diagnostic mode:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:378ddd5a-123a-41a2-a6ef-0f9fd6d5a856" class="wlWriterEditableSmartContent">
<pre class="brush:c-sharp">Application.Current.Host.Settings.EnableFrameRateCounter = true;</pre>
</div>
<h3>Make sure the System Tray is not visible</h3>
<p>By default in the beta tools, the MainPage.xaml sets the system tray to be visible. When this happens, the frame rate counters are hidden by the operating system shell.</p>
<h4>Method 1: XAML</h4>
<p>The default page template includes an XMLNS declaration for “shell”, and has this in the phone application page constructor:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:dd7b0f4f-0bde-4d4b-ad6f-c8ab434439e4" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">shell:SystemTray.IsVisible="true"</pre>
</div>
<p>Just change the IsVisible property to False:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:a0e29e6c-c60c-4e75-b7cf-4ed385579858" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">shell:SystemTray.IsVisible="false"</pre>
</div>
<h4>Method 2: Code</h4>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:7dabaf74-49ed-4989-8fbb-fa60197a381f" class="wlWriterEditableSmartContent">
<pre class="c-sharp" name="code">Microsoft.Phone.Shell.SystemTray.IsVisible = false;</pre>
</div>
<p>In a future release of the phone tools, this is actually going to be less of an issue, as the counters will actually be right-aligned on the screen instead.</p>
<h3>Adding a simple check box to toggle the counters</h3>
<p>A lot of app developers add a check box to debug builds that lets them toggle this sort of diagnostic display. In one of our ‘Scenarios’ test applications, we have a check box on the first page, and in XAML it connects the Checked and Unchecked events to this method.:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:4c41d953-1c3e-46ff-a26a-b90e550b4487" class="wlWriterEditableSmartContent">
<pre class="c-sharp" name="code">private void FrameRateCounters_Checked(object sender, RoutedEventArgs e)
{
    var checkbox = (CheckBox)sender;
    var newValue = checkbox.IsChecked.GetValueOrDefault();

    Application.Current.Host.Settings.EnableFrameRateCounter = newValue;
    SystemTray.IsVisible = !newValue; // Hides frame rate counter otherwise
}</pre>
</div>
<h3>Enabling frame rate counters only on debug builds</h3>
<p>You can also use conditional compilation to just have your debug builds display this information. Add this to your App.xaml.cs:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:0e8e0218-898c-4457-b710-69a38d76f8b5" class="wlWriterEditableSmartContent">
<pre class="c-sharp" name="code">#if DEBUG
    Application.Current.Host.Settings.EnableFrameRateCounter = true;
    Microsoft.Phone.Shell.SystemTray.IsVisible = false;
#endif</pre>
</div>
<p>This assumes you remember to eventually ship your app on the marketplace with a release build <img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/07/wlEmoticonsmile.png" />.</p>
<h3>Accelerated graphics note: If you still don’t see a frame rate counter</h3>
<p>The frame rate counter only appears when your system has a supported DirectX 10 graphics card that allows the Windows Phone emulator to use accelerated graphics.</p>
<p>If you set the frame rate counter visibility to True, the system tray is hidden, and you still don’t’ see the counters, then unfortunately your system does not have a supported card for displaying this information.</p>
<p>All Windows Phone devices will show the frame rate counter, so once phone hardware is more widely available, you’ll still have an option to test the performance of your apps.</p>
<h3>Exploring the frame rate counter data</h3>
<p>This has been covered countless times, but I figure if you’re [using your search engine of choice to find this] here that it doesn’t hurt to duplicate.</p>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="BetaCounters" border="0" alt="BetaCounters" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/07/BetaCounters.png" width="685" height="265" /></p>
<p><em>The Beta tools display frame counter information on the top of the page.</em></p>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="NewerCounters" border="0" alt="NewerCounters" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/07/NewerCounters.jpg" width="486" height="422" /></p>
<p><em>Shipping frame counter information is displayed on the right of the screen.</em></p>
<p>So moving through the counters, we have the following.</p>
<p><strong>Render Thread FPS:</strong> The number of frames per second that the independent simple animations and rendering thread is using. Keeping around 60 will provide a great experience, while a number of 30 fps will begin to show a poor experience to the end user.</p>
<p>Under 30 fps this counter will turn red in post-beta builds.</p>
<p><strong>User Interface Thread FPS:</strong> The number of fps that the primary user interface thread is experiencing. Property change notifications, data binding, primary managed code execution, and animations not handled on the render thread use this threads’ resources.</p>
<p>Turns red when the count is at or below 15 fps.</p>
<p><strong>Texture Memory Usage: </strong>A specialized memory counter indicating the video memory used for storing application textures.</p>
<p><strong>Surface Counter: </strong>A count of the number of surfaces that are passed to the graphics chip.</p>
<p><strong>Intermediate Texture Count:</strong> The number of intermediate textures created for compositing.</p>
<p><strong>Screen Fill Rate:</strong> A metric representing the number of complete phone screens being painted each and every frame.</p>
<p>This counter was not present in the Beta tools and is a new metric for post-Beta use.</p>
<h3>Target frame rates for good performance</h3>
<p>When testing on a Windows Phone device, here are key performance metrics to try for. Understand that the emulator (XDE) performance may not be indicative of actual device performance.</p>
<p>Frame rate counters may be 0 when there is no animation being updated on the thread at any particular moment. You can add a very simple, continually animating and repeating, animation to your application during development &amp; testing if you want to ensure that there is always some frame rate value available.</p>
<table border="0" cellspacing="0" cellpadding="4" width="641">
<tbody>
<tr>
<td valign="top" width="171"><em>Counter</em></td>
<td valign="top" width="162"><em>Ideal Minimum</em></td>
<td valign="top" width="155"><em>Best Experience</em></td>
<td valign="top" width="151"><em>Theoretical Max</em></td>
</tr>
<tr>
<td valign="top" width="182">Render Thread</td>
<td valign="top" width="170">30 fps</td>
<td valign="top" width="162">60 fps</td>
<td valign="top" width="156">120 fps</td>
</tr>
<tr>
<td valign="top" width="184">UI Thread</td>
<td valign="top" width="173">15 fps</td>
<td valign="top" width="165">&gt; 15 fps</td>
<td valign="top" width="159">120 fps</td>
</tr>
<tr>
<td valign="top" width="183">Screen Fill Rate</td>
<td valign="top" width="173">1.0</td>
<td valign="top" width="167">&lt;= 2.0</td>
<td valign="top" width="161"><font color="#a5a5a5">N/A</font></td>
</tr>
</tbody>
</table>
<p>Future posts will cover tips for improving the frame rate and application performance. Hope this helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/07/counters/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Updated Silverlight Unit Test Framework bits for Windows Phone and Silverlight 3</title>
		<link>http://www.jeff.wilcox.name/2010/05/sl3-utf-bits/</link>
		<comments>http://www.jeff.wilcox.name/2010/05/sl3-utf-bits/#comments</comments>
		<pubDate>Thu, 27 May 2010 21:02:52 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Silverlight Toolkit]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/05/sl3-utf-bits/</guid>
		<description><![CDATA[Here's the same unit test framework from the April 2010 Silverlight Toolkit, built for Windows Phone and SL3 developers only.]]></description>
			<content:encoded><![CDATA[<p>Here are updated quasi-official unit test framework bits for Silverlight 3 and Windows Phone developers. These are <strong>not</strong> intended for Silverlight 4 developers, since the same framework built for SL4 is included in the <a href="http://silverlight.codeplex.com/">April 2010 Silverlight Toolkit</a>.</p>
<p>This brings the <a href="http://www.jeff.wilcox.name/2010/05/new-2010-test-framework/">new features</a> from the Silverlight 4 version to developers who have a business reason to continue with Silverlight 3 development for the time being:</p>
<ul>
<li>Updated user interface</li>
<li>Integrated “tag expression” support for selecting subsets of tests to run</li>
<li>Performance improvements</li>
<li>Removal of dependencies on XLinq and System.Windows.Browser assemblies</li>
</ul>
<p>These are also the bits you want for Windows Phone testing.</p>
<h4>Why wasn’t there one for Silverlight 3 already?</h4>
<p>Since the April 2010 toolkit release was targeted for Silverlight 4 developers only, these bits were not released for version 3 (though were built from the same source).</p>
<h4>Why doesn’t the April 2010 toolkit work for Windows Phone development &amp; testing?</h4>
<p>The Windows Phone development environment is based on a version of Silverlight 3 today, and so that means that you need to use Silverlight 3 binaries and class libraries when re-using Silverlight apps and code – <em>not</em> Silverlight 4.</p>
<p>These bits work well for phone developers and replace the older bits I had posted to my <a href="http://www.jeffatmix.com/">MIX talk site</a>.</p>
<h4>Download the binaries</h4>
<p>[<a href="http://media.jeff.wilcox.name/blog/ut/SL3_UTF_May.zip"><strong>Silverlight 3 binaries for the Silverlight Unit Test Framework</strong></a>, Zip 452KB]    <br />You may need to ‘unlock’ the binaries for security reasons once downloading and extracting the assemblies from the .Zip. To do this, right-click on the file and select the ‘Unlock’ button.</p>
<p>These binaries are strong named as before, but are <em>not</em> Authenticode signed, so they are not official. This helps work around some Windows Phone signing issues I’ve heard reports of.</p>
<p>Hope this helps,   <br />Jeff</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/05/sl3-utf-bits/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>How about a Zune-style ChildWindow?</title>
		<link>http://www.jeff.wilcox.name/2010/05/my-childwindow-design/</link>
		<comments>http://www.jeff.wilcox.name/2010/05/my-childwindow-design/#comments</comments>
		<pubDate>Fri, 21 May 2010 21:25:39 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Silverlight Toolkit]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/05/my-childwindow-design/</guid>
		<description><![CDATA[Today I am sharing my ChildWindow style that resembles the Zune software user interface and has a nice transition. Enjoy!]]></description>
			<content:encoded><![CDATA[<p>Today I’m sharing my new ChildWindow style. It is a differentiated child window designed in that it doesn’t have a close button, has a completely different animation in and out, and I thought I was worth sharing. I’ve included a runtime app so you can run it and <a href="http://media.jeff.wilcox.name/blog/cw/index.html">see for yourself</a>.</p>
<h3>My ChildWindow style</h3>
<p><a href="http://media.jeff.wilcox.name/blog/cw/index.html"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="mycw" border="0" alt="mycw" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/05/mycw.png" width="680" height="359" /></a>     <br /><em>Click on the window above to open a simple Silverlight 4 application that demonstrates the transitions and interactivity. <a href="http://media.jeff.wilcox.name/blog/cw/ChildWindowTheme.zip">Project download</a>.</em></p>
<p>Some things to call out:</p>
<ul>
<li>I don’t include a Close button in the window chrome.</li>
<li>I hook up to the OnKeyDown event in my sample implementation. I always try and do this with my ChildWindows so that the escape (ESC) key can be treated as a cancelation of the dialog. Personal preference but a usability win I believe.</li>
<li>I like a light overlay color instead of a darkening experience, and went for that look.</li>
<li>My actual implementation uses a value converter to capitalize the title. I’ve removed this from my template for the time being.</li>
</ul>
<h3>The story on my evolving, unnamed theme, and how it relates to “Cosmopolitan”</h3>
<p>There’s an excellent <a href="http://visualstudiogallery.msdn.microsoft.com/en-us/9329bdf4-3be7-4347-b1cd-b2c5d4e5a293">“Cosmopolitan” Silverlight project template</a> + theme available that makes building good-looking interfaces a snap, and I’d highly recommend it if you’re looking to modernize the look of a new Silverlight project. I believe it pulls from “codename Metro” design ideas. It just works and as a VS template it rocks!</p>
<p>I’ve built an alternative, but similar theme, over time that I use on many of my projects, and it also pulls from the inspiration of the clean, consistent <a href="http://www.zune.net/en-US/products/software/default.htm">Zune software</a> design principals.</p>
<p>Now that the “Cosmopolitan” theme is out there, I’ve been taking the time to compare and contrast my similar theme with this, and see where I can make changes. Yeah, the things I do in my free time are baffling…</p>
<p>This is a good exercise because design is a two-way street, comparing and contrasting design decisions and implementations: I’ve learned that I should have been including validation templates in my theme (oops, haven’t used that feature enough). And I’ve shared some minor feedback on parts of the “Cosmopolitan” theme’s implementation details with its designers.</p>
<p>In the future I’ll present the complete theme for many controls, but until that develops, I’m going to continue to share small styles and templates, along with my comments along the way. Previously I blogged my <a href="http://www.jeff.wilcox.name/2010/05/zunelike-contextmenu-style/">context menu style</a>.</p>
<p>If you’re wondering “why should I use ChildWindow?” &#8211; I used to wonder the same thing. But I’m using <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.childwindow(VS.95).aspx">ChildWindow</a> more now than ever. I’ve discovered the importance of the nice integration with Visual Studio (there’s an item template for child windows), and out-of-browser applications have many uses for a rich modal-style window for sharing information at runtime.</p>
<p>I’ve completely replaced the MessageBox in my out-of-browser applications to instead use a child window designed to replace the message box functionality, offering a consistent visual design even when a message box-like experience is needed. I even use extension methods to add methods to MessageBox to instead use my styled child window.</p>
<h3>Other ChildWindow styles</h3>
<p>Here’s the standard ChildWindow style and control template that is built into the Silverlight SDK. I’m displaying a password entry form adapted from an app I was experimenting with:</p>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="cw1" border="0" alt="cw1" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/05/cw1.png" width="685" height="239" /> </p>
<p>Here is the same window with the “Cosmopolitan” theme’s style applied:</p>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="cwcosmo" border="0" alt="cwcosmo" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/05/cwcosmo.png" width="685" height="274" /> </p>
<h3>Note: There’s a bug in ChildWindow implicit styling support</h3>
<p>While working on creating themes, I did discover that there’s an unfortunate bug in Silverlight 4 where the implicit styles for ChildWindow are not picked up in certain XAML scenarios. Namely, if you use the handy item template in Visual Studio, the implicit style won’t be picked up.</p>
<p>Oddly, at times Visual Studio will show the proper implicit style, but at runtime it will revert to the standard control default style. Here’s a small screenshot – this is out-of-the-box “Cosmopolitan” theme with a ChildWindow item template.</p>
<h4>At design time it looks fine:</h4>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="dt" border="0" alt="dt" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/05/dt.png" width="685" height="454" /> </p>
<h4>At runtime:</h4>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="runtime_style_not_applied_bug" border="0" alt="runtime_style_not_applied_bug" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/05/runtime_style_not_applied_bug.png" width="685" height="231" /> </p>
<p>It appears that this item template format, where the XAML file of the child window’s root is the child window, doesn’t allow the style that was implicitly defined to be picked up.</p>
<p>No worries. To workaround this, add a Style attribute to the root of the file and a static resource to ChildWindow name. If you’re working with “Cosmopolitan”, then here are the steps:</p>
<ul>
<li>Open the Assets/SDKStyles.xaml file</li>
<li>Navigate to the implicit style for ChildWindow around line 2,440</li>
<li>Add an x:Key to make the style explicit instead of implicit. x:Key=”ChildWindowStyle”</li>
<li>Add this line after the (now explicit) style:</li>
</ul>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:839e9ba9-7b8c-4d91-9a85-d509a86d8e22" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;Style TargetType="controls:ChildWindow" BasedOn="{StaticResource ChildWindowStyle}" /&gt;</pre>
</div>
<ul>
<li>Open your ChildWindow XAML file (mine is called Password.xaml) and add the attribute Style=”{StaticResource ChildWindowStyle}” to the root element</li>
</ul>
<h4>And here’s it at runtime now with our fix/workaround:</h4>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="cwcosmo" border="0" alt="cwcosmo" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/05/cwcosmo.png" width="685" height="274" /></p>
<p>Note that whenever defining implicit styles myself, I always start explicit, then provide the implicit in the file using BasedOn.</p>
<h4>Download my sample project including the style</h4>
<p>[<a href="http://media.jeff.wilcox.name/blog/cw/ChildWindowTheme.zip">ChildWindowTheme.zip</a>, 71 KB] Includes the theme in App.xaml.</p>
<h3>“My yet-to-be-named Zune-inspired theme” components</h3>
<ul>
<li>ChildWindow (this post)</li>
<li><a href="http://www.jeff.wilcox.name/2010/05/zunelike-contextmenu-style/">ContextMenu</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/05/my-childwindow-design/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Using Silverlight 4 features to create a Zune-like context menu</title>
		<link>http://www.jeff.wilcox.name/2010/05/zunelike-contextmenu-style/</link>
		<comments>http://www.jeff.wilcox.name/2010/05/zunelike-contextmenu-style/#comments</comments>
		<pubDate>Sat, 15 May 2010 19:25:12 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Silverlight Toolkit]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/05/zunelike-contextmenu-style/</guid>
		<description><![CDATA[A customized Silverlight 4 ContextMenu control that resembles the crisp, simple look of the Zune software's context menu.]]></description>
			<content:encoded><![CDATA[<p>Trying to create a modern, clean and crisp user interface is a challenge – and it’s something that Zune has done rather well in both their software and hardware experiences.</p>
<p>I took a few minutes to experiment with new Silverlight 4 features, including the new <a href="http://silverlight.codeplex.com/">Silverlight Toolkit</a> (April 2010 release) that includes a context menu control, to re-style/re-template the menu to look similar to a few other menus.</p>
<p>Here’s a quick look at some common context menu visuals – clearly there is some room for artistry in creating a consistent experience with your app.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ContextMenus" border="0" alt="ContextMenus" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/05/ContextMenus.png" width="680" height="330" /> </p>
<p>The center context menu, with the Windows look, is what the default Silverlight Toolkit context menu looks most similar to.</p>
<h3>New features used</h3>
<ul>
<li>Right-click input event, added to the platform in Silverlight 4</li>
<li>Context menu control from the Silverlight Toolkit</li>
<li>Implicit styles support</li>
<li>Local fonts</li>
</ul>
<h3>Consider checking out ‘Cosmopolitan’, too</h3>
<p>There’s a theme that resembles the modern “codename Metro” design style, similar to that of the Zune user interface, that is available for Silverlight 4. <a href="http://timheuer.com/blog/archive/2010/05/03/new-silverlight-4-themes-available-for-download.aspx">More information is available on Tim’s blog</a>.</p>
<h3>What a context menu looks like in XAML</h3>
<p>You need an xmlns for the input assembly in the Silverlight Toolkit. Then you setup the ContextMenuService, a ContextMenu instance, plus multiple MenuItem and Separator instances.</p>
<p>A MenuItem can optionally have an icon, though I believe the trend these days is moving away from the icon-heavy menu and toolbar world into a clean &amp; crisp text-only experience… so I prefer a styled context menu that doesn’t optimize for icons.</p>
<p>The XMLNS for the context menu assembly is:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:9c30beb8-bc99-4dd4-9b26-528b0155f629" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">xmlns:controlsInputToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"</pre>
</div>
<p>You can directly wire up to the Click event, or use Commands. Here’s a sample context menu within a data template:</p>
<p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:f1699113-aaec-4a27-8290-b5a8687024a8" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;ListBox.ItemTemplate&gt;
    &lt;DataTemplate&gt;
        &lt;ContentPresenter Content="{Binding}"&gt;
            &lt;controlsInputToolkit:ContextMenuService.ContextMenu&gt;
                &lt;controlsInputToolkit:ContextMenu&gt;
                    &lt;controlsInputToolkit:MenuItem Header="Play" Click="OnMenuItemClick"/&gt;

                    &lt;controlsInputToolkit:Separator/&gt;

                    &lt;controlsInputToolkit:MenuItem Header="Download" Click="OnMenuItemClick"/&gt;
                    &lt;controlsInputToolkit:MenuItem Header="Buy" Click="OnMenuItemClick"/&gt;
                    &lt;controlsInputToolkit:MenuItem Header="Add to cart" Click="OnMenuItemClick"/&gt;

                    &lt;controlsInputToolkit:Separator/&gt;

                    &lt;controlsInputToolkit:MenuItem Header="Add to playlist" Click="OnMenuItemClick"/&gt;
                    &lt;controlsInputToolkit:MenuItem Header="Add to burn list" Click="OnMenuItemClick"/&gt;
                    &lt;controlsInputToolkit:MenuItem Header="Add to now playing" Click="OnMenuItemClick"/&gt;
                    &lt;controlsInputToolkit:MenuItem Header="Mark as favorite" Click="OnMenuItemClick"/&gt;

                    &lt;controlsInputToolkit:Separator/&gt;

                    &lt;controlsInputToolkit:MenuItem Header="Send" Click="OnMenuItemClick"/&gt;

                &lt;/controlsInputToolkit:ContextMenu&gt;
            &lt;/controlsInputToolkit:ContextMenuService.ContextMenu&gt;
        &lt;/ContentPresenter&gt;
    &lt;/DataTemplate&gt;
&lt;/ListBox.ItemTemplate&gt;</pre>
</div>
<p>And here’s what it looks like:</p>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DefaultContextMenu" border="0" alt="DefaultContextMenu" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/05/DefaultContextMenu.png" width="188" height="242" /> </p>
<p>To use the ContextMenu, make sure your project includes references to <em>both</em> the toolkit’s System.Windows.Controls.Input.Toolkit.dll as well as the SDK’s System.Windows.Controls.dll.</p>
<p>Now I’d like to make this look more Zune-like.</p>
<h3>Using implicit styles</h3>
<p>So there are multiple ways to have a style (predefined look, settings and template) on your object:</p>
<ol>
<li>Default style key – the default template and style that the creator of the control had in mind. No work required.</li>
<li>Implicit styles defined in Resources – in Silverlight 4, a Style defined by a user, but without an x:Key property, will automatically apply to all scoped controls of that type.</li>
<li>Static resource styles defined in Resources – the standard experience up until now, having a Style with an x:Key, then setting the Style=”{StaticResource MyKeyName}” on any and all controls that want to use that style.</li>
<li>Setting properties directly on an object.</li>
</ol>
<p>So here is a standard, simple style for a Button, with the key:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:dc290aa0-a366-4943-89ce-8a6771e556a1" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;UserControl.Resources&gt;
    &lt;Style TargetType="Button" x:Key="MyButtonStyle"&gt;
        &lt;Setter Property="Background" Value="Blue"/&gt;
    &lt;/Style&gt;
&lt;/UserControl.Resources&gt;</pre>
</div>
<p>Here’s how you reference it:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:1c329b9f-9e83-41e4-9883-2927dfdb6c1e" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;Button Style="{StaticResource MyButtonStyle}" Content="OK"/&gt;</pre>
</div>
<p>And now let’s make that into an implicit style for Silverlight 4. Just remove the x:Key:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:86e3e09e-40ad-4ef7-a8cb-6ad12d9df35a" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;UserControl.Resources&gt;
    &lt;Style TargetType="Button"&gt;
        &lt;Setter Property="Background" Value="Blue"/&gt;
    &lt;/Style&gt;
&lt;/UserControl.Resources&gt;</pre>
</div>
<p>And here’s how you reference that style – you don’t – it’s implicit:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:87648dd1-5f46-4050-af9d-07bf7335c0a9" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;Button Content="OK"/&gt;</pre>
</div>
<p><em>Small caveat, fyi:</em> there is a bug with implicit styles not necessarily being applied within data templates. To work around this, I had to move to explicit styles (adding an x:Key to the style, then setting the Style property in the DataTemplate’s XAML to the static resource’s key).</p>
<h3>Local fonts</h3>
<p>I also used a feature of Silverlight 4 that lets me pick up and use local fonts on the machine. I’m using the ‘Segoe UI’ font, a key part of the Windows 7 user experience and visual identity.</p>
<p>However I also define fallback fonts, just like you would in HTML:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:a62b7fd6-6547-4165-9612-f4a9141b6a58" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;Setter Property="FontFamily" Value="Segoe UI, Tahoma, Arial"/&gt;</pre>
</div>
<h3>My Zune-like context menu</h3>
<p>Here are the templates I ended up creating using Expression Blend.</p>
<p>To achieve the fade-in effect, I faked a little and used a Loaded event trigger, so the first time any particular context menu is shown, it will quickly fade – but subsequent presentations of the same instance will not fade, for a faster, more performant feel.</p>
<h4>ContextMenu Style</h4>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:d0a111a7-b70d-4f8b-b81a-abad98ad685e" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;Style TargetType="controlsInputToolkit:ContextMenu" x:Key="ZuneLikeContextMenu"&gt;
    &lt;Setter Property="Background" Value="#FFFFFFFF"/&gt;
    &lt;Setter Property="BorderThickness" Value="0,1,0,1"/&gt;
    &lt;Setter Property="BorderBrush" Value="#0D000000"/&gt;
    &lt;Setter Property="Padding" Value="0,4,0,4"/&gt;
    &lt;Setter Property="Template"&gt;
        &lt;Setter.Value&gt;
            &lt;ControlTemplate TargetType="controlsInputToolkit:ContextMenu"&gt;
                &lt;Border
                    x:Name="Menu"
                    Opacity="0"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    Background="{TemplateBinding Background}"
                    CornerRadius="0"&gt;
                    &lt;Border.Effect&gt;
                        &lt;DropShadowEffect
                            ShadowDepth="0" Opacity="0.6" BlurRadius="22"/&gt;
                    &lt;/Border.Effect&gt;
                    &lt;Border.Triggers&gt;
                        &lt;EventTrigger RoutedEvent="Rectangle.Loaded"&gt;
                            &lt;BeginStoryboard&gt;
                                &lt;Storyboard&gt;
                                    &lt;DoubleAnimation
                                        Duration="0:0:0.2"
                                        To="1"
                                        Storyboard.TargetProperty="Opacity"
                                        Storyboard.TargetName="Menu"/&gt;
                                &lt;/Storyboard&gt;
                            &lt;/BeginStoryboard&gt;
                        &lt;/EventTrigger&gt;
                    &lt;/Border.Triggers&gt;
                    &lt;Grid&gt;
                        &lt;ItemsPresenter Margin="{TemplateBinding Padding}"/&gt;
                    &lt;/Grid&gt;
                &lt;/Border&gt;
            &lt;/ControlTemplate&gt;
        &lt;/Setter.Value&gt;
    &lt;/Setter&gt;
&lt;/Style&gt;</pre>
</div>
<h4>Separator Style</h4>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:010d1470-b3e8-4932-8394-67b1a78e20ce" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;Style TargetType="controlsInputToolkit:Separator" x:Key="ZuneLikeSeparator"&gt;
    &lt;Setter Property="Background" Value="LightGray"/&gt;
    &lt;Setter Property="IsTabStop" Value="False"/&gt;
    &lt;Setter Property="Margin" Value="6,2,6,2"/&gt;
    &lt;Setter Property="Template"&gt;
        &lt;Setter.Value&gt;
            &lt;ControlTemplate TargetType="controlsInputToolkit:Separator"&gt;
                &lt;Border
                    BorderThickness="{TemplateBinding BorderThickness}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    Background="{TemplateBinding Background}"
                    Height="1"/&gt;
            &lt;/ControlTemplate&gt;
        &lt;/Setter.Value&gt;
    &lt;/Setter&gt;
&lt;/Style&gt;</pre>
</div>
<h4>MenuItem Style</h4>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:d0da5a04-eff4-4c6b-b93e-b68154f08dad" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;Style TargetType="controlsInputToolkit:MenuItem" x:Key="ZuneLikeMenuItem"&gt;
    &lt;Setter Property="Background" Value="Transparent"/&gt;
    &lt;Setter Property="FontSize" Value="14"/&gt;
    &lt;Setter Property="FontFamily" Value="Segoe UI, Tahoma, Arial"/&gt;
    &lt;Setter Property="BorderBrush" Value="Transparent"/&gt;
    &lt;Setter Property="BorderThickness" Value="0"/&gt;
    &lt;Setter Property="Padding" Value="8,2,10,2"/&gt;
    &lt;Setter Property="Template"&gt;
        &lt;Setter.Value&gt;
            &lt;ControlTemplate TargetType="controlsInputToolkit:MenuItem"&gt;
                &lt;Grid&gt;
                    &lt;VisualStateManager.VisualStateGroups&gt;
                        &lt;VisualStateGroup x:Name="CommonStates"&gt;
                            &lt;VisualState x:Name="Normal"/&gt;
                            &lt;VisualState x:Name="Disabled"&gt;
                                &lt;Storyboard&gt;
                                    &lt;DoubleAnimation Duration="0" Storyboard.TargetName="Presenter" Storyboard.TargetProperty="Opacity" To="0.5"/&gt;
                                &lt;/Storyboard&gt;
                            &lt;/VisualState&gt;
                        &lt;/VisualStateGroup&gt;
                        &lt;VisualStateGroup x:Name="FocusStates"&gt;
                            &lt;VisualState x:Name="Unfocused"/&gt;
                            &lt;VisualState x:Name="Focused"&gt;
                                &lt;Storyboard&gt;
                                    &lt;DoubleAnimation Duration="0" Storyboard.TargetName="Bg" Storyboard.TargetProperty="Opacity" To="1"/&gt;
                                    &lt;DoubleAnimation Duration="0" Storyboard.TargetName="IconPresenter" Storyboard.TargetProperty="Opacity" To="1"/&gt;
                                    &lt;DoubleAnimation Duration="0" Storyboard.TargetName="Presenter" Storyboard.TargetProperty="Opacity" To="1"/&gt;
                                &lt;/Storyboard&gt;
                            &lt;/VisualState&gt;
                        &lt;/VisualStateGroup&gt;
                    &lt;/VisualStateManager.VisualStateGroups&gt;
                    &lt;Rectangle
                        RadiusX="0"
                        RadiusY="0"
                        Fill="{TemplateBinding Background}"
                        Stroke="{TemplateBinding BorderBrush}"
                        StrokeThickness="{TemplateBinding BorderThickness}"/&gt;
                    &lt;Rectangle
                        x:Name="Bg"
                        RadiusX="0"
                        RadiusY="0"
                        StrokeThickness="0"
                        Opacity="0"
                        Fill="#11000000"/&gt;
                    &lt;Grid Margin="{TemplateBinding Padding}"&gt;
                        &lt;Grid.ColumnDefinitions&gt;
                            &lt;ColumnDefinition
                                Width="Auto"/&gt;
                            &lt;ColumnDefinition Width="2"/&gt;
                            &lt;ColumnDefinition Width="*"/&gt;
                            &lt;ColumnDefinition Width="17"/&gt;
                        &lt;/Grid.ColumnDefinitions&gt;
                        &lt;ContentPresenter
                            x:Name="IconPresenter"
                            Content="{TemplateBinding Icon}"
                            Margin="1"
                            Opacity=".7"
                            VerticalAlignment="Center"/&gt;
                        &lt;ContentPresenter
                            x:Name="Presenter"
                            MinWidth="120"
                            Opacity=".7"
                            Content="{TemplateBinding Header}"
                            ContentTemplate="{TemplateBinding HeaderTemplate}"
                            Grid.Column="2"/&gt;
                    &lt;/Grid&gt;
                &lt;/Grid&gt;
            &lt;/ControlTemplate&gt;
        &lt;/Setter.Value&gt;
    &lt;/Setter&gt;
&lt;/Style&gt;</pre>
</div>
<p><a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/05/ZuneLikeContextMenuImplicitStyles.xaml_.txt"><strong>ZuneLikeContextMenuImplicitStyles.xaml.txt</strong></a><strong>:</strong> XAML. Download all three in one file. The file contains both implicit styles plus defined style names.</p>
<p>Here’s a comparison, a screenshot of the Zune menu on the left, and my Silverlight 4 context menu on the right:</p>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="FinalContextMenus" border="0" alt="FinalContextMenus" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/05/FinalContextMenus.png" width="400" height="240" /> </p>
<p>Hope this helps you create some nice modern-looking Silverlight apps!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/05/zunelike-contextmenu-style/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Deep dive on Silverlight unit testing at Tech Ed next month</title>
		<link>http://www.jeff.wilcox.name/2010/05/silverlight-testing-at-teched-2010/</link>
		<comments>http://www.jeff.wilcox.name/2010/05/silverlight-testing-at-teched-2010/#comments</comments>
		<pubDate>Tue, 11 May 2010 18:30:12 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[TechEd]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/05/silverlight-testing-at-teched-2010/</guid>
		<description><![CDATA[Jeff Wilcox will be presenting a 200-level deep dive talk on Silverlight unit testing at the TechEd North America 2010 conference next month in New Orleans.]]></description>
			<content:encoded><![CDATA[<p>In about a month I will be presenting a 200-level session on Silverlight unit testing at <a href="http://northamerica.msteched.com/">Tech Ed North America in New Orleans</a>. The talk will be an hour with questions, so you can arrive new to Silverlight testing and leave with all the tools you need to be successful in building high-quality applications with the right level of regression coverage that your management can smile about.</p>
<p>The session will be more comprehensive than the overview talk I presented at <a href="http://www.jeff.wilcox.name/2010/03/mix10-testing-talk-online/">MIX 10 (which is available as a free online video stream now)</a>.</p>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="TechEd_2010" border="0" alt="TechEd_2010" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/05/TechEd_2010.png" width="300" height="123" /> </p>
<p><a href="http://northamerica.msteched.com/topic/list?keyword=WEB205">Click here to view the talk information</a> on the Tech Ed site. The tentative information is as follows, but please double-check with the conference schedule builder before showing up:</p>
<blockquote><p><a href="http://northamerica.msteched.com/topic/list?keyword=WEB205"><strong>Unit Testing in Microsoft Silverlight</strong></a>       <br />Wednesday, June 9, 2010       <br />11:45 AM – 1:00 PM       <br />Room 287       <br />Session Code WEB205       <br /><a title="http://northamerica.msteched.com/topic/list?keyword=WEB205" href="http://northamerica.msteched.com/topic/list?keyword=WEB205">http://northamerica.msteched.com/topic/list?keyword=WEB205</a></p>
</blockquote>
<p>Hope to see some friendly faces in the audience! I’ll be up there in some sort of speaker polo shirt uniform with khakis, apparently this conference isn’t quite as trendy and cool as MIX in Vegas <img src='http://www.jeff.wilcox.name/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> .</p>
<p>If you’re going to be attending Tech Ed, I’d appreciate any early comments you have as there is still time to shape the content of the talk.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/05/silverlight-testing-at-teched-2010/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Silverlight Unit Test Framework: New version in the April 2010 Silverlight Toolkit</title>
		<link>http://www.jeff.wilcox.name/2010/05/new-2010-test-framework/</link>
		<comments>http://www.jeff.wilcox.name/2010/05/new-2010-test-framework/#comments</comments>
		<pubDate>Mon, 03 May 2010 22:26:06 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Silverlight Toolkit]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/05/new-2010-test-framework/</guid>
		<description><![CDATA[The latest release of the Silverlight Toolkit contains the new Silverlight Unit Test Framework, with a new modern user interface, out-of-browser support, and performance improvements.]]></description>
			<content:encoded><![CDATA[<p>In April we released a new version of the <a href="http://silverlight.codeplex.com/releases/view/43528">Silverlight Toolkit</a> for targeting Microsoft Silverlight 4. This release contains a new version of the Silverlight Unit Test Framework. Key improvements come in user interface, Silverlight 4 support, and performance.</p>
<h3>Rich, modern user interface</h3>
<p>The user interface no longer uses the antiquated HTML DOM bridge for displaying results, but now is a data bound, rich Silverlight application itself.</p>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="NewTestFramework" border="0" alt="NewTestFramework" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/05/NewTestFramework.png" width="685" height="579" /></p>
<p>Rich results information is available, and a tree view control allows you to select results to be included in a test report that can be copied to the clipboard. Failures are automatically selected.</p>
<p>The results pane includes information about the tests that ran, as well as detailed information for failures.</p>
<p>Descriptive text helps identify negative tests, known test issues and bugs, and other important metadata that was not always exposed in the previous test framework.</p>
<h4>Integrated tag expression support</h4>
<p>The startup experience now allows you to enter a tag expression to select which tests to run, or not to run. You can add the Tag(“”) attribute to any test methods or classes to define your own tags. Also, the full and short names of tests and classes implicitly become test tags, as well as priorities.</p>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="TagExpressionsEditor" border="0" alt="TagExpressionsEditor" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/05/TagExpressionsEditor.png" width="685" height="375" /> </p>
<p>This means that you can define tags such as:</p>
<table border="0" cellspacing="0" cellpadding="2" width="600">
<tbody>
<tr>
<td valign="top" width="152">!MyTest1</td>
<td valign="top" width="448">Run all tests except for the method named MyTest1</td>
</tr>
<tr>
<td valign="top" width="152">MyTest1+MyTest2</td>
<td valign="top" width="448">Run the MyTest1 and MyTest2 test methods</td>
</tr>
</tbody>
</table>
<h3>Out of Browser support</h3>
<p>The framework now supports running out-of-browser. Paired with the new Silverlight 4 Tools for Visual Studio 2010, you can press F5 to run a test project you have marked as an out-of-browser.</p>
<p>This also opens up an opportunity to do testing of elevated apps that make use of AutomationFactory and other advanced features on Windows.</p>
<h3>Simplified dependencies</h3>
<p>The test framework removed dependencies on System.Windows.Browser (from the platform) and System.Xml.Linq (XLinq, from the SDK).</p>
<h3>Building blocks for Windows Phone testing support</h3>
<p>This version also contains the full source to the phone testing interface, which is significantly different in visual design and experience to coincide with the Windows Phone device size.</p>
<p>However, the story for phone testing is still developing: in the meantime binaries designed for phone use can be found at <a href="http://jeffatmix.com/">http://jeffatmix.com/</a> </p>
<h3>New location for binaries</h3>
<p>Since the new rich user interface contains a number of controls, the traditional design-time integration system conflicts and presents some issues.</p>
<p>As a result, we had to move the binaries from the Bin directory of the toolkit installation folder into a new Testing directory.</p>
<p>So the two test framework assemblies (Microsoft.Silverlight.Testing and Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight) have moved.</p>
<p>This location change could cause existing applications that reference the test assemblies to fail to compile due to the &quot;missing&quot; references.</p>
<p>If that happens, please delete the two broken references and create references to these assemblies in their new location. Everything else should continue to work as expected.</p>
<h3>Simplified test project template</h3>
<p>In alignment with the test project changes in Visual Studio 2010, which are more simplified, the unit test project template for Silverlight no longer includes a README.TXT file.</p>
<h3>Known issues</h3>
<h5>Test service</h5>
<p>I’ve received reports from a number of people about issues with the test service automation support. Some of the NDA/preview users of the framework reported issues that were corrected, but there may still be some bugs out there. I’m working to investigate and post a fix if and when I know more.</p>
<p>In the meantime I know that <a href="http://statlight.net/">StatLight</a>, a third party system, has been updated for the April release and is working well for automation.</p>
<h5>Test panel and visuals</h5>
<p>Please beware that some of your tests may need to be updated to use the new framework if your application, utility functions, or tests ever used the Application.Current.RootVisual (against the recommended pattern for interface testing).</p>
<p>The root visual is now the test framework application runner itself, and the tests run within the same TestPanel as before. Controls added to the test panel will not be located at the 0, 0 screen position, but likely near the bottom of the screen instead.</p>
<p>Hope this helps. To get started, download and install the April toolkit!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/05/new-2010-test-framework/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Property change notifications for multithreaded Silverlight applications</title>
		<link>http://www.jeff.wilcox.name/2010/04/propertychangedbase-crossthread/</link>
		<comments>http://www.jeff.wilcox.name/2010/04/propertychangedbase-crossthread/#comments</comments>
		<pubDate>Fri, 02 Apr 2010 18:27:28 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[silverlight;data binding;threading]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/04/propertychangedbase-crossthread/</guid>
		<description><![CDATA[Jeff Wilcox introduces a base class for dealing with INotifyPropertyChanged classes that is safe to use from background threads in Silverlight and Windows Phone.]]></description>
			<content:encoded><![CDATA[<p>As I’ve been developing more complex Silverlight business applications, I’ve been increasingly relying on <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(VS.95).aspx">BackgroundWorker</a> to offload complex calculations and operations to the background thread.</p>
<p>Something I didn’t have to worry about in the typical user interface thread-only implementation of my app was which thread change notifications fire on.</p>
<p>Here’s a typical scenario:</p>
<ol>
<li>You have a CLR property on a data/model object in your app. In a background thread, the property is updated.</li>
<li>As all data and model objects should be, the type implements <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(VS.95).aspx">INotifyPropertyChanged</a> (the data binding system relies on this to know when to update bindings).</li>
<li>The property changed event is fired, and listeners react to the change, including the data binding system.</li>
<li>The data binding system throws an invalid cross thread exception, since all UI operations, including handing off the binding changes, need to happen on the UI thread (but it’s happening on a background thread)</li>
</ol>
<p><a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/04/BackgroundThreadWithoutDispatcher.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="BackgroundThreadWithoutDispatcher" border="0" alt="BackgroundThreadWithoutDispatcher" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/04/BackgroundThreadWithoutDispatcher_thumb.png" width="685" height="160" /></a> </p>
<p>So what you really need to do is funnel those change notifications back to always happen on the user interface thread – that’s what makes the most sense given the data binding requirement.</p>
<p>By using a dispatcher, which can accept a BeginInvoke for that other thread, it will all just work and binding will move along happily:</p>
<p><a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/04/BackgroundThreadWithDispatcher.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="BackgroundThreadWithDispatcher" border="0" alt="BackgroundThreadWithDispatcher" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/04/BackgroundThreadWithDispatcher_thumb.png" width="685" height="160" /></a> </p>
<p>This scenario is ripe for a few helper classes that I’m open to receiving feedback on. Hope you agree with my approach of using a ‘smart dispatcher’.</p>
<h2>One Dispatcher to rule them all</h2>
<p>The only thing you need to fire an Action on the primary UI thread is a reference to a <a href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher(VS.95).aspx">Dispatcher</a> instance. Unfortunately this isn’t something you can request from a background thread – you need to have the instance already stored away in most cases.</p>
<p>As a result, I’ve a static helper class and in it, I try and make sure that there is an instance stored before any of my data binding or model code is used.</p>
<p>Though I could have used <a href="http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.aspx">SynchronizationContext</a> instead, Dispatcher is a little easier to use, and better suited to WPF and Silverlight apps.</p>
<p>In my App.xaml.cs, I add a line that calls Initialize on my class. This is to make sure that there is <em>always</em> an available dispatcher for other threads to get access to:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:80de451c-9a3a-4b80-aa15-24fd2bf7890d" class="wlWriterEditableSmartContent">
<pre class="csharp" name="code">public App()
{
    this.Startup += this.Application_Startup;
    this.Exit += this.Application_Exit;
    this.UnhandledException += this.Application_UnhandledException;

    SmartDispatcher.Initialize(Deployment.Current.Dispatcher);

    InitializeComponent();
}</pre>
</div>
<p>If you didn’t want to have to add this code to initialization, my implementation of a dispatcher helper class falls back to trying to grab the dispatcher from the root visual – but this won’t work in all scenarios, so I prefer the above. One more thing to remember however.</p>
<h2>Being smart about using the dispatcher</h2>
<p>It’s easy enough to replace all event firings for property changes to go through the dispatcher. However, this will reduce performance some; instead of the call being made immediately, it’s made at a later time.</p>
<p>There is a hidden method called <a href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.checkaccess(v=VS.95).aspx">CheckAccess</a> on Dispatcher that returns true if you are on the same thread that the Dispatcher was first created in. By checking with it before making a call, we can make a better perf choice:</p>
<ul>
<li>If CheckAccess is true and we’re on the UI thread, just go ahead and directly invoke the Action. </li>
<li>Else, BeginInvoke with the Dispatcher that will take care of getting it done on the UI thread later. </li>
</ul>
<p>I’ve also done some optimization to try and ensure that the design-time experience at least stays consistent. In general you shouldn’t have background operations ever occurring in a design-time scenario.</p>
<p>The static helper class I’ve created is called <strong>SmartDispatcher</strong> and simplifies all of this logic.</p>
<p>So here’s my smart dispatcher implementation:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:5f822523-5e30-4745-9db5-23a523f087b5" class="wlWriterEditableSmartContent">
<pre class="csharp" name="code">// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System.ComponentModel;

namespace System.Windows.Threading
{
    /// &lt;summary&gt;
    /// A smart dispatcher system for routing actions to the user interface
    /// thread.
    /// &lt;/summary&gt;
    public static class SmartDispatcher
    {
        /// &lt;summary&gt;
        /// A single Dispatcher instance to marshall actions to the user
        /// interface thread.
        /// &lt;/summary&gt;
        private static Dispatcher _instance;

        /// &lt;summary&gt;
        /// Backing field for a value indicating whether this is a design-time
        /// environment.
        /// &lt;/summary&gt;
        private static bool? _designer;

        /// &lt;summary&gt;
        /// Requires an instance and attempts to find a Dispatcher if one has
        /// not yet been set.
        /// &lt;/summary&gt;
        private static void RequireInstance()
        {
            if (_designer == null)
            {
                _designer = DesignerProperties.IsInDesignTool;
            }

            // Design-time is more of a no-op, won't be able to resolve the
            // dispatcher if it isn't already set in these situations.
            if (_designer == true)
            {
                return;
            }

            // Attempt to use the RootVisual of the plugin to retrieve a
            // dispatcher instance. This call will only succeed if the current
            // thread is the UI thread.
            try
            {
                _instance = Application.Current.RootVisual.Dispatcher;
            }
            catch (Exception e)
            {
                throw new InvalidOperationException("The first time SmartDispatcher is used must be from a user interface thread. Consider having the application call Initialize, with or without an instance.", e);
            }

            if (_instance == null)
            {
                throw new InvalidOperationException("Unable to find a suitable Dispatcher instance.");
            }
        }

        /// &lt;summary&gt;
        /// Initializes the SmartDispatcher system, attempting to use the
        /// RootVisual of the plugin to retrieve a Dispatcher instance.
        /// &lt;/summary&gt;
        public static void Initialize()
        {
            if (_instance == null)
            {
                RequireInstance();
            }
        }

        /// &lt;summary&gt;
        /// Initializes the SmartDispatcher system with the dispatcher
        /// instance.
        /// &lt;/summary&gt;
        /// &lt;param name="dispatcher"&gt;The dispatcher instance.&lt;/param&gt;
        public static void Initialize(Dispatcher dispatcher)
        {
            if (dispatcher == null)
            {
                throw new ArgumentNullException("dispatcher");
            }

            _instance = dispatcher;

            if (_designer == null)
            {
                _designer = DesignerProperties.IsInDesignTool;
            }
        }

        /// &lt;summary&gt;
        ///
        /// &lt;/summary&gt;
        /// &lt;returns&gt;&lt;/returns&gt;
        public static bool CheckAccess()
        {
            if (_instance == null)
            {
                RequireInstance();
            }

            return _instance.CheckAccess();
        }

        /// &lt;summary&gt;
        /// Executes the specified delegate asynchronously on the user interface
        /// thread. If the current thread is the user interface thread, the
        /// dispatcher if not used and the operation happens immediately.
        /// &lt;/summary&gt;
        /// &lt;param name="a"&gt;A delegate to a method that takes no arguments and
        /// does not return a value, which is either pushed onto the Dispatcher
        /// event queue or immediately run, depending on the current thread.&lt;/param&gt;
        public static void BeginInvoke(Action a)
        {
            if (_instance == null)
            {
                RequireInstance();
            }

            // If the current thread is the user interface thread, skip the
            // dispatcher and directly invoke the Action.
            if (_instance.CheckAccess() || _designer == true)
            {
                a();
            }
            else
            {
                _instance.BeginInvoke(a);
            }
        }
    }
}</pre>
</div>
<h2>A property change base class</h2>
<p>Next up, instead of having to manually wire up the INotifyPropertyChanged interface in all my data classes, I prefer to derive from a common base class, PropertyChangedBase, that has logic in it to use my smart dispatcher.</p>
<p>This base class:</p>
<ul>
<li>Has a protected NotifyPropertyChanged method that does all the real work</li>
<li>Statically stores created event arguments to improve performance over time (only one PropertyChangedEventArgs instance is required per property name in the application’s lifetime)</li>
<li>Uses SmartDispatcher to use a dispatcher only if not running on the user interface thread, otherwise directly invokes the property change handler.</li>
</ul>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:081eec95-108d-4637-bc82-a9dc32c0de06" class="wlWriterEditableSmartContent">
<pre class="csharp" name="code">// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System;
using System.Collections.Generic;
using System.Windows.Threading;

namespace System.ComponentModel
{
    /// &lt;summary&gt;
    /// A base class for data objects that implement the property changed
    /// interface, offering data binding and change notifications.
    /// &lt;/summary&gt;
    public class PropertyChangedBase : INotifyPropertyChanged
    {
        /// &lt;summary&gt;
        /// A static set of argument instances, one per property name.
        /// &lt;/summary&gt;
        private static Dictionary&lt;string, PropertyChangedEventArgs&gt; _argumentInstances = new Dictionary&lt;string, PropertyChangedEventArgs&gt;();

        /// &lt;summary&gt;
        /// The property changed event.
        /// &lt;/summary&gt;
        public event PropertyChangedEventHandler PropertyChanged;

        /// &lt;summary&gt;
        /// Notify any listeners that the property value has changed.
        /// &lt;/summary&gt;
        /// &lt;param name="propertyName"&gt;The property name.&lt;/param&gt;
        protected void NotifyPropertyChanged(string propertyName)
        {
            if (string.IsNullOrEmpty(propertyName))
            {
                throw new ArgumentException("PropertyName cannot be empty or null.");
            }

            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                PropertyChangedEventArgs args;
                if (!_argumentInstances.TryGetValue(propertyName, out args))
                {
                    args = new PropertyChangedEventArgs(propertyName);
                    _argumentInstances[propertyName] = args;
                }

                // Fire the change event. The smart dispatcher will directly
                // invoke the handler if this change happened on the UI thread,
                // otherwise it is sent to the proper dispatcher.
                SmartDispatcher.BeginInvoke(delegate
                {
                    handler(this, args);
                });
            }
        }
    }
}</pre>
</div>
<h2>Putting it all together</h2>
<p>To use this in your own application, you take your model/data classes and derive from PropertyChangedBase. Then, in CLR setters, always call NotifyPropertyChanged:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:dc14a951-f0ec-424e-a0a3-da3b76cbeada" class="wlWriterEditableSmartContent">
<pre class="csharp" name="code">public class SampleData : PropertyChangedBase
{
    private string _someText;
    public string SomeText
    {
        get { return _someText; }
        set
        {
            _someText = value;
            NotifyPropertyChanged("SomeText");
        }
    }
}</pre>
</div>
<h2>Grab the code</h2>
<p>I’ve decided to place these classes inside their appropriate system namespaces: System.Windows.Threading for the smart dispatcher, and System.ComponentModel for the PropertyChangedBase. Hope that isn’t too offensive.</p>
<p>Here are the files for download as well:</p>
<ul>
<li><a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/04/PropertyChangedBase.cs_.txt">PropertyChangedBase.cs</a></li>
<li><a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/04/SmartDispatcher.cs_.txt">SmartDispatcher.cs</a></li>
</ul>
<p>Hope this helps. Let me know what you think.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/04/propertychangedbase-crossthread/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Template parts and custom controls (quick tip)</title>
		<link>http://www.jeff.wilcox.name/2010/04/template-part-tips/</link>
		<comments>http://www.jeff.wilcox.name/2010/04/template-part-tips/#comments</comments>
		<pubDate>Fri, 02 Apr 2010 00:40:57 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Silverlight; Controls; Tips]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/04/template-part-tips/</guid>
		<description><![CDATA[Here’s a few simple tips and recommendations when developing custom Silverlight controls, as it relates to template parts. What’s with all the control development tips? We’re looking at the best way to share a lot of the ‘black magic’ of control development with the community, and will have details on that another way – today [...]]]></description>
			<content:encoded><![CDATA[<p>Here’s a few simple tips and recommendations when developing custom Silverlight controls, as it relates to template parts.</p>
<p><strong>What’s with all the control development tips?</strong></p>
<p>We’re looking at the best way to share a lot of the ‘black magic’ of control development with the community, and will have details on that another way – today so much of this information is hidden away in blog posts like this one.</p>
<p>Hopefully we’ll have a whitepaper at some point.</p>
<h3>What are template parts?</h3>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="TemplateBinding" border="0" alt="TemplateBinding" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/04/TemplateBinding.png" width="576" height="216" /> </p>
<p>Visualizing a control and it’s expected template: “MyControl” has a template part called Button, of type ButtonBase. And although it also may contain a text box, no events from the text box are used. Instead, just a template binding to the Text property.</p>
<p>This control has 1 template part: Button, not two. Don’t be tempted to have a text box template part!</p>
<h3>Do you need template parts or not?</h3>
<p>It’s important to minimize the number of template parts in a control to reduce complexity. Over-engineering controls leads to reduced code quality, expensive control maintenance, and increased testing cost.</p>
<p>If you can expose dependency properties and template bind into those properties from controls in the template, there is absolutely no reason to have parts present.</p>
<p>If you need to hook up to events of anything in the template, it’s likely that you will need to have a part for that sub control.</p>
<p>Choose wisely.</p>
<h3>Use constants for the names</h3>
<p>To prevent potential spelling errors or simple mistakes, it’s a good idea to not hard-code the template part name anywhere in your control.</p>
<p>Instead, add a constant string to the top of the file with the part name. You can then refer to it in the OnApplyTemplate method, the template part attribute, and anywhere else it is needed.</p>
<p>The constant can be protected if a subclass may want to reuse the name.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:56a12f0a-8e04-429f-abdb-294f6ea8028a" class="wlWriterEditableSmartContent">
<pre class="csharp" name="code">private const string PartButtonName = "Button";</pre>
</div>
<h3>Store parts as private fields in your class</h3>
<p>Template parts are not designed to always be inherited by any subclasses. Though the subclasses are welcome to use the same parts, they should not expect to just use the base classes: they need to use OnApplyTemplate to also grab instances of the parts.</p>
<p>So do use <strong>private fields </strong>to store the parts in the OnApplyTemplate method:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:1ca18128-2e4c-4831-903f-778ef6d4a6bd" class="wlWriterEditableSmartContent">
<pre class="csharp" name="code">private ButtonBase _button;</pre>
</div>
<h3>Detach any existing event handlers in OnApplyTemplate</h3>
<p>Controls can be restyled and retemplated as a result. Make sure to detach any event handlers from previous template parts before adding new handlers.</p>
<p>Here’s the typical pattern for that:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:097f53b0-9ab5-4d2e-a0fd-eab5b6785bac" class="wlWriterEditableSmartContent">
<pre class="csharp" name="code">public override void OnApplyTemplate()
{
    base.OnApplyTemplate();
    if (_button != null)
    {
        _button.Click -= OnButtonClick;
    }

    _button = GetTemplateChild(PartButtonName) as ButtonBase;

    if (_button != null)
    {
        _button.Click += OnButtonClick;
    }
}</pre>
</div>
<h3>Don’t assume template parts exist</h3>
<p>Whenever using template parts in your code, you should not assume that they exist. Always check for null, and unless a significant reason exists for requiring their presence, never throw an error in this condition.</p>
<p>Often code in the class relating to states and properties will execute long before the template is applied, yielding no template part instances early on.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:9a49b70a-8e0f-45d5-a1d7-3c6d32e5c1b5" class="wlWriterEditableSmartContent">
<pre class="csharp" name="code">if (_button != null)
{
   // Do something with the button
}</pre>
</div>
<h3>Mark controls with template part attributes</h3>
<p>Design surfaces like Expression Blend expect that controls are marked with the template part attributes. These are required to provide helpful tooling for editing templates.</p>
<p>Make sure to use the constant template part name that you created a few tips ago:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:887EC618-8FBE-49a5-A908-2339AF2EC720:d7b145d3-c7c4-4565-bc51-e0f5703d48aa" class="wlWriterEditableSmartContent">
<pre class="csharp" name="code">[TemplatePart(Name = PartButtonName, Type = typeof(ButtonBase))]
public partial class MyControl : ContentControl
{
}</pre>
</div>
<h3>Template parts don’t necessarily inherit from their base class</h3>
<p>It’s possible to have different template parts at each level of a control’s hierarchy. It’s even possible that subclasses may not want to use a template of a base class.</p>
<p>As a result, <strong>never</strong> provide template parts as public or protected properties on your controls. If subclasses want them, they can ask for them.</p>
<p>This is another reason it’s important to quietly check template parts for null, they may not be defined in base classes.</p>
<p>You should define template part attributes on every subclasses where expected. They do not inherit.</p>
<p>Hope this helps.</p>
<h5>Other tips</h5>
<p>David Anson has been furiously writing tips as well as we all have hallway conversations on control development: Check out:</p>
<ul>
<li><a href="http://blogs.msdn.com/delay/archive/2010/03/30/sometimes-you-just-gotta-do-the-best-you-can-tip-read-only-custom-dependencyproperties-don-t-exist-in-silverlight-but-can-be-closely-approximated.aspx">Read-only dependency properties in Silverlight</a></li>
<li><a href="http://blogs.msdn.com/delay/archive/2010/03/29/that-s-why-it-s-called-the-default-value-instead-of-default-values-tip-the-default-value-of-a-dependencyproperty-is-shared-by-all-instances-of-the-class-that-registers-it.aspx">Default values for dependency properties</a></li>
<li><a href="http://blogs.msdn.com/delay/archive/2010/03/26/when-you-have-two-good-options-go-with-the-easier-one-tip-set-dependencyproperty-default-values-in-a-class-s-default-style-if-it-s-more-convenient.aspx">Style default values if needed</a></li>
<li><a href="http://blogs.msdn.com/delay/archive/2010/03/25/the-platform-giveth-power-don-t-taketh-it-away-tip-do-not-assign-dependencyproperty-values-in-a-constructor-it-prevents-users-from-overriding-them.aspx">Don’t use the constructor to set defaults</a></li>
<li><a href="http://blogs.msdn.com/delay/archive/2010/03/24/freedom-isn-t-free-tip-when-creating-a-dependencyproperty-follow-the-handy-convention-of-wrapper-register-static-virtual.aspx">How to define dependency properties</a></li>
<li><a href="http://blogs.msdn.com/delay/archive/2010/03/23/do-one-thing-and-do-it-well-tip-the-clr-wrapper-for-a-dependencyproperty-should-do-its-job-and-nothing-more.aspx">When using dependency properties, the CLR setters and getters must be super simple</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/04/template-part-tips/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
