<?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; C#</title>
	<atom:link href="http://www.jeff.wilcox.name/topics/dev/csharp/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, 01 Feb 2012 14:42:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Displaying static maps on the Windows Phone for performance and scenario wins</title>
		<link>http://www.jeff.wilcox.name/2012/01/jeffwilcox-maps/</link>
		<comments>http://www.jeff.wilcox.name/2012/01/jeffwilcox-maps/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 00:36:45 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Control Development]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/?p=903</guid>
		<description><![CDATA[One of the nice visuals of 4th &#38; Mayor is the animation and display of a simple area map whenever you view a place in the app. Unfortunately, most map controls, such as the Bing Maps control included with the platform, are highly sophisticated: they let you have a bunch of pushpins, gather information about [...]]]></description>
			<content:encoded><![CDATA[<p>One of the nice visuals of 4th &amp; Mayor is the animation and display of a simple area map whenever you view a place in the app.</p>
<p>Unfortunately, most map controls, such as the Bing Maps control included with the platform, are highly sophisticated: they let you have a bunch of pushpins, gather information about bounding boxes, etc. This awesome feature set can have a negative effect on performance.</p>
<blockquote><p>2/1/2012 Update: Thanks to <a href="http://timheuer.com/blog/">Tim Heuer</a>, who just provided a pull request that adds an OpenStreetMap provider, MapQuest provider, offers the ability to add an authentication key optionally as a property on the control, and to specify the type of maps. I’ve updated NuGet to 1.1 with these contributions, thanks!</p>
</blockquote>
<p>My static map control is simple but nice because it’s an easy replacement, can be used in Panorama/Pivots, and overall still has a great, high-speed experience that your users will enjoy.</p>
<p><a href="http://www.jeff.wilcox.name/wp-content/uploads/2012/01/SampleMap.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="SampleMap" border="0" alt="SampleMap" src="http://www.jeff.wilcox.name/wp-content/uploads/2012/01/SampleMap_thumb.png" width="341" height="346" /></a>     <br /><em>A sample static Bing Map from 4th &amp; Mayor: touching the map takes you to an interactive map view page allow for directions, panning, etc.</em></p>
<h3>“JeffWilcox.Maps” Component</h3>
<p>I’ve refactored one of the libraries used in my app to be general enough for others to use: it offers simple static map code in the form of a “StaticMap” control: just drop it into your XAML page and you’re mostly good to go.</p>
<p>The <strong>MapCenter</strong> property takes a GeoCoordinate, either data bind it or set the property as the page is navigated to.</p>
<p>Over time I’ll consider adding more of the functionality I’ve had to the library, including the interactive libraries.</p>
<h3>Get the library</h3>
<p>I’m using my favorite pair of deployment places for this library: GitHub for source, NuGet for binaries.</p>
<h4>NuGet</h4>
<p>The library is <a href="http://nuget.org/packages/JeffWilcox.Maps">JeffWilcox.Maps</a></p>
<h4>Source on GitHub</h4>
<p>Fork the repo, <a href="https://github.com/jeffwilcox/wp-maps">wp-maps</a></p>
<h3>Offering an interactive experience</h3>
<p>To optimize the maps experience, I instead decided to use the static map REST APIs from Bing Maps for my mobile application: this lets me perform a HTTP request, grab the image, and data bind it into my display.</p>
<p>I then place it inside a borderless, retemplated Button control, so that touching the map takes you to a new page: an experience where I can show the real Bing Maps control, your current position, as well as the location of the place you are trying to go. By moving this to a separate assembly, I get great performance wins: the Bing Maps control and other code needed to offer the rich interactive experience is delay loaded and only there when needed.</p>
<h3>Properties on the control</h3>
<p>These properties are on the initial version of the control:</p>
<p><strong>Foreground</strong> is supported and used for the implicit, centered point: it’s Black by default to match the Windows Phone’s “Maps” app, but I find that using {StaticResource PhoneAccentBrush} looks great in my opinion.</p>
<p><strong>MapCenter</strong> takes a GeoCoordinate, this is a key property.</p>
<p><strong>ZoomLevel</strong> sets the zoom level (default of 15 I think) for the map. 1 effectively shows a bunch of the world, and 21 shows street level sizes. The zoom levels for Goog and Bing are pretty similar.</p>
<p><strong>MapCenterVisibility</strong> defaults to Visible, and if you decide you don’t want the center point to be on the view, just set this to Collapsed.</p>
<p><strong>IsSensorCoordinate</strong> should be data bound, some APIs (like Google’s) require that the API call identify whether it’s a position from a sensor, or a database. In my case, sensor is used for any GeoCoordinateWatcher/LocationService code, while I set it to False for data from the Foursquare venues database where I get info about a place.</p>
<p><strong>Provider</strong> sets the static map provider to use.</p>
<p>The height and width are automatically identified by the system, but many APIs limit the width and height to small numbers (typically &lt;= 640 pixels in any direction), FYI.</p>
<h3>Bing Maps API Key</h3>
<p>If you’re using Bing Maps, you’ll need a <a href="http://www.microsoft.com/maps/developers/web.aspx">Bing Maps API key</a> and to make sure that your app is compliant with the requirements of its terms and conditions. This is the same key you use with the Bing Maps control.</p>
<p>For this first version you have to set the API key as a string resource inside your App.xaml file.</p>
<p>Here’s how you would go about this: add the namespace and set the string – I’ve put a comment where your key should go in App.xaml:</p>
<pre class="xml" name="code">&lt;Application
    x:Class=&quot;StaticMapSample.App&quot;
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:phone=&quot;clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone&quot;
    xmlns:shell=&quot;clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone&quot;
    xmlns:core=&quot;clr-namespace:System;assembly=mscorlib&quot;&gt;

    &lt;!--Application Resources--&gt;
    &lt;Application.Resources&gt;
        &lt;core:String x:Key=&quot;BingMapsKey&quot;&gt;&lt;!-- Place your Bing Maps API key here--&gt;&lt;/core:String&gt;
    &lt;/Application.Resources&gt;

    &lt;Application.ApplicationLifetimeObjects&gt;
        &lt;!--Required object that handles lifetime events for the application--&gt;
        &lt;shell:PhoneApplicationService
            Launching=&quot;Application_Launching&quot; Closing=&quot;Application_Closing&quot;
            Activated=&quot;Application_Activated&quot; Deactivated=&quot;Application_Deactivated&quot;/&gt;
    &lt;/Application.ApplicationLifetimeObjects&gt;

&lt;/Application&gt;</pre>
<p>I haven’t decided if this is better or worse than just exposing an API key property for you to bind or set on the page, but I really like just having one central place in an app to put the key.</p>
<h3>Static map providers</h3>
<p>The initial implementation has a simple enum for chosing between two provider choices, Bing Maps and Google Maps. I’ve decided to include Google Maps because it turns out that in some parts of the world, Google Maps are much better, and I’ve had hundreds of app users ask for a setting to instead use Google Maps. There are slightly different requirements for its API, such as exposing an “open in web browser” function so that the user could decide to open the same map view in the browser on the phone.</p>
<p>Just set the <strong>Provider</strong> property on the StaticMap to either Bing or Google. The default is Bing, as it should be!</p>
<p>Here’s a screenshot of the sample app I’ve included in the GitHub repo (though if you use it, remember to put your Bing Maps API key inside of the App.xaml file first!) – it has both Bing and Google Maps, and the application bar is hooked up to events to open the Maps app on the phone <em>or</em> to open the browser with the appropriate map page. Take a look.</p>
<p><a href="http://www.jeff.wilcox.name/wp-content/uploads/2012/01/SampleApp.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="SampleApp" border="0" alt="SampleApp" src="http://www.jeff.wilcox.name/wp-content/uploads/2012/01/SampleApp_thumb.png" width="680" height="567" /></a></p>
<p><em>On the right, the expanded app bar: your app may need to expose the “open in browser” option to comply with the terms and conditions that you interpret on the maps API of your choice. Also, the “open in maps app” is a nice function to provide users who want to open the location in the main OS’s Maps app.</em></p>
<h3>Design note: flush maps</h3>
<p>One design technique that I use in my app, as does the “Local Scout” app in Mango, is having a “flush” map experience: the map extends to the edge of the phone, instead of the standard spacing with margins from the edges of the phone.</p>
<p>This visual effect looks great, and can in general be created by setting the Margin of the control to “-12,0,-12,0”.</p>
<p>Hope this helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2012/01/jeffwilcox-maps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PhoneThemeManager: allow your app to have the Light, Dark, or Inverted theme with 1 line of code</title>
		<link>http://www.jeff.wilcox.name/2012/01/phonethememanager/</link>
		<comments>http://www.jeff.wilcox.name/2012/01/phonethememanager/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 03:43:08 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/?p=890</guid>
		<description><![CDATA[Set your Windows Phone Mango app to have the Light, Dark, or inverted theme with just one line of code and this helper library, PhoneThemeManager.]]></description>
			<content:encoded><![CDATA[<p>I’ve just pushed a small library that I created this evening to the world and wanted to share details on the short project in this post. (<a href="http://nuget.org/packages/PhoneThemeManager">NuGet assembly</a>, <a href="http://nuget.org/packages/PhoneThemeManager.Source">NuGet source</a>, <a href="https://github.com/jeffwilcox/wp-thememanager">project on GitHub</a>)</p>
<p>One of the most common feature requests that I receive for 4th &amp; Mayor is a setting in the app to force it to always use the “Light” theme, overriding the dark/light theme that the user’s set for their theme.</p>
<p>Having a light background is a nice contrasting design look for the phone, and the Mail application always does this. I personally always submit mostly light theme screen shots for my applications to the Windows Phone Marketplace, it just looks better and nice to me – but I rarely use all-light themed apps other than Mail.</p>
<p><img src="http://d2bk44826ux9xe.cloudfront.net/NewMenus.png" /></p>
<p>In preparing for the next update of my app, v3.3, I’ve coded up this capability and I’m sharing it ahead of time.</p>
<h3>Technical Overview</h3>
<p>In 7.0 there were a few ways to do theme overriding, sometimes through a few silly platform bugs that we left in there – but it’s actually not an easy thing to do, and many people end up overriding every single style in their app to get the effect that they are going for.</p>
<p>This helper library is designed for altering the entire application’s running instance, <em>not</em> for providing per-page theme overriding.</p>
<p>In researching possible ways to solve this, I did come across <a href="http://windowsphonegeek.com/articles/Windows-Phone-Mango-Custom-application-Theme-Step-by-Step">this page on windowsphonegeek</a> that talks about ways to merge in styles or to programmatically override resources that are brushes.</p>
<p>I decided to create a system to walk through the known values and names for all the core theme resources of colors, brushes, plus the light/dark theme visibility and opacity properties.</p>
<p>In your app, you simply call `ThemeManager.ToLightTheme()`, `ThemeManager.ToDarkTheme()`, `ThemeManager.InvertTheme`, to force this. You need to have this call happen inside your <strong>App.xaml.cs </strong>file, in the constructor, after the Initialize calls.</p>
<p>You cannot change or call this more than once, so if you offer a setting for users to “Force Light”, use a MessageBox to inform them that their setting will be used the next time they start the app. You will have to read their setting right away when they start up the app. Once styles start applying the values, you could start to get inconsistent results.</p>
<p>The code walks and updates the Color instances, then walks the Brush resources and sets their Colors to be the original Color instances, just in case.</p>
<p>I have placed the ThemeManager class within the Microsoft.Phone.Controls namespace for this to be easy to add to your App.xaml.cs file.</p>
<p>You should have an App constructor like this:</p>
<pre class="csharp" name="code">/// &lt;summary&gt;
/// Constructor for the Application object.
/// &lt;/summary&gt;
public App()
{
    // Global handler for uncaught exceptions.
    UnhandledException += Application_UnhandledException;

    // Standard Silverlight initialization
    InitializeComponent();

    // Phone-specific initialization
    InitializePhoneApplication();

    ThemeManager.ToLightTheme();

    // Other code that might be here already...
}</pre>
<h3>What’s themed</h3>
<p>By default this is what happens:</p>
<ul>
<li>The <strong>resources</strong> for foreground, background, all the contrast/chrome/etc. colors and brushes are updated</li>
<li>The light and dark theme visibility and opacity resources are updated</li>
<li>The background brush of the Frame is set explicitly to the color (may have a negative performance impact!)</li>
<li>The <strong>System Tray </strong>whenever a page navigation completes</li>
<li>The <strong>ApplicationBar</strong> of a page if set immediately</li>
</ul>
<p>I’ve added a simple OverrideOptions enum (static) to the ThemeManager that can be used to disable the auto-behaviors I’ve added.</p>
<h4>Newing up AppBars</h4>
<p>If you have code in your app like “var ab = new ApplicationBar”, beware that that application bar will take on the system’s actual theme colors by default, and not the overridden light/dark coloring that happens with the app.</p>
<p>If you need to new up an ApplicationBar, you should use the convenience method of `ThemeManager.CreateApplicationBar()` <em>or</em> use the extension method on app bar that I added, `MatchOverriddenTheme`, to set the color values.</p>
<h3>What’s not themed</h3>
<p>Unfortunately this cannot theme <strong>MessageBox</strong> at all.</p>
<h3>Talking about fill rate performance</h3>
<p>I’ve designed the system so that resources are <em>only overridden when needed</em>.</p>
<p>If your app uses ToLightTheme to force the light theme, and the user is running the Light theme already, nothing happens – it’s a no-op.</p>
<p>Although updating resources has no negative effect really on the app’s performance, the trouble is setting the Background color of the phone application’s frame.</p>
<p>The frame is always present and may add a fill count of 1.0 to every single page in your app.</p>
<p>Anything above a fill rate of 2-3 is not a good thing, so you may notice a degraded experience. Might want to inform your users of that when providing the option to force the light theme, for example.</p>
<h3>A note about your battery</h3>
<p>Many Windows Phones use AMOLED or similar technology where bright colors, such as the background color used in the Light theme, will use a lot of power. Please respect your users and realize that long-running apps probably should not force the Light option.</p>
<p>Consider only making such a “Force Light Theme” option as a setting that users opt-in to, as opposed to always overriding the theme.</p>
<h3>About custom themes</h3>
<p>When I designed this library, I thought about offering a ton of capability in it for using “branding” colors, modifying the accent brush, etc., but instead decided to tackle just one thing. So the name ThemeManager is a little overkill maybe, but it’s where we are for now.</p>
<h2>Get the bits</h2>
<p><strong>NuGet Binary</strong></p>
<p>The binary is super easy to use. With NuGet just add the <a href="http://nuget.org/packages/PhoneThemeManager">PhoneThemeManager</a> package reference.</p>
<p><strong>NuGet Source File</strong></p>
<p>Instead of adding yet another assembly to your project, just add the single source file (or add it to your existing shared library, etc.) by using the <a href="http://nuget.org/packages/PhoneThemeManager.Source">PhoneThemeManager.Source</a> package.</p>
<p><strong>GitHub Repo</strong></p>
<p>Fork and enjoy <a href="https://github.com/jeffwilcox/wp-thememanager">https://github.com/jeffwilcox/wp-thememanager</a></p>
<p>Hope this helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2012/01/phonethememanager/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Please ship your next Windows Phone app with GZip: speed requests 50-80%</title>
		<link>http://www.jeff.wilcox.name/2012/01/windows-phone-gzip-support-by-morten/</link>
		<comments>http://www.jeff.wilcox.name/2012/01/windows-phone-gzip-support-by-morten/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 01:04:23 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/?p=887</guid>
		<description><![CDATA[Please ship your next Windows Phone app or app update using this awesome GZipWebClient library by Morten Nielsen (NuGet, blog post, source) – it’s been out there since August and we should all be using this now for HTTP-heavy apps! The next update of my app is in the works and performance is significantly improved [...]]]></description>
			<content:encoded><![CDATA[<p>Please ship your next Windows Phone app or app update using this awesome GZipWebClient library by Morten Nielsen (<a href="http://nuget.org/packages/SharpGIS.GZipWebClient">NuGet</a>, <a href="http://www.sharpgis.net/post/2011/08/28/GZIP-Compressed-Web-Requests-in-WP7-Take-2.aspx">blog post</a>, <a href="http://www.sharpgis.net/www.sharpgis.net/file.axd?file=2011%2f8%2fSharpGIS.GZipWebClient.zip">source</a>) – it’s been out there since August and we should all be using this now for HTTP-heavy apps!</p>
<p>The next update of my app is in the works and performance is significantly improved by this library. I used both generation 1 and gen 2 devices to gather a ton of data and am loving the results. Can’t wait to submit the update to the marketplace. I’ve been seeing requests speed up 50%-80%, it’s amazing – but I should note, these are unofficial numbers, I’m just grabbing these from my app that is JSON-heavy.</p>
<p><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="GZipChart" border="0" alt="GZipChart" src="http://www.jeff.wilcox.name/wp-content/uploads/2012/01/GZipChart.png" width="680" height="310" /></p>
<p><em>Some sample data: a large set of averaged requests of a very large JSON request to the Foursquare web services used in my app, 4th &amp; Mayor for Windows Phone 7.5.</em></p>
<p>These numbers aren’t official or anything like that, just what I was observing using my 3G data connection here in Seattle or home WiFi. Also interesting are the fastest times for the content – I often found that once a data connection was open, I would get as low as 100ms for some GZip requests. Just amazing.</p>
<p>One of the awesome modern web server features that nearly every browser happily supports today is <a href="http://en.wikipedia.org/wiki/Gzip">Gzip</a> compression of its output. Text and JSON beautifully compress, often by more than half, resulting in quick content downloads. It’s a simple and awesome way to improve the performance and responsiveness of your applications.</p>
<p>This isn’t a new technology, but unfortunately it isn’t just a default, built-in option for you to use in your Windows Phone apps, and you can expect that competing apps on other platforms (and even on Windows Phone) will be using Gzip to improve the performance. Hopefully we fix this in the future.</p>
<p>Frankly it isn’t a default in most mobile platforms, either, and you need to opt-in. However, some, like iOS, seem to automatically deflate incoming streams as long as you opt-in by setting the content encoding headers; in an iOS app, you just addValue “gzip” forHTTPHeaderField before your request and you’re good from there. Android is similar but you do need to check for gzip in responses and manually new up a deflating stream with GZipInputStream.</p>
<h3>HTTP Gzip and Windows Phone apps</h3>
<p>So Morten Nielsen created a wrapping WebClient library over 6 months ago and through a few iterations has made it great.</p>
<p>So now it’s super easy to get this perf win. To make this work:</p>
<ul>
<li>Add the library to your project via <a href="http://nuget.org/packages/SharpGIS.GZipWebClient">NuGet</a> [SharpGIS.GZipWebClient]</li>
<li>Replace your WebClient code to use GZipWebClient instead – yes, just rename! (GZipWebClient is in Morten’s `SharpGIS` namespace)</li>
<li>Test and ship your app!</li>
</ul>
<p>Now I’m not considering the server-side, but if you’re rolling your own web services, you might need to do some work to make sure that you’ll serve GZip content when the capability is ready on the client. Check with the documentation for your server-side app platform, cloud provider or web server technology.</p>
<p>I can totally see myself adding this to my core libraries for all future projects. Hope this helps. <strong>Thanks Morten for providing this to the community!</strong> You can follow Morten on Twitter (<a href="https://twitter.com/#!/dotMorten">@dotMorten</a>) or check out his blog (<a href="http://www.sharpgis.net/">http://www.sharpgis.net/</a>).</p>
<p>(And on the performance side: the smaller payload means networking rocks and is fast; it is worth noting that GZip adds a small amount of CPU load – hopefully in your background thread – but I haven’t detected anything negative from this yet)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2012/01/windows-phone-gzip-support-by-morten/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>A simple Windows Phone control for reading QR codes</title>
		<link>http://www.jeff.wilcox.name/2012/01/wpqr-control/</link>
		<comments>http://www.jeff.wilcox.name/2012/01/wpqr-control/#comments</comments>
		<pubDate>Sun, 15 Jan 2012 00:05:09 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Control Development]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2012/01/wpqr-control/</guid>
		<description><![CDATA[A Windows Phone visual control that uses the camera to read a QR code.]]></description>
			<content:encoded><![CDATA[<p>There are great libraries out there written or ported to C# that let us developers rock by standing on the shoulders of giants. Here’s one such project.</p>
<p>A phone developer who’s also an enthusiast of foursquare suggested a feature that I should add in a future release, and provided some sample code based on the <a href="http://code.google.com/p/zxing/">zxing barcode library</a> and the <a href="http://silverlightzxing.codeplex.com/">Silverlight port of it</a>. I’m working on adding the new feature soon.</p>
<p>In the process I realized it would be a good and quick opportunity to ship such a simple but useful control to the phone development community, so I’ve gone ahead and pushed that control refactoring and implementation to GitHub, check it out: <a href="https://github.com/jeffwilcox/wpqr-control">https://github.com/jeffwilcox/wpqr-control</a>&#160;</p>
<p>Special thanks to Michael Osthege (<a href="http://twitter.com/theCake">@theCake</a>, <a href="http://kuchenzeit.wordpress.com/">blog</a>) for providing the initial contact, sample, and encouragement.</p>
<p>The control is nice:</p>
<ul>
<li>Drop it on the design surface</li>
<li>Wire up the ScanComplete event (and optionally the Error event)</li>
<li>The control handles all the underlying image manipulation, scanning work, PhotoCamera initialization, etc.</li>
</ul>
<p>Here’s what a simple sample app looks like in use. The control includes default border thickness and coloring properties that use the accent color and provide a nice visual separator:</p>
<p><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="ReadingQR" border="0" alt="ReadingQR" src="http://www.jeff.wilcox.name/wp-content/uploads/2012/01/ReadingQR.jpg" width="685" height="514" /></p>
<p>Technically the control will expand to its container size, but I prefer the squared-off 400&#215;400 grid myself.</p>
<h3>Building the sample app</h3>
<p>All I did to build this app was drop the control into a new Windows Phone app project and wire it up. Here’s how.</p>
<h4>References and XMLNS</h4>
<p>Add either a project reference (if you cloned the git repo) <em>or</em> build the project and include references to assemblies, both the zxing library plus this control library.</p>
<p>To your XAML page where you’d like to use the control, make sure to include a namespace. Here’s what I used:</p>
<pre><font size="2" face="Consolas">xmlns:jwqr=&quot;clr-namespace:JeffWilcox.Controls;assembly=JeffWilcox.Controls.QR&quot;</font></pre>
<h4>Add the control</h4>
<p>I added this XAML to my MainPage’s ContentPanel area:</p>
<pre class="xml" name="code">&lt;jwqr:QRCodeScanner
    ScanComplete=&quot;QRCodeScanner_ScanComplete&quot;
    Error=&quot;QRCodeScanner_Error&quot;
    Width=&quot;400&quot;
    Height=&quot;400&quot;/&gt;</pre>
<h4>Implement code behind</h4>
<p>The event handlers are easy enough. In my case, I went for these (just throwing exceptions):</p>
<pre class="csharp" name="code">private void QRCodeScanner_ScanComplete(object sender, JeffWilcox.Controls.ScanCompleteEventArgs e)
{
    ApplicationTitle.Text = e.Result;
}

private void QRCodeScanner_Error(object sender, JeffWilcox.Controls.ScanFailureEventArgs e)
{
    throw e.Exception;
}</pre>
<h4>Run the project on a Windows Phone</h4>
<p>Hit F5! When you hover over a QR code, you should see its embedded text appear in place of the application title (top of the page).</p>
<h4>Future/Improvements</h4>
<p>I’d like to maybe add a sound when the scan is successful, but right now, nothing like that.</p>
<p>Eventually I may package this up as a NuGet package, but I’m not ready to prep the right spec files plus figure out how to properly attribute the sub-libraries at this time. So fork the <a href="https://github.com/jeffwilcox/wpqr-control">GitHub</a> version in the meantime! License is Apache 2.0 for both this library as well as the underlying zxing project.</p>
<p>(Looking to display codes? A few years back I briefly talked about the QR code system used by the sweet Starbucks mobile app on the iPhone. I implemented a prototype for Silverlight and Windows Phone that lets you render a QR code on the app’s surface, thanks to a nice QR code library. That <a href="http://www.jeff.wilcox.name/2010/03/windowsphone-barcode/">post is here</a>.)</p>
<p>Hope this helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2012/01/wpqr-control/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>November release of the Silverlight for Windows Phone Toolkit</title>
		<link>http://www.jeff.wilcox.name/2011/11/nov2011phonetoolkit/</link>
		<comments>http://www.jeff.wilcox.name/2011/11/nov2011phonetoolkit/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 23:47:56 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2011/11/nov2011phonetoolkit/</guid>
		<description><![CDATA[Today we pushed the button and published the November 2011 release of the Silverlight for Windows Phone Toolkit. This is a bug-fixing release and addresses a number of important issues as reported by customers on the product’s CodePlex site. For this release the team focused entirely on reported issues, important blockers for people, and we’ve [...]]]></description>
			<content:encoded><![CDATA[<p>Today we pushed the button and published the <a href="http://silverlight.codeplex.com/releases/view/75888">November 2011 release of the Silverlight for Windows Phone Toolkit</a>. This is a bug-fixing release and addresses a number of important issues as reported by customers on the product’s <a href="http://silverlight.codeplex.com/">CodePlex site</a>.</p>
<p>For this release the team focused entirely on reported issues, important blockers for people, and we’ve been sharing updates in near-real-time through the Source Control part of the CodePlex site.</p>
<h3>Download the Nov 2011 release</h3>
<blockquote><p><a href="http://silverlight.codeplex.com/releases/view/75888#DownloadId=304100"><strong>Download the MSI</strong></a>      <br /><a href="http://nuget.org/List/Packages/SilverlightToolkitWP"><strong>Get the package through NuGet</strong></a></p>
<p><a href="http://silverlight.codeplex.com/releases/view/75888#DownloadId=304099">Download the Samples and Source</a>      <br /><a href="http://silverlight.codeplex.com/releases/view/75888">View the release notes and download page</a>      <br /><a href="http://silverlight.codeplex.com/SourceControl/BrowseLatest">Browse the Source on CodePlex</a></p>
</blockquote>
<h3>Changes in this release</h3>
<p>Here is a summary listing of the changes in this release:</p>
<h4>Larger changes</h4>
<ul>
<li>ListPicker once again works in a ScrollViewer</li>
<li>LongListSelector bug fixes around OutOfRange exceptions, wrong ordering of items, grouping issues, and scrolling events. ItemTuple is now refactored to be the public type LongListSelectorItem to provide users better access to the values in selection changed handlers.</li>
<li>PerformanceProgressBar binding fix for IsIndeterminate (item 9767 and others)</li>
<li>There is no longer a GestureListener dependency with the ContextMenu, WrapPanel, and ListPicker</li>
<li>The GestureListener should be considered deprecated for all Windows Phone 7.1 SDK development. There is no direct replacement at this time, though the platform now supports events such as Tap right on visual elements.</li>
</ul>
<h4>Other improvements</h4>
<ul>
<li>Updates the ExpanderView sample so that each individual item has its own tilt effect.</li>
<li>Fixes PhoneTextBox bugs 9342 and 9345</li>
<li>PhoneTextBox hides actionitem when empty</li>
<li>ListPicker can be in horizontally scrollable views.</li>
<li>ListPicker now only supports Tap for activation (before it supported any touch that began in bounds and stayed in bounds)</li>
<li>The LongListSelector&#8217;s Background color now is used for the picker grid to enable better app/brand styling</li>
<li>LongListSelector state name correction</li>
<li>Comments added to clarify that ListPicker does not support UIElements directly by design since the framework only permits one instance of a UI Element in the tree at a time</li>
<li>ExpanderView visual glitch fixed (9525)</li>
<li>Additional null checks in ContextMenu visual state change methods</li>
<li>ListPicker SelectedItems is now settable</li>
<li>Small fixes to ToggleSwitch</li>
<li>A startup crash correction in the gesture listener.</li>
<li>The ExpanderView sample is documented better</li>
<li>LockablePivot&#8217;s IsLocked property is now a dependency property</li>
<li>RelativeTimerConverter fixes a UTC bug and no longer throws on future dates</li>
<li>Fixes some reported issues with VB.NET samples</li>
<li>Fixed a ToggleSwitchButton reanimation issue.</li>
<li>Owner is a public property now on ContextMenu</li>
<li>Handle listpicker selected item with a null items</li>
<li>Fixes sample issues when building.</li>
<li>Fixes build warnings.</li>
</ul>
<p>Hope you enjoy the new release.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2011/11/nov2011phonetoolkit/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>A note about remote URIs in Windows Phone secondary tiles</title>
		<link>http://www.jeff.wilcox.name/2011/09/a-note-about-remote-uris-in-windows-phone-secondary-tiles/</link>
		<comments>http://www.jeff.wilcox.name/2011/09/a-note-about-remote-uris-in-windows-phone-secondary-tiles/#comments</comments>
		<pubDate>Tue, 27 Sep 2011 18:19:38 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/?p=848</guid>
		<description><![CDATA[One of my favorite features in Mango is the ability for developers to let users pin a deep linking secondary tile to their start screen. It’s a simple concept but really opens up a lot of new opportunities for apps-within-an-app, shortcuts to oft-used functionality, plus many other innovations. In 4th &#38; Mayor, I use these [...]]]></description>
			<content:encoded><![CDATA[<p>One of my favorite features in Mango is the ability for developers to let users pin a deep linking secondary tile to their start screen. It’s a simple concept but really opens up a lot of new opportunities for apps-within-an-app, shortcuts to oft-used functionality, plus many other innovations.</p>
<p>In 4th &amp; Mayor, I use these to allow people to pin places to the start, and also to check-in a lot quicker. In my current released version, I actually found out after-the-fact about a remote URI bug, and wanted to share my notes on this.</p>
<p>If you’re looking for the basic reference on this deep-linking feature, do refer to the “<a href="http://msdn.microsoft.com/en-us/library/hh202979(v=VS.92).aspx">Create, Delete, and Update Tiles for Windows Phone</a>” entry on MSDN.</p>
<h3>What’s the issue with remote URIs?</h3>
<p>As best I can tell, the situation is: adding a secondary tile with a relative URI (pointing to an app’s content, such as SomeImage.png, that is packaged within the .Xap) is OK, and that secondary tile will always be present.</p>
<p>However, if you use a remote URI (such as a dynamically generated background image, or from a database or social network), that secondary tile is only present for that current device’s uptime: if you restart the device (or the battery dies, etc.), when you come back, the secondary tiles will no longer be present.</p>
<p>Users should still be able to re-pin any of their favorite secondary tiles to the start screen again. However, it turns out there is a bug here unfortunately: the secondary tile is still present in the ActiveTiles collection, and the OS seems to believe that it is still there, even though it is not.</p>
<p>The workaround is to search for the existing identical secondary tile and delete it, before re-pinning it, in your apps. This does mean that it’s not possible to tell whether a secondary tile with a remote URI is truly pinned or not – it will look pinned in the ActiveTiles collection but the user will not actually have the item pinned.</p>
<h3>Using a remote URI</h3>
<p>If you just use a remote URI (absolute), you will experience one-time pin ability; after that, and a device restart, it won’t be possible to re-pin the same page without first deleting the entry.</p>
<h3>Using a remote URI, working around re-pin issues</h3>
<p>Here is the code I’ve used to workaround these issues, effectively deleting the tile first, and re-pinning, only when using an absolute URI:</p>
<pre class="c-sharp" name="code">private void OnPinButtonPressed(object sender, RoutedEventArgs e)
{
    var backgroundImage = new Uri(&quot;http://tiles.4thandmayor.com/CrownBackground.png&quot;, UriKind.Absolute);

    var tile  = ShellTile.ActiveTiles
        .FirstOrDefault(x =&gt; x.NavigationUri == NavigationService.CurrentSource);

    // Only if this is a remote background image URI do we need to
    // delete and re-pin the secondary tile.
    if (tile != null &amp;&amp; backgroundImage.IsAbsoluteUri)
    {
        tile.Delete();

        var newTile = new StandardTileData
        {
            BackgroundImage = backgroundImage,
            Title = &quot;Secondary Tile&quot;,
        };

        ShellTile.Create(NavigationService.CurrentSource, newTile);
    }
}</pre>
<p><strong>9/29/11 1:40 PM PST note</strong>: It’s been pointed out to me that I don’t know how to code. The code above will re-pin, but not initially pin. A little more boolean logic is needed. I’ll try and update later, but the concept remains.</p>
<p>Hope this helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2011/09/a-note-about-remote-uris-in-windows-phone-secondary-tiles/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Exploring the August 2011 Silverlight for Windows Phone Toolkit for &#8216;Mango&#8217;</title>
		<link>http://www.jeff.wilcox.name/2011/08/august2011phonetoolkit/</link>
		<comments>http://www.jeff.wilcox.name/2011/08/august2011phonetoolkit/#comments</comments>
		<pubDate>Wed, 17 Aug 2011 18:00:36 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Control Development]]></category>
		<category><![CDATA[Silverlight Toolkit]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2011/08/august2011phonetoolkit/</guid>
		<description><![CDATA[We’ve now shipped the August 2011 release of the Silverlight for Windows Phone Toolkit, a key ingredient in preparing a great ‘Mango’ app. There are new controls, many bug fixes, great new localization features, and more in this pack of components. You can download the new release straight from the CodePlex site at http://silverlight.codeplex.com/ &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>We’ve now shipped the August 2011 release of the Silverlight for Windows Phone Toolkit, a key ingredient in preparing a great ‘Mango’ app. There are new controls, many bug fixes, great new localization features, and more in this pack of components.</p>
<hr />
<blockquote>
<p><b>You can download the new release straight from the CodePlex site at <a href="http://silverlight.codeplex.com/">http://silverlight.codeplex.com/</a></b> &#8211; it requires the latest ‘Mango’ developer tools as well.</p>
<p>The release is also available on NuGet as the <a href="http://nuget.org/List/Packages/SilverlightToolkitWP">SilverlightToolkitWP</a> package</p>
</blockquote>
<hr />
<h3><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="SampleProject" border="0" alt="SampleProject" align="right" src="http://www.jeff.wilcox.name/wp-content/uploads/2011/08/SampleProject.png" width="236" height="450" />Check out the sample app</h3>
<p>One of the best ways to learn about the controls is to use the sample app on your Windows Phone. We haven’t published it to the marketplace yet, so in the meantime, just deploy this .XAP to your developer-unlocked Windows Phone (or the Windows Phone Emulator). It should work with the <a href="http://create.msdn.com/en-US/">latest Windows Phone ‘Mango’ developer tools</a>.</p>
<p>We’ve posted the sample <a href="http://silverlight.codeplex.com/releases/view/71550">XAP here</a>.</p>
<p>The app includes a nice list of the controls, touch one to go into a sub-page. The full open source code to the sample is on the CodePlex site at <a href="http://silverlight.codeplex.com/">http://silverlight.codeplex.com/</a></p>
<h3>What’s in the new release?</h3>
<p><strong>LongListSelector</strong> has been rebuilt and redesigned to take advantage of the new smooth scrolling and off-thread touch input support in ‘Mango’. This is a buttery-smooth control for showing lists, including grouping and jump list support.</p>
<p><strong>MultiselectList</strong> control enables multiple selection for easily working with lists of data, similar to the Mail app’s capability.</p>
<p><strong>LockablePivot</strong> adds a special mode to the Pivot control where only the current item is shown (often used with multiple selection).</p>
<p><strong>ExpanderView</strong> is a primitive items control that can be used for expanding and collapsing items (like the threaded views in the Mail app).</p>
<p><strong>HubTile</strong> lets you add beautiful, informative, animated tiles to your application, similar to the new People groups in ‘Mango’.</p>
<p><strong>ContextMenu</strong> control has been reworked: performance improvements and visual consistency fixes.</p>
<p><strong>ListPicker</strong> now supports multiple selection.</p>
<p><strong>RecurringDaysPicker</strong> lets your users select a day of the week.</p>
<p><strong>Date &amp; Time Converters </strong>localized to 22 languages. The converters let developers easily display date and time in the user interface in one of the many styles found throughout the phone’s UI, from a short date like ‘7/19’ to relative times like ‘about a month ago’.</p>
<p><strong>Page Transitions</strong> have improved performance for a more responsive feel.</p>
<p><strong>PhoneTextBox</strong> is an early look at an enhanced text box with action icon support, watermarking, etc.</p>
<p><strong>All error messages and interface elements</strong> have been localized to all of the supported languages, making for a great experience for users around the world.</p>
<h3>Other great components</h3>
<p>If you’re new to the Silverlight for Windows Phone Toolkit, you’re in for a treat as an app developer: the simple developer library also contains these great components designed specifically for the Windows Phone:</p>
<p><strong>AutoCompleteBox</strong> is a text box control that allows for simple auto-completion based on a filter.</p>
<p><strong>DatePicker</strong> lets a user select a date, similar to that found in the Alarms app on the Windows Phone.</p>
<p><strong>PerformanceProgressBar</strong> can be used to show indeterminate progress inside an app (though you should also consider the new <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.shell.progressindicator(v=VS.92).aspx">ProgressIndicator</a> support in ‘Mango’, too).</p>
<p><strong>TiltEffect</strong> attached property that gives buttons, list items, and other components that nice ‘tilt’ touch experience.</p>
<p><strong>TimePicker</strong> for choosing a time.</p>
<p><strong>WrapPanel</strong> is a non-virtualized wrapping panel often used for displaying photo thumbnails.</p>
<p>Helper code for <strong>Gestures</strong> (touch input manipulations).</p>
<h3>Are there plans for a 7.0 toolkit refresh?</h3>
<p>Yes. We don’t have it prepared yet, but we have integrated many of these new features into the 7.0 Windows Phone branch that we have, and eventually (no timeline yet) we’ll get that out to developers.</p>
<h3>Using the localized Date and Time Converters</h3>
<p>The date/time converters help simplify displaying date information. We’ve done all the hard work of preparing relative date logic, localizing strings and information, and making sure it’s all good code, so you can just use these in your app.</p>
<p>To get started, you add the converters as resources, either app-wide (in your App.xaml), or in a specific page.</p>
<p>Here’s all of the new converters:</p>
<pre class="xml" name="code">&lt;phone:PhoneApplicationPage.Resources&gt;
    &lt;toolkit:RelativeTimeConverter x:Key=&quot;RelativeTimeConverter&quot;/&gt;
    &lt;toolkit:ThreadDateTimeConverter x:Key=&quot;ThreadDateTimeConverter&quot;/&gt;
    &lt;toolkit:ListViewDateTimeConverter x:Key=&quot;ListViewDateTimeConverter&quot;/&gt;
    &lt;toolkit:FullViewDateTimeConverter x:Key=&quot;FullViewDateTimeConverter&quot;/&gt;
    &lt;toolkit:HourlyDateTimeConverter x:Key=&quot;HourlyDateTimeConverter&quot;/&gt;
    &lt;toolkit:DailyDateTimeConverter x:Key=&quot;DailyDateTimeConverter&quot;/&gt;
&lt;/phone:PhoneApplicationPage.Resources&gt;</pre>
<p>You can use the sample app to experiment with the various views, but they mimic many of the views found throughout the Windows Phone for showing this information.</p>
<p>Now, to show the formatted and localized time or date, just use the converter in binding syntax, like this:</p>
<pre class="xml" name="code">&lt;TextBlock Text=&quot;{Binding DateAndTime, Converter={StaticResource RelativeTimeConverter}}&quot;
            FontSize=&quot;{StaticResource PhoneFontSizeMediumLarge}&quot;
            Foreground=&quot;{StaticResource PhoneForegroundBrush}&quot;/&gt;</pre>
<p>Here’s German (on the left) and French (right) with the nice RelativeTimeConverter in use:</p>
<p><a href="http://www.jeff.wilcox.name/wp-content/uploads/2011/08/DateTimeConverters.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="DateTimeConverters" border="0" alt="DateTimeConverters" src="http://www.jeff.wilcox.name/wp-content/uploads/2011/08/DateTimeConverters_thumb.png" width="680" height="567" /></a></p>
<h3>The new HubTile control</h3>
<p><a href="http://www.jeff.wilcox.name/wp-content/uploads/2011/08/HubTileSample.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="HubTileSample" border="0" alt="HubTileSample" align="right" src="http://www.jeff.wilcox.name/wp-content/uploads/2011/08/HubTileSample_thumb.png" width="300" height="575" /></a>The HubTile control lets you add your own tiles to your app, just like the People hub in ‘Mango’ does for groups of people. It looks sharp. Similar to how the phone does it, there’s a central coordination system so that tiles animate in a defined but random way; you can also freeze/unfreeze the tiles to improve performance in pivot scenarios, etc.</p>
<p>The control is simple to use, here’s some of the code from the sample project:</p>
<pre class="xml" name="code">&lt;toolkit:HubTile
    Margin=&quot;12,12,0,0&quot;
    Source=&quot;/Images/Pretzel.jpg&quot;
    Title=&quot;Pretzel&quot;
    Notification=&quot;w/fixings&quot;
    DisplayNotification=&quot;True&quot;
    GroupTag=&quot;Food&quot;/&gt;</pre>
<p>The tiles can be arranged to offer links to sub pages easily, etc. These look really slick at runtime.</p>
<h3>Using the Page Transitions</h3>
<p>The page transitions are a nice, easy way to improve the visual experience of your app, and now they are much more responsive, immediately reacting to new navigations.</p>
<p>It’s a two-step process to use the transitions in your project once you’ve included the toolkit.</p>
<p>First, open App.xaml.cs, open up the region at the bottom of the file with the phone initialization work, and replace the standard phone frame with our TransitionFrame (about line 108 in the standard project):</p>
<pre class="c-sharp" name="code">RootFrame = new TransitionFrame();</pre>
<p>Next, on every page, you can define the transitions you would like for in and out navigations; often we see developers creating a style in App.xaml and just applying that to pages.</p>
<pre class="xml" name="code">&lt;toolkit:TransitionService.NavigationInTransition&gt;
    &lt;toolkit:NavigationInTransition&gt;
        &lt;toolkit:NavigationInTransition.Backward&gt;
            &lt;toolkit:TurnstileTransition Mode=&quot;BackwardIn&quot;/&gt;
        &lt;/toolkit:NavigationInTransition.Backward&gt;
        &lt;toolkit:NavigationInTransition.Forward&gt;
            &lt;toolkit:TurnstileTransition Mode=&quot;ForwardIn&quot;/&gt;
        &lt;/toolkit:NavigationInTransition.Forward&gt;
    &lt;/toolkit:NavigationInTransition&gt;
&lt;/toolkit:TransitionService.NavigationInTransition&gt;
&lt;toolkit:TransitionService.NavigationOutTransition&gt;
    &lt;toolkit:NavigationOutTransition&gt;
        &lt;toolkit:NavigationOutTransition.Backward&gt;
            &lt;toolkit:TurnstileTransition Mode=&quot;BackwardOut&quot;/&gt;
        &lt;/toolkit:NavigationOutTransition.Backward&gt;
        &lt;toolkit:NavigationOutTransition.Forward&gt;
            &lt;toolkit:TurnstileTransition Mode=&quot;ForwardOut&quot;/&gt;
        &lt;/toolkit:NavigationOutTransition.Forward&gt;
    &lt;/toolkit:NavigationOutTransition&gt;
&lt;/toolkit:TransitionService.NavigationOutTransition&gt;</pre>
<h3>Other resources</h3>
<p>From one of the earlier releases, you can find out about ListPicker, LongListSelector, TransitionFrame, AutoCompleteBox, etc. in <a href="http://blogs.msdn.com/b/delay/archive/2010/11/02/mo-controls-mo-controls-mo-controls-announcing-the-second-release-of-the-silverlight-for-windows-phone-toolkit.aspx">David Anson’s blog post on these components</a>.</p>
<h3>Special thanks</h3>
<p>The toolkit is made possible by a number of people throughout Microsoft who are passionate about great user experiences and the Windows Phone – too many people to list here but definitely Dave, Dustin, Aaron, Phillip, Richard, Tom, Peter, and more! But with this release, we’ve also had the pleasure of working with a number of great students from around the world who interned this summer at Microsoft.</p>
<p>With their permission, I wanted to share their names here to thank them for their contributions – and this way you know who to bug on Twitter or online when you’re filing bugs!</p>
<ul>
<li>Badr Zrari (Software Engineering, Polytechnic Montreal) worked on the new buttery-smooth LongListSelector (now based on ListBox) </li>
<li><a href="https://twitter.com/#!/joseharriaga">José H. Arriaga</a> (Computer and Robotics Engineering, Monterrey Institute of Technology and Higher Education) worked on the HubTile, date and time converters, multiselect list, expander item </li>
<li><a href="http://andrewmunsell.com/">Andrew Munsell</a> worked on PhoneTextBox </li>
</ul>
<p>Hope you enjoy the new release.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2011/08/august2011phonetoolkit/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Building a detailed About page for your Windows Phone application</title>
		<link>http://www.jeff.wilcox.name/2011/07/my-app-about-page/</link>
		<comments>http://www.jeff.wilcox.name/2011/07/my-app-about-page/#comments</comments>
		<pubDate>Fri, 08 Jul 2011 02:16:56 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2011/07/my-app-about-page/</guid>
		<description><![CDATA[I’ve gotten enough questions about the “About” page in my app that I figure it’s time to share it. Is this the best way to do it? No clue… last year when I started building my first app, this is how I decided to write the about page in a few unique ways, so here [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve gotten enough questions about the “About” page in my app that I figure it’s time to share it.</p>
<p>Is this the best way to do it? No clue… last year when I started building my first app, this is how I decided to write the about page in a few unique ways, so here it is!</p>
<p><a href="http://www.jeff.wilcox.name/wp-content/uploads/2011/07/AboutPages.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="AboutPages" border="0" alt="AboutPages" src="http://www.jeff.wilcox.name/wp-content/uploads/2011/07/AboutPages_thumb.png" width="680" height="378" /></a></p>
<p>The tech industry has a long and fun history, having gone many directions, with “credits”, about experiences, and more. Do you remember when Internet Explorer had a Credits listing? Photoshop always starts up with Thomas Knoll and friends.</p>
<p>With mobile apps, the quickest way to make an app that rocks is to borrow most of the app. That’s where helper libraries, toolkits, open source friends, and everything else comes together into one shippable piece of marketplace goo.</p>
<p>Now, with most open source projects, you definitely need to remember to keep the license files in tact, track your sources, make sure licenses are compatible… and whatever else your lawyer tells you.</p>
<p>But it’s also a pretty common practice to give public credit to the developers who helped make your app possible, and as a developer, I’ll admit my ego doesn’t mind seeing my name plastered in an about page on a favorite app or two.</p>
<h3>What I put into my About page</h3>
<p>I decided to put a lot of good information in the about experience, separated using a Pivot control and a few items. At one point and time, the marketplace ingestion requirements asked for support data and some other things for all apps, but I believe these requirements have been relaxed. So, I have:</p>
<ul>
<li>Main pivot item and about screen
<ul>
<li>App name, author, version dynamically populate from the app package </li>
<li>A link to review the app </li>
<li>Support information </li>
<li>Links to the app’s privacy policy </li>
</ul>
</li>
<li>Legal page with lots of text </li>
<li>“What’s new” dynamic pivot item </li>
</ul>
<h3>Note: A nice ‘About’ experience can have zero performance impact</h3>
<p>The About page for my app is contained in its own assembly, “About.dll”. It’s small in size, but since it’s a separate assembly not often used (and not loaded at startup).</p>
<p>According to analytics data, less than 3% of the time people look at my About page, so most probably have not seen it – why make them pay for it?</p>
<p>All that’s required for this is:</p>
<ul>
<li>Referencing the About project/assembly from your main app’s project </li>
<li>Navigating to this URI: <strong>/About;component/About.xaml</strong> </li>
</ul>
<h3>Creating the info page</h3>
<p>So to get started…</p>
<ul>
<li>Add a new class library project to your app’s solution; I named mine simply, ‘About’ </li>
<li>Delete the Class1.cs that comes with it </li>
<li>Add an About.xaml to the project </li>
<li>Add any XMLNS and project references you may need (such as the TiltEffect from the toolkit, etc.) </li>
</ul>
<p>In the pivot, I set its Title to my app’s name, then put in a few text blocks and hyperlink buttons. I’ve named the version block and also have a Review this app button.</p>
<pre class="xml" name="code">&lt;controls:PivotItem Header=&quot;about&quot;&gt;
    &lt;ScrollViewer&gt;
        &lt;StackPanel Margin=&quot;0,-12,0,24&quot;&gt;
            &lt;TextBlock
                Style=&quot;{StaticResource PhoneTextExtraLargeStyle}&quot;
                Text=&quot;4th &amp;amp; Mayor&quot;
                Foreground=&quot;{StaticResource PhoneAccentBrush}&quot; /&gt;
            &lt;TextBlock
                Style=&quot;{StaticResource PhoneTextLargeStyle}&quot;
                Text=&quot;by Jeff Wilcox&quot; /&gt;

            &lt;HyperlinkButton
                NavigateUri=&quot;http://www.4thandmayor.com/&quot;
                TargetName=&quot;_new&quot;
                HorizontalAlignment=&quot;Left&quot;
                Content=&quot;www.4thandmayor.com&quot; /&gt;

            &lt;StackPanel Orientation=&quot;Horizontal&quot; Margin=&quot;0,18,0,0&quot;&gt;
                &lt;TextBlock
                    Style=&quot;{StaticResource PhoneTextNormalStyle}&quot;
                    Text=&quot;Version:&quot; /&gt;
                &lt;TextBlock
                    Margin=&quot;0&quot;
                    Style=&quot;{StaticResource PhoneTextNormalStyle}&quot;
                    x:Name=&quot;_versionText&quot; /&gt;
            &lt;/StackPanel&gt;
              &lt;Button
                  HorizontalAlignment=&quot;Left&quot;
                  Tag=&quot;Review&quot;
                  Click=&quot;HyperlinkButton_Click&quot;
                  Content=&quot;Review this app&quot;/&gt;
        &lt;/StackPanel&gt;
    &lt;/ScrollViewer&gt;
&lt;/controls:PivotItem&gt;</pre>
<p>In code behind, I’m then hooking up a few quick things…</p>
<pre class="c-sharp" name="code">private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
    string s = ((ButtonBase)sender).Tag as string;

    switch (s)
    {
        case &quot;Review&quot;:
            var task = new MarketplaceReviewTask();
            task.Show();
            break;
    }
}</pre>
<p>And the version that I pull in isn’t pretty code, but it’ll grab it from the manifest file. This can be done in the constructor or in the OnNavigatedTo event:</p>
<pre class="c-sharp" name="code">Uri manifest = new Uri(&quot;WMAppManifest.xml&quot;, UriKind.Relative);
var si = Application.GetResourceStream(manifest);
if (si != null)
{
    using (StreamReader sr = new StreamReader(si.Stream))
    {
        bool haveApp = false;
        while (!sr.EndOfStream)
        {
            string line = sr.ReadLine();
            if (!haveApp)
            {
                int i = line.IndexOf(&quot;AppPlatformVersion=\&quot;&quot;, StringComparison.InvariantCulture);
                if (i &gt;= 0)
                {
                    haveApp = true;
                    line = line.Substring(i + 20);

                    int z = line.IndexOf(&quot;\&quot;&quot;);
                    if (z &gt;= 0)
                    {
                      // if you're interested in the app plat version at all
                      // AppPlatformVersion = line.Substring(0, z);
                    }
                }
            }

            int y = line.IndexOf(&quot;Version=\&quot;&quot;, StringComparison.InvariantCulture);
            if (y &gt;= 0)
            {
                int z = line.IndexOf(&quot;\&quot;&quot;, y + 9, StringComparison.InvariantCulture);
                if (z &gt;= 0)
                {
                    // We have the version, no need to read on.
                    _versionText.Text = line.Substring(y + 9, z - y - 9);
                    break;
                }
            }
        }
    }
}
else
{
    _versionText.Text = &quot;Unknown&quot;;
}</pre>
<p>OK, so that gives us at least a simple starting point for the about page. Of course a solid app would also try and tombstone the select pivot item, etc.</p>
<h3>My dynamic LICENSE.TXT solution</h3>
<p>Instead of just embedding the XAML for my ‘legal’ pivot item, I decided that it would be much easier to maintain if I just pulled this information in from a file inside the application’s installation directory called LICENSE.TXT. As an app dev, I’m used to using this kind of file to track dependencies and credit.</p>
<h4>Prepare the file:</h4>
<ul>
<li>In your <em>main application’s project</em>, right-click in VS and add a new Text File</li>
<li>Select the file, open the Properties window</li>
<li>Change the type of the file to ‘Content’</li>
</ul>
<p>Content will make sure that the file ends up inside your XAP (which is ‘exploded’ on the client into an installation directory), but it won’t take up space in any of the app’s assemblies.</p>
<h4>Prep the pivot and pivot item:</h4>
<p>First, let’s add the new pivot item for the ‘legal’ information.</p>
<pre class="xml" name="code">&lt;controls:PivotItem Header=&quot;legal&quot;&gt;
    &lt;ScrollViewer x:Name=&quot;sv1&quot;
                    Margin=&quot;0,0,-12,24&quot;/&gt;
&lt;/controls:PivotItem&gt;</pre>
<p>Pretty simple. Note I named the scroll viewer “sv1” so that I could dynamically add everything I needed to it. This is partly to workaround the 2000&#215;2000 pixel limitation for large things like text blocks, so that it doesn’t clip.</p>
<p>Add a SelectionChanged event to the pivot and wire it up (or just do it in XAML). I use this to wait until someone swipes to the ‘legal’ pivot item to actually load in the file. It’s all such little work for the device to do that you really could just do it in the page constructor, too, but when I first coded this, I decided to do it this way!</p>
<p>This is probably way too code heavy, but hey it works. It uses the app’s GetResourceStream to load the LICENSE.txt from the installation directory. I also decided that when the code encounters a blank line, that the next will have full opacity (instead of 0.7), so it stands out. This helps designate ‘sections’ in the text.</p>
<pre class="c-sharp" name="code">private void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    Pivot piv = (Pivot)sender;
    if (piv.SelectedIndex &gt; 0 &amp;&amp; _licenses == null)
    {
        Dispatcher.BeginInvoke(() =&gt;
        {
            _licenses = new StackPanel();

            StreamResourceInfo sri = Application.GetResourceStream(
                new Uri(&quot;LICENSE.txt&quot;, UriKind.Relative));
            if (sri != null)
            {
                using (StreamReader sr = new StreamReader(sri.Stream))
                {
                    string line;
                    bool lastWasEmpty = true;
                    do
                    {
                        line = sr.ReadLine();

                        if (line == string.Empty)
                        {
                            Rectangle r = new Rectangle
                            {
                                Height = 20,
                            };
                            _licenses.Children.Add(r);
                            lastWasEmpty = true;
                        }
                        else
                        {
                            TextBlock tb = new TextBlock
                            {
                                TextWrapping = TextWrapping.Wrap,
                                Text = line,
                                Style = (Style)Application.Current.Resources[&quot;PhoneTextNormalStyle&quot;],
                            };
                            if (!lastWasEmpty)
                            {
                                tb.Opacity = 0.7;
                            }
                            lastWasEmpty = false;
                            _licenses.Children.Add(tb);
                        }
                    } while (line != null);
                }
            }

            sv1.Content = _licenses;
        });
    }
}</pre>
<h3>A web-connected “What’s New” display</h3>
<p>OK, so now we have a <em>static</em> first page, a <em>runtime-read</em> license display, and next, let’s finish off with a <em>dynamic, web-requested block of XAML</em>.</p>
<p>When I created the app, I really wanted to be able to provide updated information or bug listings on the fly if needed. I decided to host a XAML file in the cloud; if the file can be resolved, it’s downloaded and displayed, and if not, it falls back to some basic text.</p>
<p>Another idea I had, but never implemented fully, was to have a blog/RSS feed with ‘known issues’, and then let the app pick up the recent posts and show them inside this tab: then users could see if they’re experiencing issues, and if they were, could even go to the blog post and comment on it with others. Didn’t get there. Maybe in a future update I’ll spend the time!</p>
<p>So here’s what my final pivot item looks like in XAML</p>
<pre class="xml" name="code">&lt;controls:PivotItem Header=&quot;what's new?&quot;&gt;
    &lt;ScrollViewer&gt;
          &lt;shared:WebXamlBlock
            Margin=&quot;0,24,12,24&quot;
            VerticalAlignment=&quot;Top&quot;
            HorizontalContentAlignment=&quot;Left&quot;
            XamlUri=&quot;http://www.4thandmayor.com/app/changelog.xaml&quot;&gt;
              &lt;shared:WebXamlBlock.FallbackContent&gt;
                  &lt;StackPanel&gt;
                      &lt;TextBlock
                        TextWrapping=&quot;Wrap&quot;
                        Style=&quot;{StaticResource PhoneTextLargeStyle}&quot;&gt;Information about the latest version can be found out at:&lt;/TextBlock&gt;
                      &lt;TextBlock
                        Text=&quot; &quot; /&gt;
                      &lt;HyperlinkButton
                        HorizontalAlignment=&quot;Left&quot;
                        Style=&quot;{StaticResource AccentHyperlink}&quot;
                        FontSize=&quot;{StaticResource PhoneFontSizeMediumLarge}&quot;
                        NavigateUri=&quot;http://www.4thandmayor.com/&quot;
                        Content=&quot;http://www.4thandmayor.com/&quot;
                        TargetName=&quot;_self&quot; /&gt;
                  &lt;/StackPanel&gt;
              &lt;/shared:WebXamlBlock.FallbackContent&gt;
          &lt;/shared:WebXamlBlock&gt;
    &lt;/ScrollViewer&gt;
&lt;/controls:PivotItem&gt;</pre>
<p>So the final piece that’s missing is the ‘Shared:WebXamlBlock’ control that dynamically downloads from the web the XAML. If you use this, be sure to have a complete security review and make sure it’s OK for you to grab dynamic pieces, some people might be spooked by that.</p>
<p>Here is a version of the control; I’ve removed a few dependencies I had on other components I had build to support my projects. The control is a ContentControl and has no default style so it’s simple to get going.</p>
<pre class="c-sharp" name="code">using System.Windows.Controls;
using System;
using System.Windows;
using System.Net;
using System.Windows.Data;
using System.Windows.Markup;

namespace JeffWilcox.Controls
{
    public class WebXamlBlock : ContentControl
    {
        #region public Uri XamlUri
        /// &lt;summary&gt;
        /// Gets or sets the XAML Uri.
        /// &lt;/summary&gt;
        public Uri XamlUri
        {
            get { return GetValue(XamlUriProperty) as Uri; }
            set { SetValue(XamlUriProperty, value); }
        }

        /// &lt;summary&gt;
        /// Identifies the XamlUri dependency property.
        /// &lt;/summary&gt;
        public static readonly DependencyProperty XamlUriProperty =
            DependencyProperty.Register(
                &quot;XamlUri&quot;,
                typeof(Uri),
                typeof(WebXamlBlock),
                new PropertyMetadata(null, OnXamlUriPropertyChanged));

        /// &lt;summary&gt;
        /// XamlUriProperty property changed handler.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;d&quot;&gt;WebXamlBlock that changed its XamlUri.&lt;/param&gt;
        /// &lt;param name=&quot;e&quot;&gt;Event arguments.&lt;/param&gt;
        private static void OnXamlUriPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            WebXamlBlock source = d as WebXamlBlock;
            source.TryDownloading();
        }
        #endregion public Uri XamlUri

        #region public object FallbackContent
        /// &lt;summary&gt;
        /// Gets or sets the content to fallback to if the request fails.
        /// &lt;/summary&gt;
        public object FallbackContent
        {
            get { return GetValue(FallbackContentProperty) as object; }
            set { SetValue(FallbackContentProperty, value); }
        }

        /// &lt;summary&gt;
        /// Identifies the FallbackContent dependency property.
        /// &lt;/summary&gt;
        public static readonly DependencyProperty FallbackContentProperty =
            DependencyProperty.Register(
                &quot;FallbackContent&quot;,
                typeof(object),
                typeof(WebXamlBlock),
                new PropertyMetadata(null));
        #endregion public object FallbackContent

        public WebXamlBlock()
        {
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            TryDownloading();
        }

        private bool _haveTried;

        private void TryDownloading()
        {
            if (_haveTried)
            {
                return;
            }
            _haveTried = true;
            if (XamlUri != null)
            {
                var wc = new WebClient();
                wc.DownloadStringCompleted += OnDownloadStringCompleted;
                wc.DownloadStringAsync(XamlUri);
            }
        }

        private void OnError()
        {
            Dispatcher.BeginInvoke(() =&gt;
                {
                    var b = new Binding(&quot;FallbackContent&quot;) {Source = this};
                    SetBinding(ContentProperty, b);
                });
        }

        private void OnDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error != null || e.Cancelled)
            {
                OnError();
            }
            else
            {
                string xaml = e.Result;
                Dispatcher.BeginInvoke(() =&gt;
                    {
                        try
                        {
                            var o = XamlReader.Load(xaml);
                            if (o != null)
                            {
                                Content = o;
                            }
                        }
                        catch
                        {
                            OnError();
                        }
                    });
            }
        }
    }
}</pre>
<p>And now, for your actual XAML file that you host in the cloud, just drop your XAML in the file with the appropriate standard XML namespaces for XAML and you’re good-to-go.</p>
<h3>Fun aside</h3>
<p>Activity if you’re ever super bored: </p>
<ul>
<li>borrow a friends’ iOS device. </li>
<li>Go into the Settings. </li>
<li>Touch ‘General’. </li>
<li>Touch ‘About’. </li>
<li>Touch ‘Legal’. </li>
<li>Begin reading and/or scrolling </li>
</ul>
<p>That’s right, it’s just like the iTunes user agreement! But it’s also full of information about the tons of libraries and contributors that make that product.</p>
<h3>Source note</h3>
<p>My implementation is actually pretty tightly coupled to a bunch of random components; until I update the source drop of my app and framework online, this post’s walkthrough will have to do – I don’t have a separate .csproj file with the About app right now. Sorry!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2011/07/my-app-about-page/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Creating a global ProgressIndicator experience using the Windows Phone 7.1 SDK Beta 2</title>
		<link>http://www.jeff.wilcox.name/2011/07/creating-a-global-progressindicator-experience-using-the-windows-phone-7-1-sdk-beta-2/</link>
		<comments>http://www.jeff.wilcox.name/2011/07/creating-a-global-progressindicator-experience-using-the-windows-phone-7-1-sdk-beta-2/#comments</comments>
		<pubDate>Fri, 08 Jul 2011 00:44:24 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2011/07/creating-a-global-progressindicator-experience-using-the-windows-phone-7-1-sdk-beta-2/</guid>
		<description><![CDATA[One of the nice new features in the 7.1 release of Windows Phone for developers is ProgressIndicator support right within the app platform, removing the need in many situations for the Silverlight-based PerformanceProgressBar control that I created some time ago. (The PerformanceProgressBar was a decent performance improvement over the stock ProgressBar in the first release [...]]]></description>
			<content:encoded><![CDATA[<p>One of the nice new features in the 7.1 release of Windows Phone for developers is ProgressIndicator support right within the app platform, removing the need in many situations for the Silverlight-based PerformanceProgressBar control that I created some time ago.</p>
<p>(The PerformanceProgressBar was a decent performance improvement over the stock ProgressBar in the first release of the OS, but offloading the control to the OS improves performance even more. As many people pointed out, the rich visualization wasn’t free.)</p>
<p>So my initial thought was that I could use the new ProgressIndicator control and have a single instance to use throughout my app. Not so fast! Unfortunately (in my mind) the ProgressIndicator property is a SystemTray property and it’s set on every single page instance.</p>
<p>In my applications, I prefer to wire all key events (data downloads, long-running tasks, etc.) to a single, centralized ‘global loading’ control, removing the need to have more than a single progress bar instance in the app.</p>
<p>So in this post quickly we’ll:</p>
<ul>
<li>See how to hook up the GlobalLoading when your app starts up</li>
<li>Note that the navigation framework’s events are used to auto-hookup the same shared progress indicator instance to every page</li>
<li>See how to use the IsLoading setter to turn on and off the loading experience</li>
</ul>
<h3>My old &amp; new strategies</h3>
<p>In my 7.0 apps, I would re-template the root phone application frame and have the single indeterminate progress bar in there, so it’s always available.</p>
<p>In 7.1, my goal is to be able to re-purpose my existing global loading system. I want to create a single instance of the new ProgressIndicator type, and then automatically have it set to every single page’s appropriate system tray property automatically. This will eliminate any manual hook-up required, so it will just always be present and work.</p>
<h3>Initializing the global loading system at startup</h3>
<p>In order to always have the progress indicator visible, I need to make sure it’s always set when a page navigation happens, sharing that single instance. Let’s use the Navigated event of the PhoneApplicationFrame that is created in App.xaml.cs.</p>
<ul>
<li>Open up your 7.1 app’s App.xaml.cs </li>
<li>Expand the “Phone application initialization” region in the editor </li>
<li>At line ~120 (in a new project), where the RootFrame is set, add the initialize call. </li>
</ul>
<pre class="c-sharp" name="code">GlobalLoading.Instance.Initialize(RootFrame);</pre>
<h3>Hooking up to the Navigated event</h3>
<p>Now, you’ll see that inside the global loading system implementation below, I’m using the Navigated event to set the ProgressIndicator property with every complete navigation:</p>
<pre class="c-sharp" name="code">private void OnRootFrameNavigated(object sender, NavigationEventArgs e)
{
    // Use in Mango to share a single progress indicator instance.
    var ee = e.Content;
    var pp = ee as PhoneApplicationPage;
    if (pp != null)
    {
        pp.SetValue(SystemTray.ProgressIndicatorProperty, _mangoIndicator);
    }
}</pre>
<p>Nothing for you to do other than include the GlobalLoading.cs file in your project.</p>
<h3>Using the global loading system</h3>
<p>Now, in my app, I have two ways of providing data to this global loader, one of which is pretty automatic:</p>
<ul>
<li>AgFx: I hook up to the DataManager’s property change event, looking for changes in its own central IsLoading property</li>
<li>You can set GlobalLoading.Instance.IsLoading to <em>true</em> or <em>false</em></li>
</ul>
<p>Note that setting IsLoading to true <em>increments</em> an internal counter, and setting to false decrements; the idea is that you match operations to results: if you start a web browser navigation and set IsLoaded to True, make sure that when the navigation is complete or canceled, you set it to False.</p>
<p>However, if multiple requests are happening at once, the loading indication will not stop until all requests have completed.</p>
<p>Now, one of the downfalls of using simple integer arithmetic here is that you could potentially forget to increment or decrement, leaving the indicator always going, and likely keeping your app from making it through the marketplace ingestion requirements.</p>
<p>A better solution might be to request and use “tokens” or some sort of instance that could either timeout or be used to debug your app’s logic; it would also allow you to use the new progress indicator’s text property to provide information about loading operations (“Currently loading 2 things…”, “Refreshing your places list”), which is more interesting.</p>
<p>The cool <a href="http://hiddenpineapple.com/rowi/">Rowi</a> app does this.</p>
<h3>Data binding or not</h3>
<p>In my 7.0 implementation, I actually directly data bind a central PerformanceProgressBar’s IsLoading property to the GlobalLoading.Instance.ActualIsLoading property; in 7.1, I decided for simplicity to instead just directly set the progress indicator’s values, but I maybe could have data bound to the indicator. Let me know if you try that and have any issues!</p>
<p>Here’s the source to GlobalLoading.cs. I’ve commented out the AgFx parts in case you’re not using that system.</p>
<h3>GlobalLoading.cs</h3>
<pre class="c-sharp" name="code">using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
// using AgFx;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;

namespace JeffWilcox.FourthAndMayor
{
    public class GlobalLoading : INotifyPropertyChanged
    {
        private ProgressIndicator _mangoIndicator;

        private GlobalLoading()
        {
        }

        public void Initialize(PhoneApplicationFrame frame)
        {
            // If using AgFx:
            // DataManager.Current.PropertyChanged += OnDataManagerPropertyChanged;

            _mangoIndicator = new ProgressIndicator();

            frame.Navigated += OnRootFrameNavigated;
        }

        private void OnRootFrameNavigated(object sender, NavigationEventArgs e)
        {
            // Use in Mango to share a single progress indicator instance.
            var ee = e.Content;
            var pp = ee as PhoneApplicationPage;
            if (pp != null)
            {
                pp.SetValue(SystemTray.ProgressIndicatorProperty, _mangoIndicator);
            }
        }

        private void OnDataManagerPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (&quot;IsLoading&quot; == e.PropertyName)
            {
                // if AgFx: IsDataManagerLoading = DataManager.Current.IsLoading;
                NotifyValueChanged();
            }
        }

        private static GlobalLoading _in;
        public static GlobalLoading Instance
        {
            get
            {
                if (_in == null)
                {
                    _in = new GlobalLoading();
                }

                return _in;
            }
        }

        public bool IsDataManagerLoading { get; set; }

        public bool ActualIsLoading
        {
            get
            {
                return IsLoading || IsDataManagerLoading;
            }
        }

        private int _loadingCount;

        public bool IsLoading
        {
            get
            {
                return _loadingCount &gt; 0;
            }
            set
            {
                bool loading = IsLoading;
                if (value)
                {
                    ++_loadingCount;
                }
                else
                {
                    --_loadingCount;
                }

                NotifyValueChanged();
            }
        }

        private void NotifyValueChanged()
        {
            if (_mangoIndicator != null)
            {
                _mangoIndicator.IsIndeterminate = _loadingCount &gt; 0 || IsDataManagerLoading;

                // for now, just make sure it's always visible.
                if (_mangoIndicator.IsVisible == false)
                {
                    _mangoIndicator.IsVisible = true;
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}</pre>
<p>Hope this helps!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2011/07/creating-a-global-progressindicator-experience-using-the-windows-phone-7-1-sdk-beta-2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Windows Phone, a great dev platform: adding leaderboards to 4th &amp; Mayor in 30 minutes</title>
		<link>http://www.jeff.wilcox.name/2011/03/4am-leaderboard-notification/</link>
		<comments>http://www.jeff.wilcox.name/2011/03/4am-leaderboard-notification/#comments</comments>
		<pubDate>Mon, 21 Mar 2011 03:07:48 +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/2011/03/4am-leaderboard-notification/</guid>
		<description><![CDATA[Just over a week ago, a new foursquare feature was released for nice leaderboards. WP7 is fast - I added the feature in about 30 minutes.]]></description>
			<content:encoded><![CDATA[<p>It’s just amazing how efficient the Windows Phone (powered by Silverlight) dev environment can be. I’m a little biased here (yeah yeah I work on the team), but wanted to start of my app development series with a short example of just how quickly the platform can enable rapid changes and innovation.</p>
<p>At SXSW a little over a week ago, foursquare introduced the new ‘<a href="http://blog.foursquare.com/2011/03/08/foursquare-3/">fsq3</a>’ version of their apps for iPhone, Android, and I believe eventually Blackberry, too, though not initially. Foursquare has always been about a fun time, exploring the city as part of a massive, worldwide-game, and so they did some nice work in version 3 to bring in a little more fun: every time you check-in to a place, there’s a leaderboard (relative to all of your friends) that appears, showing your latest scores and your close competition.</p>
<p>It took about 30 minutes to add this feature to my foursquare app, sadly this blog post will probably take 60 minutes to prepare.</p>
<p>The steps really are:</p>
<ul>
<li>Parsing the JSON of the added data</li>
<li>Creating a new data/model item</li>
<li>Designing and creating new XAML templates for presenting the data</li>
<li>Updating the data template selector for the added notification type</li>
<li>Binding the data and making the magic happen</li>
</ul>
<p>Here’s what it looks like on an iPhone – the new “Leaderboard” section is of interest. Interestingly, the Android app for foursquare is pretty much a clone of the iPhone app… so no need to really highlight that.</p>
<p><img src="http://d2tz2ccf2zi8lx.cloudfront.net/media/posts/leaderboardInResults.png" /></p>
<p>The way that this is implemented on the foursquare service side is a simple new “notification” type that comes in after a check-in or other action. When working with services like this, as a developer it’s more important than ever to be resilient against “invalid” or unknown data and types – lots of null checks, default handling clauses, etc. So foursquare added a new <em>leaderboard</em> notification type to the others (such as mayor status, a recommended tip at a place, etc.)</p>
<p>The code I wrote to handle notifications started with a simple set of parsing methods. Notifications can actually come from any foursquare web request, but typically it’s just when you check-in. I use (and absolute love!) <a href="http://json.codeplex.com/">JSON.NET</a> by James Newton-King &#8211; the LINQ to JSON stuff is nice, and it’s a lot better than the JSON stuff built into the platform.</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:3636f1cf-0285-4a90-aa71-9cc2aa386cff" class="wlWriterEditableSmartContent">
<pre class="csharp" name="code">// Notifications is a List&lt;Notification&gt;
public static Notifications ParseJson(JToken json, string venueId)
{
    var ns = new Notifications();

    foreach (var notif in json)
    {
        Notification notification = Notification.ParseJson(notif, venueId);
        if (notification != null)
        {
            ns.Add(notification);
        }
    }

    return ns;
}

public static Notification ParseJson(JToken notification, string venueId)
{
    Notification n = null;

    string type = Checkin.TryGetJsonProperty(notification, "type");
    var item = notification["item"];
    if (item != null)
    {
        switch (type)
        {
            case "message":
                n = new MessageNotification(item);
                break;

            case "badge":
                n = new BadgeNotification(item);
                break;

            case "mayorship":
                n = new MayorshipNotification(item);
                break;

            case "tip":
                n = new RecommendedTipNotification(item);
                break;

            case "leaderboard":
                n = new LeaderboardNotification(item);
                break;

            case "special":
                n = new SpecialNotification(item, venueId);
                break;

            case "score":
                n = new ScoreNotification(item);
                break;

            default:
                var hasMessage = item["message"];
                if (hasMessage != null)
                {
                    n = new MessageNotification(item);
                }

                break;
        }
    }

    return n;
}

namespace JeffWilcox.FourthAndMayor.Model
{
    public class LeaderboardNotification : Notification
    {
        public string Message { get; private set; }

        public List&lt;LeaderboardItem&gt; Leaderboard { get; private set; }

        public LeaderboardNotification(JToken item)
        {
            Message = Checkin.SanitizeString(Checkin.TryGetJsonProperty(item, "message"));

            var leaders = new List&lt;LeaderboardItem&gt;();
            var lj = item["leaderboard"];
            if (lj != null)
            {
                foreach (var victor in lj)
                {
                    var wolverine = LeaderboardItem.ParseJson(victor);
                    if (wolverine != null)
                    {
                        leaders.Add(wolverine);
                    }
                }
            }

            Leaderboard = leaders;
        }
    }
}</pre>
</div>
<p>And then a switch to handle known notification types and create data model objects from that. This yields a nice strongly typed data object – I personally prefer this to just storing the JSON tree live, or using a property bag, but everyone has their own opinions. Strong typing makes data binding in Silverlight super easy.</p>
<p>The JSON from foursquare looks a lot like this:</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:13c02a2f-e8e1-46bf-aa3e-5eba88c5a2b7" class="wlWriterEditableSmartContent">
<pre class="jscript" name="code">{
"type": "mayorship",
"item": {
  "type": "nochange",
  "checkins": 27,
  "message": "You're still the Mayor of Boka Kitchen &#038; Bar! (27 check-ins in the past two months)",
  "image": "http://foursquare.com/img/crown.png"
}
},
{
"type": "leaderboard",
"item": {
  "leaderboard": [
	{
	  "user": {
		"id": "4052351",
		"firstName": "Gilles",
		"lastName": "K",
		"photo": "https://playfoursquare.s3.amazonaws.com/userpix_thumbs/FXM5YX5ABXZARAR1.png",
		"gender": "male",
		"homeCity": "WA",
		"relationship": "friend"
	  },
	  "scores": {
		"recent": 120,
		"max": 127,
		"checkinsCount": 31
	  },
	  "rank": 1
	},
	{
	  "user": {
		"id": "20057",
		"firstName": "Jeff",
		"lastName": "W",
		"photo": "https://playfoursquare.s3.amazonaws.com/userpix_thumbs/RRJIFN1NATUHRN4J.jpg",
		"gender": "male",
		"homeCity": "Seattle, WA",
		"relationship": "self"
	  },
	  "scores": {
		"recent": 117,
		"max": 124,
		"checkinsCount": 49
	  },
	  "rank": 2
	},
	{
	  "user": {
		"id": "130986",
		"firstName": "Tim",
		"lastName": "H",
		"photo": "https://playfoursquare.s3.amazonaws.com/userpix_thumbs/4A52T22PCNGR11EM.jpg",
		"gender": "male",
		"homeCity": "WA",
		"relationship": "friend"
	  },
	  "scores": {
		"recent": 116,
		"max": 125,
		"checkinsCount": 41
	  },
	  "rank": 3
	}
  ],
  "message": "You jumped ahead of Tim!",
  "scores": [
	{
	  "points": 3,
	  "icon": "https://playfoursquare.s3.amazonaws.com/static/img/points/mayor.png",
	  "message": "You're the Mayor!"
	}
  ],
  "total": 3
}
},</pre>
</div>
<p>And so at runtime, when you check-in, you’ll end up with this return result being stored. Since I’ve already coded in my app simple parsing methods for CompactUsers, it’s easy to work with this rich hierarchical data.</p>
<p>In my checkin (“what’s new”) window of <a href="http://www.4thandmayor.com/">4th &amp; Mayor</a> I’ve a very simple items control that is used to expand at runtime the data objects into a nice visual presentation. Now in Silverlight 3 (the version that was forked for Windows Phone initially) there isn’t a way to have implicit “data templates” that key off of type, so I did have to do a little hacking. But this is super easy.</p>
<p>Here’s my data template selector that I wrote as a value converter. I expose public properties of type DataTemplate:</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:d523f33d-ef72-47f7-bfa5-d37000efafed" class="wlWriterEditableSmartContent">
<pre class="csharp" name="code">namespace JeffWilcox.FourthAndMayor.Converters
{
    public class NotificationDataTemplateSelector : IValueConverter
    {
        public DataTemplate MessageTemplate { get; set; }
        public DataTemplate MayorTemplate { get; set; }
        public DataTemplate BadgeTemplate { get; set; }
        public DataTemplate TipTemplate { get; set; }
        public DataTemplate ScoreTemplate { get; set; }
        public DataTemplate SpecialTemplate { get; set; }
        public DataTemplate LeaderboardTemplate { get; set; }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ScoreNotification sn = value as ScoreNotification;
            if (sn != null)
            {
                return ScoreTemplate;
            }

            BadgeNotification bn = value as BadgeNotification;
            if (bn != null)
            {
                return BadgeTemplate;
            }

            MayorshipNotification mn = value as MayorshipNotification;
            if (mn != null)
            {
                return MayorTemplate;
            }

            LeaderboardNotification ln = value as LeaderboardNotification;
            if (ln != null)
            {
                return LeaderboardTemplate;
            }

            RecommendedTipNotification tip = value as RecommendedTipNotification;
            if (tip != null)
            {
                return TipTemplate;
            }

            MessageNotification msg = value as MessageNotification;
            if (msg != null)
            {
                return MessageTemplate;
            }

            var special = value as SpecialNotification;
            if (special != null)
            {
                return SpecialTemplate;
            }

            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}</pre>
</div>
<p>And then on my check-in page, in the page’s resources, I define the individual data templates that I would like different notification data objects to appear as. XAML is pretty verbose but wow, powerful. I hand-edited many of my data templates. And I’m picky, I prefer one attribute per line in most situations – it makes diffs in source control a lot easier to understand and work with, especially while integrating.</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:83ca7e7a-1eca-40ec-a2f1-96f251a7df9a" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;DataTemplate x:Key="Leaderboard"&gt;
    &lt;StackPanel&gt;
		&lt;ContentPresenter Content="Leaderboard"
		                  ContentTemplate="{StaticResource GroupHeader}"/&gt;
        &lt;TextBlock
            Text="{Binding Message}"
            TextWrapping="Wrap"
            Margin="0,0,0,12"
            Style="{StaticResource PhoneTextNormalStyle}"/&gt;
        &lt;ItemsControl ItemsSource="{Binding Leaderboard}"&gt;
            &lt;ItemsControl.ItemTemplate&gt;
                &lt;DataTemplate&gt;
                    &lt;HyperlinkButton Style="{StaticResource NoHyperlink}"
                                HorizontalAlignment="Stretch"
                                HorizontalContentAlignment="Stretch"
                                NavigateUri="{Binding User.UserUri}"&gt;
                        &lt;Grid Margin="0,0,0,12"&gt;
                            &lt;Grid.ColumnDefinitions&gt;
                                &lt;ColumnDefinition Width="72"/&gt;
                                &lt;ColumnDefinition /&gt;
                                &lt;ColumnDefinition Width="88"/&gt;
                            &lt;/Grid.ColumnDefinitions&gt;
                            &lt;Grid Grid.Column="0"&gt;
                                &lt;Grid
                                    Width="72"
                                    Height="72"
                                    Background="{StaticResource PhoneChromeBrush}"&gt;
                                    &lt;Image
                                        jw:AwesomeImage.UriSource="{Binding User.Photo}"
                                        Tag="clear"/&gt;
                                &lt;/Grid&gt;
                                &lt;Grid
                                    Background="{StaticResource PhoneAccentBrush}"
                                    Width="12"
                                    HorizontalAlignment="Left"
                                    VerticalAlignment="Stretch"
                                    Visibility="{Binding IsSelf, Converter={StaticResource Vis}}"&gt;
                                    &lt;Grid.RenderTransform&gt;
                                        &lt;TranslateTransform X="-24"/&gt;
                                    &lt;/Grid.RenderTransform&gt;
                                &lt;/Grid&gt;
                            &lt;/Grid&gt;
                            &lt;StackPanel
                                Grid.Column="1"
                                Orientation="Horizontal"&gt;
                                &lt;TextBlock
                                    Style="{StaticResource PhoneTextLargeStyle}"
                                    FontFamily="{StaticResource PhoneFontFamilySemiBold}"
                                    VerticalAlignment="Center"
                                    Text="{Binding Rank}"/&gt;
                                &lt;TextBlock
                                    VerticalAlignment="Center"
                                    Margin="0"
                                    Text="{Binding User}"
                                    Style="{StaticResource PhoneTextLargeStyle}"/&gt;
                            &lt;/StackPanel&gt;
                            &lt;TextBlock
                                Text="{Binding Scores.Recent}"
                                HorizontalAlignment="Left"
                                VerticalAlignment="Center"
                                Grid.Column="2"
                                Style="{StaticResource PhoneTextLargeStyle}"
                                FontFamily="{StaticResource PhoneFontFamilySemiLight}"/&gt;
                        &lt;/Grid&gt;
                    &lt;/HyperlinkButton&gt;
                &lt;/DataTemplate&gt;
            &lt;/ItemsControl.ItemTemplate&gt;
        &lt;/ItemsControl&gt;
    &lt;/StackPanel&gt;
&lt;/DataTemplate&gt;</pre>
</div>
<p>So next I add an instance of the converter and give it a name. This is designed to associate the XAML data templates with the way to show specific notification object types when the items control expands after binding.</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:940a8a41-e4fb-4b4b-bda9-38db8861a7a5" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;Converters:NotificationDataTemplateSelector
    MessageTemplate="{StaticResource Message}"
    BadgeTemplate="{StaticResource Badge}"
    MayorTemplate="{StaticResource Mayor}"
    TipTemplate="{StaticResource PopularTip}"
    ScoreTemplate="{StaticResource Score}"
    LeaderboardTemplate="{StaticResource Leaderboard}"
    SpecialTemplate="{StaticResource Special}"
    x:Key="DataTemplateSelector"/&gt;</pre>
</div>
<p>And now here’s the items control. Here I bind the ItemsSource to my list of notifications, then use this syntax to use the data template selector:</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:4f818259-6bd6-4faa-b1d7-99d0f9c4d170" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;jw:AwesomeScrollViewer&gt;
    &lt;StackPanel Margin="12,0,12,12"&gt;
        &lt;TextBlock
            Text="what's new"
            Margin="9,-7,0,16"
            Style="{StaticResource PhoneTextTitle1Style}"/&gt;
        &lt;ItemsControl ItemsSource="{Binding}"
                        Margin="0,0,0,24"&gt;
            &lt;ItemsControl.ItemTemplate&gt;
                &lt;DataTemplate&gt;
                    &lt;Grid Margin="12,0"&gt;
                        &lt;ContentControl
                        HorizontalContentAlignment="Stretch"
                        Content="{Binding}"
                        ContentTemplate="{Binding Converter={StaticResource DataTemplateSelector}}"/&gt;
                    &lt;/Grid&gt;
                &lt;/DataTemplate&gt;
            &lt;/ItemsControl.ItemTemplate&gt;
        &lt;/ItemsControl&gt;
    &lt;/StackPanel&gt;
&lt;/jw:AwesomeScrollViewer&gt;</pre>
</div>
<p>And at runtime we end up with this great output, now including the new <strong>v3 leaderboard feature</strong> in under 30 minutes! Building on all the other components in my app, and the rich Silverlight visual tree, I’m able to add features like this really quickly, without worry.</p>
<p>Another nice thing about XAML and data templates: typically there is very little required testing, especially if you’re in the habit of going through code reviews or at least reviewing source control diffs first – if you don’t change the shape of your data, you’re in a pretty good place.</p>
<p><img src="http://d2tz2ccf2zi8lx.cloudfront.net/media/posts/leaderboardWp7InResults.png" /></p>
<p>There are a lot of amazing efficiencies possible thanks to XAML. For instance, I have just a few instances in my app of data templates for check-ins, places, tips, etc. Then, whenever I add a new page, I can refer to the existing tip template, so there’s a central places for any visual tweaks or fixes that I make.</p>
<h3>Leaderboards to the next level</h3>
<p>So there’s also a leaderboard endpoint on the foursquare v2 web service that lets you grab the complete leaderboard of your friends. I was able to add this to the app in another 15 minutes – but that’s for another blog post. At a high level for that,</p>
<ul>
<li>I defined a new model item base that exposes a small list hierarchy – leaderboard items, leaderboard scores, and a leaderboard collection. (5 minutes) </li>
<li>Added a data loader class for the ‘leaderboard’ endpoint, powered by AgFx (5 minutes) </li>
<li>Added a new pivot item to the current users’ profile page, re-used the exact same “leaderboard” data template from the notifications window done above (5 minutes) </li>
</ul>
<p>Hope this helps. Oh, and if you’re noticing, these objects are not implementing INotifyPropertyChanged… in my app this sort of data doesn’t change at runtime. You only get a check-in report once for a check-in, with static data. Easy that way.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2011/03/4am-leaderboard-notification/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A small but important UX improvement for ScrollViewer on the Windows Phone</title>
		<link>http://www.jeff.wilcox.name/2010/12/betterscrollviewer/</link>
		<comments>http://www.jeff.wilcox.name/2010/12/betterscrollviewer/#comments</comments>
		<pubDate>Mon, 06 Dec 2010 07:32:13 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Control Development]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/12/betterscrollviewer/</guid>
		<description><![CDATA[Here’s a quick UX improvement to the scroll viewer that adds a visual indicator for the user showing them briefly the scroll bars. Interestingly, the actual phone operating system does have this concept of a hint, so I think it’s a smart addition any developer should consider while polishing their app before submission to the [...]]]></description>
			<content:encoded><![CDATA[<p>Here’s a quick UX improvement to the scroll viewer that adds a visual indicator for the user showing them briefly the scroll bars.</p>
<p>Interestingly, the actual phone operating system does have this concept of a hint, so I think it’s a smart addition any developer should consider while polishing their app before submission to the marketplace.</p>
<p>If you aren’t sure what the goal is here, go to the “settings” for the Windows Phone either in the emulator, on the real phone, or hey even the iPhone’s scroll bars all do this, so you have options.</p>
<h3>The user experience problem with the ScrollViewer for WP7</h3>
<p>There is no visual cue to the existence of the scroll bars in Silverlight applications for Windows Phone by default. I don’t know why this wasn’t done for the official control styles in the platform, but being so easy to fix, I think folks should pick this up.</p>
<p>Now that I’m finally doing some fun app coding on the weekends, I intend to share more small tidbits like this and I hope you all appreciate this sort of fit and finish attention.</p>
<p>I have also been downloading and experiencing many of the apps on the Windows Phone Marketplace, with varied success. I’ve had more than one occasion where I was briefly confused, not knowing there was more information just a pan away, since the scroll viewer is effectively invisible until you touch the surface.</p>
<h3>Triggers to the rescue</h3>
<p>Triggers were something WPF developers will remember; back in the day, before we had the magical and designable visual states system. Now if you’re saying “but dude Silverlight doesn’t support triggers,” you’re mostly right. There is, however, support for the Loaded event. So in XAML you can define a storyboard that will run when the control’s loaded event fires, super easy.</p>
<p>Exactly what we want! I want to animate that same opacity from 1 to 0 to match the normal state at startup.</p>
<h3>The BetterScrollViewer Template</h3>
<p>This is a control template, not a style. So remember to set the Template property to the static resource for it to work.</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:1af282e3-c034-4a98-a13d-109139a98b23" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;ControlTemplate TargetType="ScrollViewer" x:Key="BetterScrollViewer"&gt;
    &lt;Grid Margin="{TemplateBinding Padding}" Background="{TemplateBinding Background}"&gt;
        &lt;Grid.Triggers&gt;
            &lt;EventTrigger RoutedEvent="Grid.Loaded"&gt;
                &lt;BeginStoryboard&gt;
                    &lt;Storyboard&gt;
                        &lt;DoubleAnimation Duration="00:00:01.5" From="1" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="VerticalScrollBar"/&gt;
                        &lt;DoubleAnimation Duration="00:00:01.5" From="1" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="HorizontalScrollBar"/&gt;
                    &lt;/Storyboard&gt;
                &lt;/BeginStoryboard&gt;
            &lt;/EventTrigger&gt;
        &lt;/Grid.Triggers&gt;
        &lt;VisualStateManager.VisualStateGroups&gt;
            &lt;VisualStateGroup x:Name="ScrollStates"&gt;
                &lt;VisualStateGroup.Transitions&gt;
                    &lt;VisualTransition GeneratedDuration="00:00:00.5"/&gt;
                &lt;/VisualStateGroup.Transitions&gt;
                &lt;VisualState x:Name="Scrolling"&gt;
                    &lt;Storyboard&gt;
                        &lt;DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="VerticalScrollBar"/&gt;
                        &lt;DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="HorizontalScrollBar"/&gt;
                    &lt;/Storyboard&gt;
                &lt;/VisualState&gt;
                &lt;VisualState x:Name="NotScrolling"/&gt;
            &lt;/VisualStateGroup&gt;
        &lt;/VisualStateManager.VisualStateGroups&gt;
        &lt;ScrollContentPresenter x:Name="ScrollContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}"/&gt;
        &lt;ScrollBar x:Name="VerticalScrollBar" HorizontalAlignment="Right" Height="Auto" IsHitTestVisible="False" IsTabStop="False" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Opacity="0" Orientation="Vertical" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{TemplateBinding VerticalOffset}" ViewportSize="{TemplateBinding ViewportHeight}" VerticalAlignment="Stretch" Width="5"/&gt;
        &lt;ScrollBar x:Name="HorizontalScrollBar" HorizontalAlignment="Stretch" Height="5" IsHitTestVisible="False" IsTabStop="False" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Opacity="0" Orientation="Horizontal" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{TemplateBinding HorizontalOffset}" ViewportSize="{TemplateBinding ViewportWidth}" VerticalAlignment="Bottom" Width="Auto"/&gt;
    &lt;/Grid&gt;
&lt;/ControlTemplate&gt;</pre>
</div>
<h3>Using the template</h3>
<p>I place this template in my App.xaml then just set the template every time I use a scroll viewer.</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:43ea7a63-08dc-4ee3-a1f5-b1a6c5210ff4" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;ScrollViewer
    Template="{StaticResource BetterScrollViewer}"&gt;
&lt;/ScrollViewer&gt;</pre>
</div>
<p>Now if you want this in ListBox, you need to (unfortunately, it’s a pain) re-template ListBox. So any ListBox needs to set the template to something like BetterListBox. This template is exactly the same as the standard one except of course the static resource set in there.</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:7ea784f9-2e94-4dd5-924f-56932561e582" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;ControlTemplate TargetType="ListBox" x:Key="BetterListBox"&gt;
	&lt;ScrollViewer x:Name="ScrollViewer"
	Template="{StaticResource BetterScrollViewer}"
	BorderBrush="{TemplateBinding BorderBrush}"
	BorderThickness="{TemplateBinding BorderThickness}"
	Background="{TemplateBinding Background}"
	Foreground="{TemplateBinding Foreground}"
	Padding="{TemplateBinding Padding}"&gt;
		&lt;ItemsPresenter/&gt;
	&lt;/ScrollViewer&gt;
&lt;/ControlTemplate&gt;</pre>
</div>
<p>And to use this with just regular scroll bars, well, you’re on your own, but can use the same trigger mechanism to add it easily I bet.</p>
<h3>Notes + I removed the border!</h3>
<p>This scroll viewer template I modified also reduces the visual count by 1. I didn’t like the idea of having the scroll viewer wrapped in a border and supporting those properties, since I don’t use them. If you want to use those properties though you’ll want to build your own template from the standard to keep those template bindings in place.</p>
<p>If you’re using one of the controls like panorama or pivot, that may do some pre-loading offscreen of items, it is likely that the Loaded event will fire and trigger this animation when the user&#160; cannot actually see it.</p>
<p>So don’t expect this behavior to help in those scenarios. To really polish those you’ll need to jump into code.</p>
<p>And I picked the time of 1.5 seconds for that initial scroll appearance. If I find out from any UX folks I will try and learn what the official value is that’s used on the phone, but in the meantime, 1.5 looks about right to me.</p>
<p>Hope this helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/12/betterscrollviewer/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>A quick and easy extension to HyperlinkButton for Windows Phone 7</title>
		<link>http://www.jeff.wilcox.name/2010/11/phonehyperlinkbutton/</link>
		<comments>http://www.jeff.wilcox.name/2010/11/phonehyperlinkbutton/#comments</comments>
		<pubDate>Wed, 01 Dec 2010 04:48:01 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Control Development]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/11/phonehyperlinkbutton/</guid>
		<description><![CDATA[A quick and easy HyperlinkButton-derived control for Windows Phone that lets you set the Tag to an e-mail or web address and get the associated task goo for free.]]></description>
			<content:encoded><![CDATA[<p>While doing some application building, I naively assumed that I could just put a web address in the NavigateUri field of the HyperlinkButton control (Windows Phone 7) and have it just magically work.</p>
<p><strong><font color="#ff0000">UPDATED 12/3/2010: </font></strong>I’ve made improvements that you will find here: <a title="http://www.jeff.wilcox.name/2010/12/updated-phone-hyperlink-button/" href="http://www.jeff.wilcox.name/2010/12/updated-phone-hyperlink-button/">http://www.jeff.wilcox.name/2010/12/updated-phone-hyperlink-button/</a>&#160;</p>
<p>Turns out you need to actually handle the Click event yourself and setup the proper task for that, unless you’re doing local within-the-app navigation.</p>
<p>I wrote a super simple PhoneHyperlinkButton control that derives from HyperlinkButton. No custom template or style, so just drop the file into any project and you’re off and running.</p>
<p>Set the “Tag” property of your instance to be the URI or e-mail address you’d like the message to go to: if it starts with mailto:, then it’ll use the EmailComposeTask. Otherwise, the web browser task.</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:74b46341-d5c2-4642-906e-feed833d31b7" 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.

using System.Diagnostics;
using System.Windows.Controls;
using Microsoft.Phone.Tasks;

namespace Microsoft.Phone.Controls.Unofficial
{
    /// &lt;summary&gt;
    /// An extended HyperlinkButton control that uses the Tag property to
    /// handle web browser or e-mail compose task intended use on the phone.
    /// &lt;/summary&gt;
    public class PhoneHyperlinkButton : HyperlinkButton
    {
        protected override void OnClick()
        {
            base.OnClick();

            Debug.Assert(Tag is string, "You need to set the Tag property!");
            string tag = (string)Tag;

            int i = tag.IndexOf("mailto:");
            if (i &gt;= 0)
            {
                tag = tag.Substring(i + 7);
                EmailComposeTask ect = new EmailComposeTask
                {
                    To = tag,
                };
                ect.Show();
            }
            else
            {
                // Assume the web.
                WebBrowserTask wbt = new WebBrowserTask
                {
                    URL = (string)Tag,
                };
                wbt.Show();
            }
        }
    }
}</pre>
</div>
<p>Hope this helps. Oh, and remember that once the task completes, your app will likely be tombstoned.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/11/phonehyperlinkbutton/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>MyPhotoApp: Sample project from my Windows Phone development series at &#216;redev</title>
		<link>http://www.jeff.wilcox.name/2010/11/demo-myphotoapp/</link>
		<comments>http://www.jeff.wilcox.name/2010/11/demo-myphotoapp/#comments</comments>
		<pubDate>Tue, 16 Nov 2010 17:52:51 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Conferences]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone]]></category>
		<category><![CDATA[apps]]></category>
		<category><![CDATA[demos]]></category>
		<category><![CDATA[mvvm]]></category>
		<category><![CDATA[oredev]]></category>
		<category><![CDATA[pivot]]></category>
		<category><![CDATA[samples]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/11/demo-myphotoapp/</guid>
		<description><![CDATA[Last week I gave a multi-part series on Windows Phone development at the Øredev conference in Malmö, Sweden. Here is the sample app that was built throughout the talk. It’s a simple app that lets you pick a photoset from Flickr for a given user, then browse the photos in a nice slideshow format (swipe&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I gave a multi-part series on Windows Phone development at the <a href="http://www.oredev.org/2010">Øredev conference</a> in Malmö, Sweden. Here is the sample app that was built throughout the talk. It’s a simple app that lets you pick a photoset from Flickr for a given user, then browse the photos in a nice slideshow format (swipe&#160; to move between the photos). It’s all setup with sweet data binding and goodness.</p>
<p><a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/11/MyPhotoApp.zip">Download the zip</a> and make sure that you have the <a href="http://create.msdn.com/">Windows Phone Development Tools</a> and also the <a href="http://silverlight.codeplex.com/">Silverlight for Windows Phone Toolkit</a>.</p>
<p>This app has a number of things inside it:</p>
<ul>
<li>Simple view models</li>
<li>Simple Flickr web service layer</li>
<li>Integration of the service into the view model</li>
<li>Navigation service passing parameters to pages</li>
<li>Makes use of the <a href="http://json.codeplex.com/">JSON</a> library on CodePlex</li>
<li>Makes use of the Silverlight Toolkit for page transitions and the list picker control</li>
<li>Various examples of templating and styling</li>
<li>The Pivot control for the phone is used as a photo slide show with built-in flick and pan manipulations by not using the header or title properties, and binding the actual items to the photos to be shown</li>
<li>PerformanceProgressBar</li>
</ul>
<p>Things you need to do to get this working:</p>
<ul>
<li>You may need to add the references to the <a href="http://json.codeplex.com/">JSON library</a> as well as the toolkit before it will build for you.</li>
<li>You need a Flickr API key, <a href="http://www.flickr.com/services/apps/create/apply/">get one here</a>.</li>
<li>You need to put your API key inside the FlickrService.cs file on line 23.</li>
<li>Unless you want to browse all my photosets, you’ll want to put your own Flickr user ID string inside of MainPageViewModel.cs line 74.</li>
</ul>
<p>The talks in the series will be uploaded in the coming weeks I’ve been told, but they are not yet available.</p>
<h2>Pivot as a slide show component for photos</h2>
<p>Since pivot has the nice manipulations support built into it, it was super simple to use as a slide show-style photo viewer. Here’s the XAML I used for the slide show page:</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:4e3632a9-9910-4c5c-80fd-455485423650" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;controls:Pivot
    ItemsSource="{Binding Photos}"&gt;
    &lt;controls:Pivot.HeaderTemplate&gt;
        &lt;DataTemplate&gt;
            &lt;Grid Height="1" Width="1"/&gt;
        &lt;/DataTemplate&gt;
    &lt;/controls:Pivot.HeaderTemplate&gt;
    &lt;controls:Pivot.ItemTemplate&gt;
        &lt;DataTemplate&gt;
            &lt;Image Source="{Binding ImageUrl}"
                    /&gt;
        &lt;/DataTemplate&gt;
    &lt;/controls:Pivot.ItemTemplate&gt;
    &lt;controls:Pivot.ItemContainerStyle&gt;
        &lt;Style TargetType="controls:PivotItem"&gt;
            &lt;Setter Property="Margin" Value="0"/&gt;
            &lt;Setter Property="Padding" Value="0"/&gt;
        &lt;/Style&gt;
    &lt;/controls:Pivot.ItemContainerStyle&gt;
&lt;/controls:Pivot&gt;</pre>
</div>
<p>Walking through the elements, here is what they do.</p>
<h3>ItemsSource binding</h3>
<p>The view model for the slide show page includes a property that exposes the photo objects. This binds the pivot to that list. This means that without any of the other elements and templates being set, the pivot control will show the type name (Photo) instead of the actual photos.</p>
<p>Here’s the slide show view model file btw:</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:fd4331ad-ca66-49f3-843a-ffd56e1de05c" class="wlWriterEditableSmartContent">
<pre class="c-sharp" name="code">public class SlideshowViewModel : ViewModel
{
    private readonly IFlickrService _flickr;
    private bool _isLoading;
    private IEnumerable&lt;Photo&gt; _photos;

    public SlideshowViewModel()
        : this(new FlickrService())
    {
    }

    public SlideshowViewModel(IFlickrService flickrService)
    {
        _flickr = flickrService;
    }

    public bool IsLoading
    {
        get { return _isLoading; }
        private set
        {
            _isLoading = value;
            RaisePropertyChanged("IsLoading");
        }
    }

    public IEnumerable&lt;Photo&gt; Photos
    {
        get { return _photos; }
        set
        {
            _photos = value;
            RaisePropertyChanged("Photos");
        }
    }

    public void LoadPhotos(string photosetId)
    {
        IsLoading = true;
        _flickr.LoadPhotoset(photosetId, photos =&gt; Dispatch(() =&gt;
            {
                if (photos != null)
                {
                    Photos = photos;
                }
                IsLoading = false;
            }));
    }
}</pre>
</div>
<h3>HeaderTemplate data template</h3>
<p>This is a little bit of a Pivot control hack. You actually can set the header to x:Null, but then when you run this under the debugger, you may get a first-chance exception. The pivot control catches and continues, but it’s annoying as a developer.</p>
<p>This workaround, a 1&#215;1 grid, enables a “screen capture” to be taken of the header, avoiding the exception when it isn’t of size:</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:31221d9d-7cf4-4cb7-885f-2839df85da02" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;controls:Pivot.HeaderTemplate&gt;
    &lt;DataTemplate&gt;
        &lt;Grid Height="1" Width="1"/&gt;
    &lt;/DataTemplate&gt;
&lt;/controls:Pivot.HeaderTemplate&gt;</pre>
</div>
<p>This is all because for this slide show page, we don’t even want to show any headers, we aren’t using that visual part of the pivot ux – we’re just using the slick built-in manipulations logic and animations plus data binding.</p>
<h3>ItemTemplate data template</h3>
<p>This is what translates the data object (Photo) into an actual image that can be loaded.</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:ada8f8f9-4a63-4fce-9168-957f065bd307" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;controls:Pivot.ItemTemplate&gt;
    &lt;DataTemplate&gt;
        &lt;Image Source="{Binding ImageUrl}"
                /&gt;
    &lt;/DataTemplate&gt;
&lt;/controls:Pivot.ItemTemplate&gt;</pre>
</div>
<p>The binding to ImageUrl is for the property on the Photo data object. Sorry it was a string instead of a Uri, cheap and easy on my side I suppose.</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:b0ad5a43-253a-44f7-8085-79cd22a7296e" class="wlWriterEditableSmartContent">
<pre class="c-sharp" name="code">namespace MyPhotoApp.Flickr
{
    public class Photo
    {
        public string Id { get; set; }
        public string Title { get; set; }
        public string ImageUrl { get; set; }
    }
}
</pre>
</div>
<p>So this way the image will automatically load. A nice improvement I should have made was write some better code to make sure the images are ready to go and maybe even fade in as they’re downloaded, but for a two-minute slide show, this was all pretty easy.</p>
<h3>ItemContainerStyle for PivotItems</h3>
<p>By default, the user experience guidelines for the pivot control and pivot items are nicely set in the default styles and templates. You’ll note without using the item container style that there is spacing between the edge of the photos and the edge of the phone’s screen.</p>
<p>This is the 12 pixel margin on the left and right of the pivot items; when using the standard phone styles for things like buttons and textblocks, which include another 12px margin, this means there should be 24px on the left and right of the actual visual things inside the pivot. Things align nicely in that situation.</p>
<p>But this is a photo viewer, so we actually want to show as much of the photos as possible – so this container style says “for each new item we are creating, let’s just set the margin and padding properties to 0!”.</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:3010caac-244d-49bd-9501-20d2479d30bd" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;controls:Pivot.ItemContainerStyle&gt;
    &lt;Style TargetType="controls:PivotItem"&gt;
        &lt;Setter Property="Margin" Value="0"/&gt;
        &lt;Setter Property="Padding" Value="0"/&gt;
    &lt;/Style&gt;
&lt;/controls:Pivot.ItemContainerStyle&gt;</pre>
</div>
<h2>Navigation service usage</h2>
<p>Inside this app, the navigation service is used to go to the slideshow page. Since the slideshow page has its nice view model data bound into the DataContext, I need to use the navigation service to get the photoset ID into the page. By using the URI inside the nav service instead of using a global variable or app-level call or property set, this means that the tombstoning for the app just works.</p>
<p>If you press the Start key while in a photoset, then hit back, you’ll come back to that photoset instead of the homepage for the app.</p>
<p>Now being a sample/demo app, I didn’t fully implement the right tombstoning behavior: I also should have actually stored the pivot selected index and restored that, so they would be on the same photo, etc. I also don’t using isolated storage in this app for simplicity sake, but that must be done for a real production app of course.</p>
<p>I also don’t properly do null/empty string checks in the calls, so if no photosets are returned and you try navigating, you’ll get a null ref exception. It’s demo code!</p>
<h3>Moving to the sub-page</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:bff2b55a-702b-4780-8075-74eb3c8981fa" class="wlWriterEditableSmartContent">
<pre class="c-sharp" name="code">private void OnButtonClick(object sender, RoutedEventArgs e)
{
    NavigationService.Navigate(new Uri(
        string.Format(
        "/Views/SlideshowPage.xaml?id={0}",
        ((Photoset)SetList.SelectedItem).Id),
        UriKind.Relative));
}</pre>
</div>
<h3>Getting the photoset from the URI in the slideshow page</h3>
<p>In the page’s OnNavigatedTo event handler, I read the property from the query string if I can. I only load photos if I find a photoset ID. This does have the trouble that you’ll see a blank bit of nothing if there are no photos returned.</p>
<p>Also if you look at the implementation, you’ll note that the loading automatically happens in the view model – so I don’t have to have the code in the slideshow file worry at all about whether to show the loading indicator or not. That’s all declaratively setup in XAML. Nice.</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:959455a6-6054-43c1-bd52-7195040c4e1b" class="wlWriterEditableSmartContent">
<pre class="c-sharp" name="code">protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    var context = DataContext as SlideshowViewModel;
    if (context != null)
    {
        string id;
        if (NavigationContext.QueryString.TryGetValue("id", out id))
        {
            context.LoadPhotos(id);
        }
    }
}
</pre>
</div>
<p>And since all IDs in Flickr are to be treated as UTF8 strings, I don’t have to parse or convert the string value from the query string into an integer or anything like that.</p>
<h4>General memory note</h4>
<p>Note that you’ll want to watch your <a href="http://blogs.msdn.com/b/ptorr/archive/2010/10/30/that-memory-thing-i-promised-you.aspx">memory consumption</a> if you go this route.</p>
<p><a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/11/MyPhotoApp.zip">MyPhotoApp.zip download</a>. Hope this helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/11/demo-myphotoapp/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A less abrupt progress bar for Windows Phone developers</title>
		<link>http://www.jeff.wilcox.name/2010/11/smooth-loading-performanceprogressbar/</link>
		<comments>http://www.jeff.wilcox.name/2010/11/smooth-loading-performanceprogressbar/#comments</comments>
		<pubDate>Mon, 15 Nov 2010 19:24:36 +0000</pubDate>
		<dc:creator>Jeff Wilcox</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Control Development]]></category>
		<category><![CDATA[Windows Phone]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[performanceprogressbar]]></category>
		<category><![CDATA[phone]]></category>
		<category><![CDATA[progressbar]]></category>

		<guid isPermaLink="false">http://www.jeff.wilcox.name/2010/11/smooth-loading-performanceprogressbar/</guid>
		<description><![CDATA[Here’s a progress bar for showing loading operations that lets the animation smoothly finish before disappearing. It’s a lot more like that in the Windows Phone itself, and easy to use: just data bind to the IsLoading property (a new property; the standard IsIndeterminate still will immediately start or stop the animation, so don’t try [...]]]></description>
			<content:encoded><![CDATA[<p>Here’s a progress bar for showing loading operations that lets the animation smoothly finish before disappearing. It’s a lot more like that in the Windows Phone itself, and easy to use: just data bind to the IsLoading property (a new property; the standard IsIndeterminate still will immediately start or stop the animation, so don’t try that!).</p>
<p>This control is easier to use than my original PerformanceProgressBar implementation, since you just drop it onto a page, no need to set the style or add the style to the app.</p>
<p>As I’ve become the phone progress bar guy with the introduction of <a href="http://www.jeff.wilcox.name/2010/08/progressbarperftips2/">PerformanceProgressBar</a>, I’ve actually received a number of specific requests from people to make it easier to use. I also receive questions like “why isn’t this in the toolkit” and “when will it be fixed in the platform.” I don’t have answers to those things quite yet, but what I do have is an easier version that fulfills some very specific requests.</p>
<p>I haven’t decided yet if this is my recommended progress bar or not, so don’t quote me on saying this is perfect…</p>
<p>The source is up on GitHub at <a href="https://github.com/jeffwilcox/wpessentials/tree/master/samples/progressbar/">https://github.com/jeffwilcox/wpessentials/tree/master/samples/progressbar/</a>     <br />Download a ZIP of the <a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/11/PerformanceProgressBarSample.zip">sample app current as of 11/15/2010 here</a> (24 KB)</p>
<h2>What this sample addresses</h2>
<h3>“Let the animation complete please!”</h3>
<p>The scenario was a request by a customer to me via e-mail. Since the indeterminate storyboard has the repeat behavior of “Forever”, the Completed event never fires, which makes it difficult to allow the dots to animate completely across the screen at the end of a loading/indeterminate operation. I had to do some work to get around this limitation.</p>
<h3>Let me just drop a control on the page to make the performance version easier to use</h3>
<p>By creating a derived control, developers will find it easier to use by just dropping on a page, since the default style can contain all the nifty <a href="http://www.jeff.wilcox.name/2010/08/progressbarperftips2/">PerformanceProgressBar</a> optimizations.</p>
<h3>Optimize for just the loading/indeterminate state</h3>
<p>Most people needing these performance fixes are just using the IsIndeterminate mode. This control addresses this by just having a simple property for true/false, removing the need to also consider collapsing the regularly templated control.</p>
<h2>Using the actual PerformanceProgressBar control</h2>
<p>If you open up the project, you’ll see the files you need: a few that implement the control, plus the Generic.xaml with the default styles. To then use it on a page:</p>
<h3>Register the XMLNS</h3>
<p>In the sample project, since the control is in the project, I just use a local reference. If you place it in a class library, include the right assembly name, too.</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:30158ae5-1e8a-4c9e-8f7d-e305d8d38c2e" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">xmlns:localControls="clr-namespace:Microsoft.Phone.Controls" </pre>
</div>
<h3>Data bind or set using the IsLoading property and <font style="font-weight: bold">NOT </font>IsIndeterminate</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:9039f668-2236-41d0-bc7a-7b45981d92b2" class="wlWriterEditableSmartContent">
<pre class="xml" name="code">&lt;localControls:PerformanceProgressBar
    VerticalAlignment="Top"
    IsLoading="{Binding IsLoading}" /&gt;</pre>
</div>
<p>This is a little hacky, since I would prefer to either re-use or adapt the standard progress bar, but it was the quickly way to enable this. The IsIndeterminate property can still be set, and this will immediately turn on/off the behavior, so beware!</p>
<h3>No need to data bind the Visibility property any longer</h3>
<p>Just a note. Previously this was required to keep the standard progress bar from showing a slightly transparent background with the phone’s accent color, but my template for this indeterminate-only control takes care of the collapsing automatically.</p>
<h2>Small implementation note for performance geeks</h2>
<p>Although this control builds on the performance progress bar work I’ve done, to enable this to work, I’ve had to remove the repeat behavior of “Forever” on the animation and instead have the animation restart in code. That call happens on the UI thread, so in an extremely long and blocking operation, the restart of the animation may be delayed. Be assured that the actual animation of the dots across the screen will all still happen by the independent animations processor on the compositor thread, so no worries there, it’ll still be visually smooth. But it’s a small caveat.</p>
<h2>GitHub!</h2>
<p>I’m experimenting with using GitHub to store this kind of sample app and code in the future, as it’ll be a good place to keep track of bug fixes and changes and allow others to contribute. Thanks to <a href="http://self.d-struct.org/">Chris Gansen</a> for pointing me in the right direction.</p>
<p>My GitHub repository for phone development is at <a href="https://github.com/jeffwilcox/wpessentials/">https://github.com/jeffwilcox/wpessentials/</a> and I hope to start building that out some.</p>
<p>I eventually will add a proper controls project as a standalone class library, easy for anyone to use. Until then, I’ll just place sample apps up there. Let me know what you think about this!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/11/smooth-loading-performanceprogressbar/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>WP7 Panorama: Smoothly fading the background (and enabling fading when changing, too)</title>
		<link>http://www.jeff.wilcox.name/2010/11/wp7-panorama-smooth-background-changing/</link>
		<comments>http://www.jeff.wilcox.name/2010/11/wp7-panorama-smooth-background-changing/#comments</comments>
		<pubDate>Mon, 15 Nov 2010 02:08:47 +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/11/wp7-panorama-smooth-background-changing/</guid>
		<description><![CDATA[I’ve heard a number of conversations with developers about wanting to smoothly fade in background image changes within the Panorama control that ships in the Windows Phone 7 Developer Tools. I spent the better part of this rainy Seattle Sunday looking into this. I actually had a conversation with the famed Kelly Sommers (@kellabyte) a [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve heard a number of conversations with developers about wanting to smoothly fade in background image changes within the Panorama control that ships in the <a href="http://create.msdn.com/">Windows Phone 7 Developer Tools</a>.</p>
<p>I spent the better part of this rainy Seattle Sunday looking into this. I actually had a conversation with the famed <a href="http://kellabyte.com/">Kelly Sommers</a> (<a href="http://twitter.com/kellabyte">@kellabyte</a>) a few months ago about implementing a Panorama whose Background was automatically set to the daily Bing image, and was recently inspired by an internal developer discussion at Microsoft.</p>
<p>Here’s a video of the sample project where I was able to do just that, and more! The control takes care of smoothly fading any background property change, and the sample project grabs the daily Bing image to show in there as a sample, too.</p>
<p><object type="application/x-shockwave-flash" width="685" height="389" data="http://www.flickr.com/apps/video/stewart.swf?v=71377" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"><param name="flashvars" value="intl_lang=en-us&amp;photo_secret=d96b9daf9e&amp;photo_id=5176150607&amp;hd_default=false"></param><param name="movie" value="http://www.flickr.com/apps/video/stewart.swf?v=71377"></param><param name="bgcolor" value="#000000"></param><param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/video/stewart.swf?v=71377" bgcolor="#000000" allowfullscreen="true" flashvars="intl_lang=en-us&#038;photo_secret=d96b9daf9e&#038;photo_id=5176150607&#038;hd_default=false" height="389" width="685"></embed></object></p>
<p>So if you just want to jump in, the source is all up in the sample project in <a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/11/DynamicPanoramaBackgrounds.zip">DynamicPanoramaBackgrounds.zip download (1.2 MB)</a>.</p>
<p>Feel free to use this in your own projects, it’s a simple set of extensions. This sort of effect is nice, but I’m personally glad that it isn’t built into the framework by default: there’s definitely some fixed performance cost to this sort of dynamic effect in the platform today.</p>
<p>I did a lot of testing on my phone and didn’t run into any noticeable performance issues, but beware that this implementation will increase the fill rate and have an effect over the standard, so don’t just use it without evaluating how important the scenario is to your apps. Note that this isn’t designed to do well when moving between background Brush types, or images of massively different sizes – but if they are all the same or similar, it should just work well!</p>
<h2>Using ‘DynamicBackgroundPanorama’</h2>
<p>Just set the Background property of the Panorama!</p>
<p>You can use data binding, or just straight code, for this. The example sample I wrote has two sub pages: one which just shows the current Bing search background for your region, and another which shows some photos that are just built into the project. No special work required!</p>
<p>I’ve packaged the control and its various components into the sample project instead of building out a standalone class library, so if you place it in your project, make sure you pick up all its individual files, including the Generic\Themes.xaml file that contains the default styles.</p>
<h3>Contrasting image note</h3>
<p>I haven’t addressed the contrasting image issue in this implementation. Ideally a second brush might be exposed, to allow for a translucent overlay of color such as a transparent black, over the backgrounds. This would help with keeping the contrast more appropriate, but I didn’t want to as it would increase the fill rate even more.</p>
<h2>Designing the primitive(s)</h2>
<p>It’s pretty straightforward to think about, but difficult to implement without also building out a few primitive controls to help with the re-templating experience.</p>
<p>So in designing the right implementation, I decided to mimic the same design ideas that went into the TransitioningContentControl (TCC) that is built into the <a href="http://silverlight.codeplex.com/">Silverlight Toolkit</a>’s layout control library. With that control, the Content property (or bound Content) is used in a cycle to smoothly animate out the old content and bring in the new content.</p>
<p>I wanted the same effect, but instead with just a Brush – in most situations an ImageBrush. I went ahead and started from the open source code to the TCC, changed the content presenters in the default style and control template to no longer be needed in the same way (I just derived from Control instead of ContentControl).</p>
<p>So here are the primitive components I built out:</p>
<h3>DynamicBackgroundPanorama</h3>
<p>A one-line control that derives from the official Panorama control. The constructor sets the DefaultStyleKey to the type, enabling the style from the Generic.xaml file to be pulled in automatically.</p>
<p>This is important because this scenario is built on re-templating and just a few primitive changes, and this type lets a developer use it without having to work very hard at all.</p>
<h3>UpdatingPanningLayer</h3>
<p>This is a one-method derived control, deriving from the primitive PanningBackgroundLayer. The purpose is to call the UpdateWrappingRectangles method, a protected method. This will cause the writeable bitmaps in the control to update so that the updated image changes will also update the “ears” or left/right wrapping rectangles used to show the wrap-around effect.</p>
<h3>TransitioningBackgroundControl</h3>
<p>Starting with the Silverlight Toolkit’s TransitioningContentControl created by <a href="http://www.sitechno.com/blog/">Mr. Ruurd Boeke</a>, I changed it up to instead work from the brushes. In case anyone is interested, changes from that were basically:</p>
<ul>
<li>Moving the ContentPresenter sites from typeof ContentPresenter to Grid </li>
<li>Updating the code to specific issues with image brushes, where I’d like to wait to kick off the transition until <em>after</em> the image actually loads. Most of this code is done in the StartTransition method, plus the addition of the Loading visual state. </li>
<li>I dropped a subset of the VisualStates internal class from the toolkit into the file, just to reduce the number of unique files needed for the solution. </li>
<li>Added a dependency property of type Brush and name DynamicBackground. I could have used just the standard Background property, but that actually takes more work to wire up to ‘change’ events than to just define a new property like this. </li>
<li>A special workaround in the OnApplyTemplate to walk up the visual tree and identify the UpdatingPanningLayer, if any. This lets me force the Panorama control to effectively bump and update the side images of the control used when you scroll beyond the edges of the extreme items. </li>
<li>Updating the template:
<ul>
<li>Removing the alternative defined transitions </li>
<li>Changing the default fade-in template by removing the fade out of the current – leads to a smoother look in my opinion </li>
<li>Adding a Loading visual state to help with the delay-load effect of loading an image brush from a URI, for smoothness. </li>
<li>Adding BitmapCache settings to the two individual sites (Grids) </li>
</ul>
</li>
</ul>
<h3>Themes\Generic.xaml</h3>
<p>This file contains the custom template for Panorama as well as the important default style and template for the TransitioningBackgroundControl that I built. The differences from the official Panorama template are:</p>
<ul>
<li>The PanningLayer primitive is replaced by my UpdatingPanningLayer </li>
<li>The Border and background set in the content of the background panning layer has been replaced by my TransitioningBackgroundControl </li>
<li>The background has the margin offset to eliminate the seam </li>
<li>There is no BitmapCache setting on the background in Panorama, instead it is set within the transitioning control, for performance reasons. </li>
</ul>
<p>I’ve also taken guidance from Panorama developer extraordinaire Dave Relyea’s posts:</p>
<ul>
<li><a href="http://blogs.msdn.com/b/devdave/archive/2010/09/17/panorama-tricks-how-to-eliminate-blending-seams.aspx">Eliminating seams</a> </li>
<li><a href="http://blogs.msdn.com/b/devdave/archive/2010/09/20/panorama-using-xaml-for-your-background.aspx">Using XAML for your Background</a> </li>
</ul>
<p>Note that this project makes use of the Silverlight for Windows Phone Toolkit for transitions, so make sure you have it installed if you want to use the sample code.</p>
<h2>Download the sample project</h2>
<p><a href="http://www.jeff.wilcox.name/wp-content/uploads/2010/11/DynamicPanoramaBackgrounds.zip">Sample Project and Control Implementation [ZIP]</a> (1.2 MB)     <br />Dependencies: Windows Phone developer tools and the <a href="http://silverlight.codeplex.com/">Silverlight for Windows Phone Toolkit</a> (for transitions in the example only. The control does not have this dependency)</p>
<p>Hope this helps!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jeff.wilcox.name/2010/11/wp7-panorama-smooth-background-changing/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

