<?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; Windows Phone</title>
	<atom:link href="http://www.jeff.wilcox.name/topics/dev/windows-phone/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>Windows Phone? Sounds exciting!</title>
		<link>http://www.jeff.wilcox.name/2010/05/phone-developers-phone-developers/</link>
		<comments>http://www.jeff.wilcox.name/2010/05/phone-developers-phone-developers/#comments</comments>
		<pubDate>Fri, 21 May 2010 19:35:22 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/05/phone-developers-phone-developers/</guid>
		<description><![CDATA[Just letting folks know... I'm working in a much more official capacity on the Silverlight and Windows Phone developer story.]]></description>
			<content:encoded><![CDATA[<p>As an FYI, I wanted to let people know that I’m now focusing much more exclusively on the Windows Phone project here at Microsoft. Though the organization boundaries aren’t that exciting, I am still part of the great Silverlight team – only now more focused on the phone development story.</p>
<p><object width="640" height="385"><param name="movie" value="http://www.youtube-nocookie.com/v/RWtlxXC0Xnc&amp;hl=en_US&amp;fs=1&amp;rel=0&amp;color1=0x2b405b&amp;color2=0x6b8ab6"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube-nocookie.com/v/RWtlxXC0Xnc&amp;hl=en_US&amp;fs=1&amp;rel=0&amp;color1=0x2b405b&amp;color2=0x6b8ab6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object></p>
<p>It’s a familiar crowd: many of the brightest from across the company have been joining the ranks, and a lot of the classic Silverlight Toolkit team members are a part of the effort.</p>
<p>The focus of this blog won’t be changing much at all – I continue to be involved in Silverlight Toolkit, the Silverlight Unit Test Framework, and anything else I can get my hands on.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/05/phone-developers-phone-developers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>&#8220;Peppermint&#8221; MIX demo sources</title>
		<link>http://www.jeff.wilcox.name/2010/03/peppermint-src/</link>
		<comments>http://www.jeff.wilcox.name/2010/03/peppermint-src/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 21:30:53 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[MIX]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/03/peppermint-src/</guid>
		<description><![CDATA[At MIX, during my talk on unit testing Silverlight and Windows Phone applications, I demoed a simple application called ‘Peppermint’. Here’s the source; I’ll be writing up a full tutorial on Windows Phone later, so these are just ‘bleeding-edge bits’. Peppermint-Demo.zip [Zip, 1.2 MB] Silverlight: Requires Visual Studio 2010 (or express) Requires the Silverlight Toolkit [...]]]></description>
			<content:encoded><![CDATA[<p>At MIX, during my talk on <a href="http://live.visitmix.com/MIX10/Sessions/CL59">unit testing Silverlight and Windows Phone applications</a>, I demoed a simple application called ‘Peppermint’. Here’s the source; I’ll be writing up a full tutorial on Windows Phone later, so these are just ‘bleeding-edge bits’.</p>
<p><a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/03/Peppermint-Demo.zip"><strong>Peppermint-Demo.zip</strong></a> [Zip, 1.2 MB]</p>
<p>Silverlight:</p>
<blockquote><p>Requires Visual Studio 2010 (or express)     <br />Requires the <a href="http://silverlight.codeplex.com/">Silverlight Toolkit</a>      <br />Requires the test framework binaries included in the zip</p>
</blockquote>
<p>Windows Phone:</p>
<blockquote><p>Requires the <a href="http://www.silverlight.net/getstarted/devices/windows-phone/">Windows Phone development tools CTP</a>      <br />Requires the test framework binaries included in the zip</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/03/peppermint-src/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Displaying 2D QR barcodes in Windows Phone applications</title>
		<link>http://www.jeff.wilcox.name/2010/03/windowsphone-barcode/</link>
		<comments>http://www.jeff.wilcox.name/2010/03/windowsphone-barcode/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 18:37:51 +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/03/windowsphone-barcode/</guid>
		<description><![CDATA[Last year, enthused by the Starbucks Mobile Card application for the iPhone, I built an app that displays 2D QR barcodes in Silverlight. Today, in two minutes, I got that running on the Windows Phone. Talk about an awesome development experience. These barcode-displaying apps let you get rid of the plastic in your wallet and [...]]]></description>
			<content:encoded><![CDATA[<p>Last year, enthused by the <a href="http://www.techflash.com/seattle/2009/09/starbucks_debuts_apps_for_finding_stores_buying_coffee.html">Starbucks Mobile Card</a> application for the iPhone, I <a href="http://www.jeff.wilcox.name/2009/09/quick-read-silverlight-barcodes/">built an app that displays 2D QR barcodes in Silverlight</a>. Today, in two minutes, I got that running on the Windows Phone. Talk about an awesome development experience.</p>
<p>These barcode-displaying apps let you get rid of the plastic in your wallet and use your phone instead. Many airports and carriers have been using these barcodes for <a href="http://www.tsa.gov/approach/tech/paperless_boarding_pass_expansion.shtm">paperless boarding passes</a>, too.</p>
<p><a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/03/CoffeeCardApps.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="CoffeeCardApps" border="0" alt="CoffeeCardApps" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/03/CoffeeCardApps_thumb.png" width="624" height="496" /></a>     <br /><em>The barcode within the Windows Phone app on the left is QR encoded and stores the text ‘Hello World’</em></p>
<p>So, background: when I did this first implementation in September of ‘09, I wanted to see how quickly I could adapt existing .NET libraries for the desktop to work with Silverlight. I was really happy to find that it was simple, taking an existing .NET library for generating <a href="http://en.wikipedia.org/wiki/QR_Code">2D QR barcodes</a> and doing some <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap(VS.95).aspx">WriteableBitmap</a> work.</p>
<p>This really demonstrates how awesome the app platform for the Windows Phone can be – building on top of not only existing Silverlight knowledge, code, and libraries – but also full-fledged .NET libraries.</p>
<p>Here’s the app, and you’ll even see on the design surface that the barcode is showing up in real-time:</p>
<p><a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/03/BarcodeInVs.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="BarcodeInVs" border="0" alt="BarcodeInVs" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/03/BarcodeInVs_thumb.png" width="685" height="600" /></a> </p>
<p>I expose the barcode through a simple control. Here’s the XAML that binds the barcode’s encoded text to the text box’s text – yes, you can type on the phone in real-time and watch the barcode update:</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:63d8c26a-a66c-47f6-b38c-810a423bf6b4" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;barcode:QuickReadBarcode
    Width="100"
    Background="White"
    Text="{Binding Path=Text, ElementName=dataText}" /&gt;</pre>
</div>
<h4>Download the source to this Windows Phone app</h4>
<p><a href="http://media.jeff.wilcox.name/blog/barcode/JeffWilcox.WindowsPhone.Barcode.zip">JeffWilcox.WindowsPhone.Barcode.zip</a> [Zip, 1.12 MB]</p>
<p>Requires the Windows Phone development tools CTP (<a href="http://www.silverlight.net/getstarted/devices/windows-phone/">info</a>)</p>
<p>Hope this helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/03/windowsphone-barcode/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Data binding user settings in Windows Phone applications</title>
		<link>http://www.jeff.wilcox.name/2010/03/data-binding-user-settings-in-windows-phone-applications/</link>
		<comments>http://www.jeff.wilcox.name/2010/03/data-binding-user-settings-in-windows-phone-applications/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 01:02:23 +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/03/data-binding-user-settings-in-windows-phone-applications/</guid>
		<description><![CDATA[Thanks to the rich data binding system built into Silverlight for Windows Phone, you can easily store rich user settings without using code behind files. The canonical example of user settings is a “Show this welcome screen at startup” checkbox so that your application can offer a nice out-of-box experience. By writing a simple type [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to the rich data binding system built into <a href="http://www.silverlight.net/getstarted/devices/windows-phone/">Silverlight for Windows Phone</a>, you can easily store rich user settings without using code behind files.</p>
<p><a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/03/StartupPage1.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="StartupPage" border="0" alt="StartupPage" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/03/StartupPage_thumb1.png" width="301" height="589" /></a> </p>
<p>The canonical example of user settings is a “Show this welcome screen at startup” checkbox so that your application can offer a nice out-of-box experience.</p>
<p>By writing a simple type with some properties, adding a few helper files, and setting up a two-way data binding, you can store any settings without having to write special code.</p>
<p>Here’s what the completed project’s two-way data binding looks like for the checkbox shown to the right:</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:31a809df-3c54-45c6-9f71-e3939f303551" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;CheckBox
   IsChecked="{Binding Source={StaticResource MySettings}, Path=IsFirstRun, Mode=TwoWay}"
   Content="Show this page at startup"
/&gt;</pre>
</div>
<p>You’ll see these components in the data binding:</p>
<ul>
<li>Source is a static resource, a strongly typed settings class you define</li>
<li>Path points to the property name to bind to</li>
<li>Binding is two-way so that the value is stored automatically</li>
<li>Value and type converters can be applied as always in bindings if necessary</li>
</ul>
<p>Let’s quickly implement this functionality in a quick app. We’ll also add a text box to the main application page, to let the value always be persisted between application runs, and even application updates.</p>
<h3>Getting started</h3>
<p>You can use the free <a href="http://www.silverlight.net/getstarted/devices/windows-phone/">Windows Phone development tools</a>, or just Visual Studio 2010 if you have the phone tools CTP installed already.</p>
<p>Create a new ‘Silverlight for Windows Phone’ application project.</p>
<h3>Adding some helper code</h3>
<p>Either add the class library project I have for download here, or just add the 4 C# files that make up the helper code:</p>
<ul>
<li><a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/03/SettingsHelperCode.zip"><strong>SettingsHelperCode.zip</strong></a> (8 KB, zip)</li>
</ul>
<h3>Creating your configuration/settings type</h3>
<p>Next, we need to create a strongly typed configuration class that derives from my SettingsProvider type. This class must:</p>
<ul>
<li>Implement INotifyPropertyChanged, so that bindings work well</li>
<li>Have properties of the appropriate type for the settings you are interested in. Optionally, include the DefaultValue attribute to provide defaults.</li>
</ul>
<p>Here is the MySettings.cs file I’ve created for this app. It defines two properties that I always want to have stored:</p>
<ul>
<li><strong>HelloWorld</strong> is just some text I let the user edit in the user interface. A more realistic setting might be “best friend” or a list of people to show on the home screen of the app.</li>
<li><strong>IsFirstRun</strong> is a true/false value that indicates whether the welcome screen should be shown.</li>
</ul>
<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:f4b3a428-cf5a-4044-bad1-2a305d70a31b" 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;
using JeffWilcox.Settings;

namespace Sample
{
    /// &lt;summary&gt;
    /// My settings class for storing application data and setting specific to
    /// the user.
    /// &lt;/summary&gt;
    public class MySettings : SettingsProvider
    {
        private bool _isFirstRun;
        private string _hello;

        public MySettings() : base("MySettings.xml") { }

        [DefaultValue("What's up?")]
        public string HelloWorld
        {
            get { return _hello; }
            set
            {
                _hello = value;
                NotifyPropertyChanged("HelloWorld");
            }
        }

        [DefaultValue(true)]
        public bool IsFirstRun
        {
            get { return _isFirstRun; }
            set
            {
                bool old = _isFirstRun;
                _isFirstRun = value;
                if (value != old)
                {
                    NotifyPropertyChanged("IsFirstRun");
                }
            }
        }
    }
}</pre>
</div>
<p>Looking closer, inside the MySettings file:</p>
<ul>
<li>MySettings type derives from SettingsProvider, part of the helper code downloaded above.</li>
<li>The constructor calls the base class’s constructor with the name of a settings file to use within the isolated storage area for the phone application</li>
<li>Properties have backing fields and fire change notifications</li>
<li>Default values</li>
</ul>
<h3>Add the settings object to your App.xaml</h3>
<p>Now, open up App.xaml. Add an XMLNS prefix declaration for your project. I named my app project “Sample”, so it’s short:</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:acd9bf42-6d28-4915-bf66-d21d8e7c8936" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">xmlns:local="clr-namespace:Sample"</pre>
</div>
<p>And then add your settings object to the resources (I’m omitting all the theme resources in App.xaml to make it clear where this goes only).</p>
<p><strong>AlwaysSaveOnChange</strong> needs to be set to true for Windows Phone applications: if you’re building a regular Silverlight app, the Application.Exit event works well and can be used to store. But on the phone, since an app may be in a paused or unknown state, this property tells my helper code to save the settings <em>whenever</em> a binding has a change notification. For performance impact should be minimal.</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:13458972-7b46-4eb1-bc09-09a5287a27df" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;Application.Resources&gt;
        &lt;!-- Settings --&gt;
        &lt;local:MySettings x:Key="MySettings" AlwaysSaveOnChange="True" /&gt;
&lt;/Application.Resources&gt;</pre>
</div>
<h3>A simple TextBox binding</h3>
<p>Now on my MainPage.xaml, I am just going to bind to the Hello World property from the MySettings type. Any time you type characters into the text box, they will be saved, and always there when you run the app. No need to write code to save or read settings.</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:30433b15-c4bf-475a-8a49-59b91a731f58" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;TextBox
    Text="{Binding Source={StaticResource MySettings}, Path=HelloWorld, Mode=TwoWay}" /&gt;
</pre>
</div>
<h3>Good to go</h3>
<p>To pull it in, I’m going to add a page called FirstRun.xaml to the project. This will be the content that I want first-time users to see. Then, I need to add the code to call this from main page at startup:</p>
<p>I define a loaded event for this that checks whether the current instance has run the page yet (hacky, and not a permanent setting), and then checks whether the user wants to see the screen (which defaults to true in my settings file):</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:3ec0659d-8aee-41bc-b130-2bd8f24eca37" class="wlWriterEditableSmartContent">
<pre class="csharp" name="code">if (!((App)App.Current).HasFirstRunCheckHappenedYet)
{
    ((App)App.Current).HasFirstRunCheckHappenedYet = true;

    MySettings settings = (MySettings)App.Current.Resources["MySettings"];
    if (settings != null &#038;&#038; settings.IsFirstRun)
    {
        NavigationService.Navigate(new Uri("/FirstRun.xaml", UriKind.Relative));
    }
}</pre>
</div>
<p>It then uses the navigation service to navigate, if needed.</p>
<p>If you’d like to learn more about Silverlight data binding, do check out this MSDN resource: <a title="http://msdn.microsoft.com/en-us/library/cc278072(VS.95).aspx" href="http://msdn.microsoft.com/en-us/library/cc278072(VS.95).aspx">http://msdn.microsoft.com/en-us/library/cc278072(VS.95).aspx</a></p>
<p>Some people have experimented with directly binding to the isolated storage settings file, but this approach gives your some separation – by having your own class, you can provide default values, even upgrade logic, and do some neat work.</p>
<p>This is based on a classic WPF post by <a href="http://blogs.msdn.com/patrickdanino/archive/2008/07/23/user-settings-in-wpf.aspx">Patrick Danino</a> which used the full .NET configuration classes. Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/03/data-binding-user-settings-in-windows-phone-applications/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Silverlight Toolkit and the Windows Phone: WrapPanel, and a few others</title>
		<link>http://www.jeff.wilcox.name/2010/03/toolkit-and-the-windows-phone/</link>
		<comments>http://www.jeff.wilcox.name/2010/03/toolkit-and-the-windows-phone/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 20:27:34 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Silverlight Toolkit]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/03/toolkit-and-the-windows-phone/</guid>
		<description><![CDATA[Are you looking for WrapPanel for your Windows Phone application? Look no further. The Silverlight Toolkit has several controls that work pretty well on the Windows Phone. I wanted to provide my own informal look at how it’s working with Silverlight for Windows Phone today. Note that this information is only current as of today, [...]]]></description>
			<content:encoded><![CDATA[<p>Are you looking for WrapPanel for your Windows Phone application? Look no further. The Silverlight Toolkit has several controls that work pretty well on the Windows Phone.</p>
<p><a href="http://silverlight.codeplex.com/"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="WrapPanel" border="0" alt="WrapPanel" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/03/WrapPanel.png" width="454" height="338" /></a> </p>
<p>I wanted to provide my own informal look at how it’s working with Silverlight for Windows Phone today.</p>
<p>Note that this information is only current as of today, 3/21, when used with the MIX-related CTP of the tools and emulator, and the November 2009 Silverlight Toolkit. A lot could change, and this is <strong>not exhaustive</strong>.</p>
<p>I’m also including some controls that are found in the Silverlight SDK today. I present these in order of how much I have used the components while building apps.</p>
<h3>WrapPanel and DockPanel</h3>
<p>Found in the Silverlight Toolkit, System.Windows.Controls.Toolkit.dll (SWC.Toolkit).</p>
<p>Work great.</p>
<p>If you just need the WrapPanel, and don’t want to include the entire toolkit assembly, you can just paste these source files into your application project instead (license: <a href="http://opensource.org/licenses/ms-pl.html">Ms-PL</a>):</p>
<ul>
<li><a href="http://silverlight.codeplex.com/sourcecontrol/network/Show?projectName=Silverlight&amp;changeSetId=35261#636618">OrientedSize.cs</a></li>
<li><a href="http://silverlight.codeplex.com/sourcecontrol/network/Show?projectName=Silverlight&amp;changeSetId=35261#638862">WrapPanel.cs</a></li>
</ul>
<h3>Charting and Data Visualization</h3>
<p>There is a known issue with LINQ that prevents the controls today from working perfectly. A small, targeted fix has been made in the charting codebase and a future release will work well on the device.</p>
<p>Re-templating and styling the control is very important, and required, for working on the phone in an acceptable manner. I hope to share any decent templates I can come up with.</p>
<h3>HeaderedItemsControl, HeaderedContentControl</h3>
<p>Work great. Split between System.Windows.Controls (SWC) and SWC.Toolkit.</p>
<h3>TreeView</h3>
<p>SWC. Functional; requires massive re-templating and styling. Font sizes are much too small, and the theme and visuals do not appear code-name “Metro” compatible.</p>
<h3>AutoCompleteBox</h3>
<p>Found in the System.Windows.Controls.Input SDK library of the Silverlight 3 SDK.</p>
<p>Works OK, not ready for general development use.</p>
<p>Drop-down appears well. Major features all work. However, touching an entry in the drop down only performs selection. A second touch is required to verify the choice, effectively requiring a double-tap in use.</p>
<h3>Calendar, DatePicker</h3>
<p>SWC. Limited functionality, too small visually. Not designed for touch – not enough space to reliably click on a date. Require massive re-templating. Do not resemble the same experience as the date picker built into the Windows Phone operating system.</p>
<h3>GridSplitter</h3>
<p>Works, but may pose difficult to use on a device: requires much larger padding and custom templates to make the touch area visible and useful.</p>
<h3>Not yet checked</h3>
<p>DataGrid, DataPager, ChildWindow, Label, NumericUpDown, DomainUpDown, DataForm, Rating, TimePicker, TimeUpDown, GlobalCalendar, TransitioningContentControl, TreeMap, BusyIndicator, Viewbox, Expander, Accordion, drag and drop features, and many more.</p>
<p>We’re also still developing a story for the toolkit’s phone story moving forward. As there is a lot of momentum around the phone in the company, it’s very likely that some set of phone tools, samples, and toolkits come out.</p>
<p>Hope this helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/03/toolkit-and-the-windows-phone/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Unit Testing Silverlight &amp; Windows Phone Applications &#8211; talk now online</title>
		<link>http://www.jeff.wilcox.name/2010/03/mix10-testing-talk-online/</link>
		<comments>http://www.jeff.wilcox.name/2010/03/mix10-testing-talk-online/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 22:07:26 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[MIX]]></category>
		<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/03/mix10-testing-talk-online/</guid>
		<description><![CDATA[My MIX 10 talk, an introduction to unit testing on Silverlight and the Windows Phone, is now online for streaming and download. Thank you to everyone who attended. An early preview set of bits are online at http://jeffatmix.com/ – and the next release of the Silverlight Toolkit when Silverlight 4 ships will contain support for [...]]]></description>
			<content:encoded><![CDATA[<p>My <a href="http://live.visitmix.com/MIX10/Sessions/CL59">MIX 10 talk</a>, an introduction to unit testing on Silverlight and the Windows Phone, <a href="http://live.visitmix.com/MIX10/Sessions/CL59">is now online</a> for streaming and download. Thank you to everyone who attended.</p>
<p>An early preview set of bits are online at <a href="http://jeffatmix.com/">http://jeffatmix.com/</a> – and the next release of the Silverlight Toolkit when Silverlight 4 ships will contain support for the phone officially. Stay tuned for more.</p>
<p><a href="http://www.jeff.wilcox.name/2010/03/mix10-testing-talk-online/"><img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="SilverlightUnitTestFrameworkforWindowsPhone[1]" border="0" alt="SilverlightUnitTestFrameworkforWindowsPhone[1]" src="http://www.jeff.wilcox.name/wp-content/uploads/2010/03/SilverlightUnitTestFrameworkforWindowsPhone1_thumb.jpg" width="360" height="480" /></a> </p>
<p>Over the next few weeks, I’ll be blogging plenty on these subjects.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/03/mix10-testing-talk-online/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
