<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Shawn Burke's Blog</title><link>http://blogs.msdn.com/b/sburke/</link><description>Pushing the new stuff</description><dc:language>en</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>Using AgFx with OAuth</title><link>http://blogs.msdn.com/b/sburke/archive/2011/04/26/using-agfx-with-oauth.aspx</link><pubDate>Tue, 26 Apr 2011 16:49:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10158217</guid><dc:creator>Shawn Burke - MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/sburke/rsscomments.aspx?WeblogPostID=10158217</wfw:commentRss><comments>http://blogs.msdn.com/b/sburke/archive/2011/04/26/using-agfx-with-oauth.aspx#comments</comments><description>&lt;h2&gt;New Release&lt;/h2&gt;
&lt;p&gt;First, if you wander on over to the &lt;a href="http://agfx.codeplex.com"&gt;AgFx CodePlex&lt;/a&gt; site, you'll see that there is a&lt;a href="http://agfx.codeplex.com/releases/view/65210"&gt; new release&lt;/a&gt; up. &amp;nbsp;There's some new things in this new release such as some statistics about the performance of your application, the ability to specify exact cache expiration, and some bug fixes. &amp;nbsp;The majority of feedback that I have gotten has been feature requests or "how do I?", and few in the way of bug reports. &amp;nbsp;So it's working well for most people, hopefully that continues. &amp;nbsp;Please file bugs if you find them!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;All of the below references the code sample that you can find in the CodePlex source tree at&lt;a target="_blank" href="http://agfx.codeplex.com/SourceControl/changeset/view/72308#1809898"&gt; AgFx\Samples\Facebook.Auth.Sample&lt;/a&gt;.&amp;nbsp; &lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;OAuth with Facebook and AgFx on Windows Phone 7&lt;/h2&gt;
&lt;p&gt;Something applications commonly want to do is to use Facebook as their credentials system instead of hand-rolling one. &amp;nbsp;For many types of applications this makes good sense, but it turns out that integrating a Windows Phone 7 application with Facebook can be a bit challenging.&lt;/p&gt;
&lt;p&gt;So with this release, you'll see a new sample called Facebook.Auth.Sample that gives you a template to start from that will hopefully make your life easier.&lt;/p&gt;
&lt;p&gt;In case you're new to OAuth, it's basically a way to establish credentials without allowing the calling application to ever see a username or password. &amp;nbsp;So instead of some kind of a web service call like &lt;span style="font-family: 'courier new', courier;"&gt;service.login(username, password)&lt;/span&gt;, &amp;nbsp;instead you have a bit of a round-about pattern that looks like the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The calling application directs a web browser to an auth url. &amp;nbsp;Imagine something like &lt;span style="font-family: 'courier new', courier;"&gt;http://www.somesite.com/oauth?appid=12345&amp;amp;redirect_uri=http://www.myapplication.com/authcomplete&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;The user enters the SomeSite credentials into the web page and submits.&lt;/li&gt;
&lt;li&gt;If the credentials are correct, SomeSite issues a redirect to something like &lt;span style="font-family: 'courier new', courier;"&gt;http://www.myapplication.com/authcomplete#access_token=ABCD1234&amp;amp;expires_in=3600&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;For mobile appliacations "authcomplete" may be a dummy URL, it's just there as away to get the values. &amp;nbsp;So the application traps the Navigating event on the browser, sees the token, grabs it off of the URL, and ends the process. &amp;nbsp;What the application really cares about is access_token. &amp;nbsp;In the case of Facebook, they have a landing page called &lt;span style="font-family: 'courier new', courier;"&gt;login_success.html&lt;/span&gt; that we can use without having to set up a server.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Because there isn't a direct service call here, AgFx isn't set up to really handle this process. &amp;nbsp;It wants a URL to call and a response to parse. &amp;nbsp;We can't do that, but it's still nice to use the caching and databinding-friendly features of AgFx, so we can craft a hybrid solution.&lt;/p&gt;
&lt;p&gt;The strategy is basically as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Complete the process above for Facebook&lt;/li&gt;
&lt;li&gt;Once we have a token and expiration time, stash it on a LoadContext for our &lt;span style="font-family: 'courier new', courier;"&gt;FacebookLoginModel&lt;/span&gt; (derives from LoginModel)&lt;/li&gt;
&lt;li&gt;Have AgFx kick off a Load for that load context.&lt;/li&gt;
&lt;li&gt;Instead of returning a &lt;span style="font-family: 'courier new', courier;"&gt;WebLoadRequest&lt;/span&gt;, which fetches a URL, we create a custom LoadRequest (&lt;span style="font-family: courier new,courier;"&gt;FacebookLoadRequest&lt;/span&gt;)&amp;nbsp;that just serializes the token/expiration into a Stream and returns that.&lt;/li&gt;
&lt;li&gt;The result of that load will be an instance of &lt;span style="font-family: 'courier new', courier;"&gt;FacebookLoginModel&lt;/span&gt; with the Token available for us to call, and now AgFx has data that it can manage via the regular caching mechanism.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With that in hand, we're in good shape, and we can start making other calls out to Facebook.&amp;nbsp; It is a little goofy that we take data that we have in hand, write it to a stream, and just read it back out again.&amp;nbsp; But OAuth itself is a bit odd compared to the rest of the direct call APIs out there.&amp;nbsp; So this is the price we pay.&amp;nbsp; It's a small one.&lt;/p&gt;
&lt;p&gt;Take a look at &lt;a href="http://agfx.codeplex.com/SourceControl/changeset/view/72308#1809898"&gt;FacebookLoginModel&lt;/a&gt; for details of how this dance works.&lt;/p&gt;
&lt;h2&gt;Login UI with PhoneApplicationFrameEx&lt;/h2&gt;
&lt;p&gt;PhoneApplicationFrameEx has a property on it called "PopupContent". &amp;nbsp;This content will be shown over the top of the UI (e.g. over the current Page) whenever IsPopupContentVisible is set to true.&lt;/p&gt;
&lt;p&gt;We can use this to make the login UI show automatically whenever the user is not logged in, and disappear automatically when a login succeeds. &amp;nbsp;If you look in the samples App.xaml.cs, you'll see the following:&lt;/p&gt;
&lt;pre class="scroll"&gt;&lt;code class="csharp"&gt;// Here we set up the frame binding.&lt;br /&gt;
//&lt;br /&gt;
// the below says:&lt;br /&gt;
//      "When the FacebookLoginModel.Current.IsLoggedIn property is FALSE, &lt;br /&gt;
//       set the PhoneApplicationFrameEx.IsPopupVisible to true.  Or vice-versa."&lt;br /&gt;
//&lt;br /&gt;
RootFrame.PopupContent = loginView;&lt;br /&gt;
Binding b = new Binding("IsLoggedIn");&lt;br /&gt;
b.Source = FacebookLoginModel.Current;&lt;br /&gt;
b.Converter = new NotConverter();&lt;br /&gt;
RootFrame.SetBinding(PhoneApplicationFrameEx.IsPopupVisibleProperty, b);&lt;/code&gt;&lt;/pre&gt;
&lt;pre class="scroll"&gt;&lt;code class="csharp"&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which basically takes the F&lt;span style="font-family: 'courier new', courier;"&gt;acebookLoginModel.IsLoggedIn&lt;/span&gt; property and binds it's opposite to the IsPopupVisible property on the Frame. &amp;nbsp;So, when the app starts for the first time, no cached creds will be available, and the login UI will show. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;In the sample, the login UI is pretty much just the WebBrowser control, but I added an overlay that updates status when navigations and processing is happening. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;See &lt;span style="font-family: 'courier new', courier;"&gt;FacebookLoginView&lt;/span&gt; in the sample:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x325/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97/6471.fb_5F00_login.png" border="0" /&gt;&lt;img height="325" src="http://blogs.msdn.com/resized-image.ashx/__size/550x300/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97/0458.fb_5F00_login.jpg" border="0" /&gt;&lt;/p&gt;
&lt;p&gt;Upon logging in, the app fetches the full name of the user that logged in.&lt;/p&gt;
&lt;h2&gt;Making Service Calls&lt;/h2&gt;
&lt;p&gt;Once we are logged in, making service calls is easy. &amp;nbsp;In the case of the sample, there is a very basic ViewModel called FacebookUser. &amp;nbsp;By default, I just call the "me" user, which returns the information for the logged in user. &amp;nbsp;It works like a standard AgFx model, and here's an example of it's GetLoadRequst:&lt;/p&gt;
&lt;pre class="scroll"&gt;&lt;code class="csharp"&gt;public LoadRequest GetLoadRequest(LoadContext loadContext, Type objectType) {&lt;br /&gt;
&lt;br /&gt;
    // abort if we don't have a token.&lt;br /&gt;
    //&lt;br /&gt;
    if (!FacebookLoginModel.Current.IsLoggedIn) {&lt;br /&gt;
        return null;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // build the "me" url including the auth token.&lt;br /&gt;
    //&lt;br /&gt;
    string meUri = String.Format("https://graph.facebook.com/{0}?access_token={1}", loadContext.Identity, FacebookLoginModel.Current.Token);&lt;br /&gt;
&lt;br /&gt;
    return new WebLoadRequest(loadContext, new Uri(meUri));&lt;br /&gt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And in Deserialize, you'd typically want to use a JSON parser to pick out the data, which comes back from Facebook as JSON. &amp;nbsp;For brevity in the sample,&amp;nbsp;I'm using a Regex, which is not an industrial strength solution! &amp;nbsp;In this case, the only value we grab is the user's full name, which then ends up bound into the UIs.&lt;/p&gt;
&lt;p&gt;All calls you make should access the &lt;span style="font-family: 'courier new', courier;"&gt;FacebookLoginModel.Current.Token&lt;/span&gt; property to access the access_token, &amp;nbsp;and a good pattern to handle log outs and other errors is to create a base DataLoader (like FacebookDataLoaderBase, for example), that has unified handling for errors and scenarios where the token has expired. &amp;nbsp;If that's the case, you have one place to go clear the login state. &amp;nbsp;Which, if you may have guessed, will automatically pop the login UI. &amp;nbsp;Then derive your model DataLoaders from that type and do your model-specific processing.&lt;/p&gt;
&lt;h2&gt;Challenges Along the Way&lt;/h2&gt;
&lt;p&gt;Getting this to work was a bit harder than I expected, so I'm glad I took the time to work through the scenario.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;There were three issues:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;On a redirect, the Windows Phone 7 WebBrowser control has a bug that strips everything after the #. &amp;nbsp;If you'll look up at the OAuth process, you'll see that there's a hash at step 3. &amp;nbsp;This is a big problem because we lose the exact information we need. &amp;nbsp;There is a workaround, but involves an extra redirect, and worse than that, involves needing to have the app's secret embedded in the code. &amp;nbsp;I'm making sure this gets fixed for the next phone release. &amp;nbsp;&lt;/li&gt;
&lt;li&gt;Logging out of Facebook turns out to be challenging. &amp;nbsp;If you search the web for "Facebook OAuth logout", you'll find lots of long, complicated threads of people trying to solve this problem. &amp;nbsp;The issue is that there isn't a clean way of killing an access_token. &amp;nbsp;So what happens is that you tell AgFx to logout and clear the LoginModel state, then redirect the web browser to the oauth page, and it just logs you right back in again because of a browser cookie that's hard to get to. &amp;nbsp;After a fair amount or wrestling, I managed to detect this case and then redirect to &lt;span style="font-family: 'courier new', courier;"&gt;http://www.facebook.com/logout.php&lt;/span&gt;, wait for that to complete, then to back to the auth page. &amp;nbsp;That seems to work, but I'm not in love with the solution.&lt;/li&gt;
&lt;li&gt;There are hiccups in the Facebook OAuth process.&amp;nbsp; For example, if the user is logging in from a device for the first time, they will be directed to the Facebook page that lets you name the device.&amp;nbsp; Unfortunately this doesn't perisist the redirect so the process dies.&amp;nbsp; With some more code you could work around this, but if you don't, the user ends up on their home page.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &amp;nbsp;sample project handles both of these cases so you can use it as a template for your own Facebook or other OAuth integrations. &amp;nbsp;I believe that Facebook uses standard OAuth, so it should port to another service cleanly, but I have not verified this. &amp;nbsp;The pattern should be about the same.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10158217" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/sburke/archive/tags/Windows+Phone+7/">Windows Phone 7</category><category domain="http://blogs.msdn.com/b/sburke/archive/tags/AgFx/">AgFx</category></item><item><title>AgFx now on CodePlex</title><link>http://blogs.msdn.com/b/sburke/archive/2011/04/01/agfx-now-on-codeplex.aspx</link><pubDate>Fri, 01 Apr 2011 22:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10149006</guid><dc:creator>Shawn Burke - MSFT</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/sburke/rsscomments.aspx?WeblogPostID=10149006</wfw:commentRss><comments>http://blogs.msdn.com/b/sburke/archive/2011/04/01/agfx-now-on-codeplex.aspx#comments</comments><description>&lt;p&gt;Today, the &lt;a target="_blank" href="http://agfx.codeplex.com/"&gt;CodePlex AgFx&lt;/a&gt; site went live, with a new updated release.&lt;/p&gt;
&lt;p&gt;Quite a few folks are now building Windows Phone 7 apps on AgFx and are having good luck with it.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve written a few more walkthroughs and detail pages on the &lt;a target="_blank" href="http://agfx.codeplex.com/documentation"&gt;documentation&lt;/a&gt; tab, and the release now includes a help CHM file. &lt;/p&gt;
&lt;p&gt;Along with some bug fixes the Release on CodePlex adds:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The ability to manually push items into the cache with the DataManager.Current.Save method&lt;/li&gt;
&lt;li&gt;Helper classes for handling login and credentials management with AgFx (AgFx.Controls.Phone.Authentication)&lt;/li&gt;
&lt;li&gt;A derived PhoneApplicaitonFrame type (creatively named PhoneApplicationFrameEx) that gives support for
&lt;ul&gt;
&lt;li&gt;An app-wide header area for something like a loading progress bar&lt;/li&gt;
&lt;li&gt;A PopupContent property that makes it easy to pop UI over the current page for things like login or &amp;ldquo;Loading&amp;hellip;&amp;rdquo; UI.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A CachePolicy of CachePolicy.Forever that keeps things in the cache indefinitely.&amp;nbsp; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are some additional features in the tree that didn&amp;rsquo;t make it into the initial release as well:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The ability for model items to specify their cache duration.&amp;nbsp; Before this had to be statically declared as part of the CachePolicyAttribute.&amp;nbsp; Now an object can override that and provide an exact time for it&amp;rsquo;s cache to expire.&amp;nbsp; If CachePolicy.AutoRefresh is specified, a reload will happen automatically at that time.&lt;/li&gt;
&lt;li&gt;AgFx knows a lot about what your app is up to, so I added some functionality to keep some statistics around that info.&amp;nbsp; AgFx will build a report on this data for you on-demand, and it gives you a lot of insight into what your apps is up to:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To enable this, I just need to write the following code at startup.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;DataManager.ShouldCollectStatistics = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;And everything happens automatically.&amp;nbsp; I can fetch the data as follows:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;StringWriter writer = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringWriter();
AgFx.DataManager.Current.GetStatisticsReport(writer, &lt;span class="kwrd"&gt;false&lt;/span&gt;);
writer.Flush();
&lt;span class="kwrd"&gt;string&lt;/span&gt; output = writer.ToString();&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Here is an example of the output for the sample NWS weather application.&amp;nbsp; In this case, I started the app, requested weather for a few different zip codes, closed the app, then did a few more request, some new, some repeated.&lt;/p&gt;
&lt;p&gt;As you can see I get a lot of data about my network requests (called &amp;ldquo;fetch&amp;rdquo;) below, my deserialization, and how many objects of each type I was managing.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: 'Courier New'; "&gt;Totals:
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total Instances: 6
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total Requests: 10
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total Fetches: 5
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total Fetch Failures: 0
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total Deserialization Failures: 0
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Cache Hit Rate: 0.50
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Average Fetch Time: 546.1ms
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Maximum Fetch Time: 2780.0ms (Object Type=WeatherForecastVm, ID=98109)
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Average Deserialize Time: 19.8ms
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Maximum Deserialize Time: 84.0ms (Object Type=WeatherForecastVm, ID=98112)
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Average Deserialize Size: 7287.5 bytes
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Maximum Deserialize Size: 14437 bytes (Object Type=WeatherForecastVm, ID=98033)
    &lt;br /&gt;Statistics for NWSWeather.Sample.ViewModels.WeatherForecastVm:
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total Instances: 3
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total Requests: 4
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total Fetches: 3
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total Fetch Failures: 0
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total Deserialization Failures: 0
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Cache Hit Rate: 0.33
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;Average Fetch Time: 997.5ms
      &lt;br /&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Maximum Fetch Time: 2780.0ms (Object Type=WeatherForecastVm, ID=98109)
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Average Deserialize Time: 29.7ms
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Maximum Deserialize Time: 84.0ms (Object Type=WeatherForecastVm, ID=98112)
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;em&gt;Average Deserialize Size: 14351.7 bytes
      &lt;br /&gt;&lt;/em&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Maximum Deserialize Size: 14437 bytes (Object Type=WeatherForecastVm, ID=98033)
    &lt;br /&gt;Statistics for NWSWeather.Sample.ViewModels.ZipCodeVm:
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total Instances: 3
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total Requests: 6
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total Fetches: 2
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total Fetch Failures: 0
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Total Deserialization Failures: 0
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Cache Hit Rate: 0.67
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;Average Fetch Time: 94.7ms&lt;/strong&gt;
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Maximum Fetch Time: 195.0ms (Object Type=ZipCodeVm, ID=98109)
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Average Deserialize Time: 10.0ms
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Maximum Deserialize Time: 29.0ms (Object Type=ZipCodeVm, ID=98112)
    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;em&gt;Average Deserialize Size: 223.3 bytes
      &lt;br /&gt;&lt;/em&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Maximum Deserialize Size: 224 bytes (Object Type=ZipCodeVm, ID=98033)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Notice&lt;strong&gt; how much faster&lt;/strong&gt; the Zip Code service is that the Weather Service!&amp;nbsp; Of course, it&amp;rsquo;s a &lt;em&gt;lot less data&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10149006" width="1" height="1"&gt;</description></item><item><title>My Visual Studio snippets</title><link>http://blogs.msdn.com/b/sburke/archive/2011/03/29/my-visual-studio-snippets.aspx</link><pubDate>Tue, 29 Mar 2011 22:58:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10147415</guid><dc:creator>Shawn Burke - MSFT</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/sburke/rsscomments.aspx?WeblogPostID=10147415</wfw:commentRss><comments>http://blogs.msdn.com/b/sburke/archive/2011/03/29/my-visual-studio-snippets.aspx#comments</comments><description>&lt;p&gt;One of the great features of Visual Studio, that&amp;rsquo;s been around for a while is snippets.&amp;nbsp; Frankly, I should build more of these because I use them *so* often.&lt;/p&gt;
&lt;p&gt;I find them so useful I thought I&amp;rsquo;d share them here, either for you to use or to template into ones of your own.&lt;/p&gt;
&lt;p&gt;Firs t,when building templated controls I write this a lot:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;[TemplatePart(Name = ElementContent, Type = &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(FrameworkElement))]&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;And it&amp;rsquo;s not just that, I then have to create a constant to define &amp;ldquo;ElementContent&amp;rdquo; and then usually load that value into a member variable as part of OnApplyTemplate.&lt;/p&gt;
&lt;p&gt;So I built a snippet that builds this stuff out for me, resulting in this:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;    [TemplatePart(Name = ElementContent, Type = &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(FrameworkElement))]
    &lt;span class="rem"&gt;//private const string ElementContent = "Content_FrameworkElement";&lt;/span&gt;
    &lt;span class="rem"&gt;//private FrameworkElement _Content;&lt;/span&gt;
    //_Content = (FrameworkElement)GetTemplatePart(ElementContent);&lt;/pre&gt;
&lt;p&gt;


&lt;/p&gt;
&lt;p&gt;Which gives me some extra code commented below that I can just copy down into the class.&amp;nbsp; Nice!&lt;/p&gt;
&lt;p&gt;Building snippets is easy, it&amp;rsquo;s just an XML format.&amp;nbsp;&amp;nbsp; It works great, just add the folder to VS via the Snippet Manager (&lt;strong&gt;Tools &amp;ndash;&amp;gt; Code Snippets Manager&lt;/strong&gt;).&lt;/p&gt;
&lt;p&gt;In my case, I have a snippets folder on Live Mesh that gets replicated to all the places I write code, so I always have my snippets.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/0804.image_5F00_04657393.png"&gt;&lt;img height="484" width="470" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/3058.image_5F00_thumb_5F00_4356F42E.png" alt="image" border="0" title="image" 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" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="kwrd"&gt;For the snippet above, the xml looks like this:&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="utf-8" ?&amp;gt;&lt;br /&gt;&amp;lt;CodeSnippets&amp;nbsp; xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;CodeSnippet Format="1.0.0"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Header&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Title&amp;gt;Template Part Declaration&amp;lt;/Title&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Shortcut&amp;gt;&lt;span style="background-color: #ffff00;"&gt;template_part&lt;/span&gt;&amp;lt;/Shortcut&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Description&amp;gt;Template Part Decl&amp;lt;/Description&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Author&amp;gt;Shawn Burke&amp;lt;/Author&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;SnippetTypes&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;SnippetType&amp;gt;&lt;span style="background-color: #ffff00;"&gt;Expansion&lt;/span&gt;&amp;lt;/SnippetType&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/SnippetTypes&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Header&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Snippet&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Declarations&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Literal&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ID&amp;gt;&lt;span style="background-color: #00ff00;"&gt;name&lt;/span&gt;&amp;lt;/ID&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ToolTip&amp;gt;Template Part Name&amp;lt;/ToolTip&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Default&amp;gt;PartName&amp;lt;/Default&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Literal&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Literal&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ID&amp;gt;&lt;span style="background-color: #4bacc6;"&gt;type&lt;/span&gt;&amp;lt;/ID&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ToolTip&amp;gt;Element Type&amp;lt;/ToolTip&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Default&amp;gt;type&amp;lt;/Default&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Literal&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Declarations&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Code Language="&lt;span style="background-color: #ffff00;"&gt;csharp&lt;/span&gt;"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;![CDATA[&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [TemplatePart(Name = Element&lt;span style="background-color: #00ff00;"&gt;$name$&lt;/span&gt;, Type = typeof(&lt;span style="background-color: #4bacc6;"&gt;$&lt;span&gt;type&lt;/span&gt;$&lt;/span&gt;))]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //private const string Element&lt;span style="background-color: #00ff00;"&gt;$name$&lt;/span&gt; = "&lt;span style="background-color: #00ff00;"&gt;$name$&lt;/span&gt;_&lt;span style="background-color: #4bacc6;"&gt;$type$&lt;/span&gt;";&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //private &lt;span style="background-color: #4bacc6;"&gt;$type$&lt;/span&gt; _&lt;span style="background-color: #00ff00;"&gt;$name$&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //_&lt;span style="background-color: #00ff00;"&gt;$name$&lt;/span&gt; = (&lt;span style="background-color: #4bacc6;"&gt;$type$&lt;/span&gt;)GetTemplatePart(Element$name$);&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;$end$]]&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Code&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Snippet&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/CodeSnippet&amp;gt;&lt;br /&gt;&amp;lt;/CodeSnippets&amp;gt;&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s pretty simple, I&amp;rsquo;ve highlighted the interesting parts. There are much fancier things you can do with snippets which I should probably learn.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a list of the ones I use regularly, and a zip of all of them attached to this post.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create an INotifyPropertyChanged class implementation &amp;ndash; inpc_impl&lt;/li&gt;
&lt;li&gt;Create a property that raises a INotifyPropertyChange.PropertyChanged event &amp;ndash; inpc_prop (I probably use this one the most)&lt;/li&gt;
&lt;li&gt;Create a Silverlight/Phone formatted Dependency Property with a change handler &amp;ndash; propdpsl&lt;/li&gt;
&lt;li&gt;Create a template part attiibute (above) &amp;ndash; template_part&lt;/li&gt;
&lt;li&gt;Create a template visual state attribute &amp;ndash; template_visualstate&lt;/li&gt;
&lt;li&gt;Create a wrapper for an async call to an Service Reference proxy &amp;ndash; svca&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The last one generates this code, for a method called GetComments, which gives me nice lambda handlers for success and error cases, which is the pattern I use for most calls to a generated proxy.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; &lt;span style="background-color: #ffff00;"&gt;GetComments&lt;/span&gt;(&lt;span class="kwrd"&gt;&lt;span style="background-color: #ffff00;"&gt;string&lt;/span&gt;&lt;/span&gt; &lt;span style="background-color: #ffff00;"&gt;postId&lt;/span&gt;, Action&amp;lt;&lt;span style="background-color: #ffff00;"&gt;IEnumerable&amp;lt;Comment&amp;gt;&lt;/span&gt;&amp;gt; success, Action&amp;lt;Exception&amp;gt; error) {
            var ws = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span style="background-color: #ffff00;"&gt;BlogService&lt;/span&gt;Client();

            ws.&lt;span style="background-color: #ffff00;"&gt;GetComments&lt;/span&gt;Completed += (s, a) =&amp;gt;
            {

                &lt;span class="kwrd"&gt;if&lt;/span&gt; (a.Error != &lt;span class="kwrd"&gt;null&lt;/span&gt;) {
                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (error != &lt;span class="kwrd"&gt;null&lt;/span&gt;) {
                        error(a.Error);
                    }
                    &lt;span class="kwrd"&gt;else&lt;/span&gt; {
                        HandleError(ws, &lt;span class="str"&gt;"&lt;span style="background-color: #ffff00;"&gt;GetComments&lt;/span&gt;"&lt;/span&gt;, a.Error);
                    }
                }
                &lt;span class="kwrd"&gt;else&lt;/span&gt; {
                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (success != &lt;span class="kwrd"&gt;null&lt;/span&gt;) {
                        success(a.Result);
                    }
                }
                ws.Close();
            };
            ws.&lt;span style="background-color: #ffff00;"&gt;GetComments&lt;/span&gt;Async(postId);
        }
        &lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;The highlighted parts are template parameters.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10147415" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-14-74-15/snippets.zip" length="4280" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/b/sburke/archive/tags/Silverlight/">Silverlight</category><category domain="http://blogs.msdn.com/b/sburke/archive/tags/Windows+Phone+7/">Windows Phone 7</category></item><item><title>Tutorial: Building a connected phone app with AgFx</title><link>http://blogs.msdn.com/b/sburke/archive/2011/03/17/tutorial-building-a-connected-phone-app-with-agfx.aspx</link><pubDate>Thu, 17 Mar 2011 21:39:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10142810</guid><dc:creator>Shawn Burke - MSFT</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/sburke/rsscomments.aspx?WeblogPostID=10142810</wfw:commentRss><comments>http://blogs.msdn.com/b/sburke/archive/2011/03/17/tutorial-building-a-connected-phone-app-with-agfx.aspx#comments</comments><description>&lt;p&gt;Earlier this week I &lt;a href="http://blogs.msdn.com/b/sburke/archive/2011/03/11/build-great-windows-phone-applications-the-easy-way.aspx" target="_blank"&gt;wrote a post&lt;/a&gt; detailing the application framework that I&amp;rsquo;ve been working on, which I&amp;rsquo;m calling AgFx.&amp;nbsp; I wanted that post to be a bit of an introductory overview,. Now I&amp;rsquo;m going to dig into detail a bit more, as well as show a bit about how you can use the free Windows Phone 7 Developer tools to quickly create a great application.&amp;nbsp; AgFx does a lot, and one of the apps I used to generate requirements and testing, is Jeff Wilcox&amp;rsquo;s gorgeous new foursquare&amp;trade; client: &lt;a href="http://www.4thandmayor.com/" target="_blank"&gt;4th &amp;amp; Mayor&lt;/a&gt;, which is built on AgFx.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Jeff and I, along with some others, have written several apps on top of AgFx over the last few months, and have really sharpened it to be exactly what you need when building a connected phone application.&amp;nbsp; And the steps that you use to do it are almost always the same, and I&amp;rsquo;ll detail them here.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re thinking about writing an app that talks to a web service of any kind, go ahead and follow along with that example in your head.&lt;/p&gt;
&lt;p&gt;Below is pretty long and comprehensive, but it is not only a basic tutorial, it is also a summary of some of the broader set of features in AgFx.&amp;nbsp; So it may give you some ideas about how to use AgFx for your next Phone application, or even your current one!&amp;nbsp; We have moved several existing data-connected applications to AgFx and in every case the code becomes smaller, simpler, and better performing. &lt;/p&gt;
&lt;h2&gt;Step 1: Figure out what data you&amp;rsquo;ll be using&lt;/h2&gt;
&lt;p&gt;The first step is to go take a look at the data that the web service offers and how you can process it.&amp;nbsp; In this example case we&amp;rsquo;ll be using the &lt;a href="http://www.weather.gov/forecasts/xml/rest.php" target="_blank"&gt;NOAA National Weather Service REST Web Service&lt;/a&gt;.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;So we go to the website above an look at what the web service offers.&amp;nbsp; Looking through at their service operations, I see this one:&lt;/p&gt;
&lt;ul&gt;
&lt;strong&gt;Summarized Data for One or More Zipcodes&lt;/strong&gt;: Returns DWML-encoded NDFD data for one ore more zip codes (50 United States and Puerto Rico). 
&lt;/ul&gt;
&lt;p&gt;Which sounds about right.&amp;nbsp; Give it a zip code, get back weather data.&amp;nbsp; And there is an example for a query there as well:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a title="http://www.weather.gov/forecasts/xml/sample_products/browser_interface/ndfdBrowserClientByDay.php?zipCodeList=98052&amp;amp;format=12+hourly&amp;amp;numDays=7" href="http://www.weather.gov/forecasts/xml/sample_products/browser_interface/ndfdBrowserClientByDay.php?zipCodeList=98052&amp;amp;format=12+hourly&amp;amp;numDays=7"&gt;http://www.weather.gov/forecasts/xml/sample_products/browser_interface/ndfdBrowserClientByDay.php?zipCodeList=98052&amp;amp;format=12+hourly&amp;amp;numDays=7&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We like things that we can easily build a query string from.&amp;nbsp; AgFx supports more complex operations, but these GET queries are a slam dunk.&amp;nbsp; If you click on that link, you&amp;rsquo;ll get a bunch of XML data.&amp;nbsp; It&amp;rsquo;s a little hairy, but the data is there so all we need to do is parse it, which is easy enough.&amp;nbsp; OK, weather data: check.&lt;/p&gt;
&lt;p&gt;One thing it does not give us, though, is the name of the city for the zip code.&amp;nbsp; It gives us the latitude and longitude, but that&amp;rsquo;s not that helpful really.&amp;nbsp; We want to be able to display the name of the city for a given zip code, and we can get that from &lt;a href="http://webservicex.net" target="_blank"&gt;WebServiceX.NET&lt;/a&gt;, &lt;a href="http://www.webservicex.net/ws/WSDetails.aspx?WSID=42&amp;amp;CATID=7" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;WebServiceX.net provides an API for converting a zip code into a city and state name.&lt;/p&gt;
&lt;p&gt;Basically we call this:&amp;nbsp; &lt;a title="http://www.webservicex.net/uszip.asmx/GetInfoByZIP?USZip=98052" href="http://www.webservicex.net/uszip.asmx/GetInfoByZIP?USZip=98052"&gt;http://www.webservicex.net/uszip.asmx/GetInfoByZIP?USZip=98052&lt;/a&gt;, and we get this:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;="1.0"&lt;/span&gt; &lt;span class="attr"&gt;encoding&lt;/span&gt;&lt;span class="kwrd"&gt;="utf-8"&lt;/span&gt;?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;NewDataSet&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Table&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;CITY&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Redmond&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;CITY&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;STATE&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;WA&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;STATE&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ZIP&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;98052&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ZIP&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;AREA_CODE&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;425&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;AREA_CODE&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TIME_ZONE&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;P&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;TIME_ZONE&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Table&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;NewDataSet&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Perfect!&amp;nbsp; City name: check.&lt;/p&gt;
&lt;h2&gt;Step 2: Define your identifiers and LoadContexts&lt;/h2&gt;
&lt;p&gt;Now it&amp;rsquo;s time to start writing the code to talk to the service.&lt;/p&gt;
&lt;p&gt;The first thing to think about is the shape of the objects coming back from the service, and what is their &lt;strong&gt;unique identifier&lt;/strong&gt;.&amp;nbsp; In database terms, this would be the primary key.&amp;nbsp; Given that key, I expect to get the correct data back, and that data should be discreet from calls using different keys.&lt;/p&gt;
&lt;p&gt;In the weather case, the weather data is basically a set of weather forecast objects.&amp;nbsp; They always come together as a group and this app will never talk to them individually &amp;ndash; it&amp;rsquo;s the collection of objects that makes up the data we care about.&amp;nbsp; We don&amp;rsquo;t care about addressing the individual forecasts, so the zip code works great as the identifier for our forecast.&lt;/p&gt;
&lt;p&gt;For the zip code information, it&amp;rsquo;s even easier, the data is tied directly to the zip code, so that&amp;rsquo;s also the unique identifier here.&lt;/p&gt;
&lt;p&gt;Before we go on, let&amp;rsquo;s think of some other examples.&lt;/p&gt;
&lt;p&gt;Imagine you were talking to the Flickr service.&amp;nbsp; Flickr has identifiers on almost every object.&amp;nbsp; For example the identifier for my user profile on Flickr is &amp;ldquo;78467353@N00&amp;rdquo;.&amp;nbsp; If I was to write a model for my Flickr user profile, I&amp;rsquo;d use that as my identifier.&amp;nbsp; The same goes for a model that represents my PhotoStream, because that&amp;rsquo;s tied to my user account.&amp;nbsp; But a model for an individual album or photo would use the id associated with that item.&amp;nbsp; And so on.&lt;/p&gt;
&lt;p&gt;This identifer is how you&amp;rsquo;ll ask for data from AgFx, so that&amp;rsquo;s why it&amp;rsquo;s important, we&amp;rsquo;ll see more about this later:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;DataManager.Current.Load&amp;lt;ZipCodeVm&amp;gt;(txtZipCode.Text);&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, back to &lt;strong&gt;LoadContext&lt;/strong&gt; what&amp;rsquo;s going on with that guy?&amp;nbsp; Good question.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;LoadContext&lt;/strong&gt; is where I store data that will be used to make a request for my data.&amp;nbsp; For example, if I want to request a photos on Flickr from a photo album, I may want to pass in paging information, or information about how many items to return.&amp;nbsp; The LoadContext is where I would put that information, the reason why will be clear later.&amp;nbsp; LoadContext really exists for more sophisticated cases and in the case of simple requests, like those for the weather app, you won&amp;rsquo;t need to bother with it much.&amp;nbsp; But you&amp;rsquo;ll see it in the API so you should understand what it&amp;rsquo;s for.&lt;/p&gt;
&lt;p&gt;Even in simple cases, it also gives you a chance to make things strongly typed.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;If you look at the base LoadContext:&lt;/p&gt;
&lt;pre&gt;&amp;nbsp; public class LoadContext {&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public object Identity { get; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string UniqueKey {get;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public LoadContext(object identity) {}&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // .. other stuff&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;p&gt;you&amp;rsquo;ll see the &lt;strong&gt;Identity&lt;/strong&gt; property there is of type object.&amp;nbsp; So in this case, we&amp;rsquo;re just going to derive and give ourselves a nice strongly-typed property and constructor:&lt;/p&gt;
&lt;pre&gt;     public class ZipCodeLoadContext : LoadContext {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string ZipCode {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (string)Identity;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ZipCodeLoadContext(string zipcode)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : base(zipcode) {&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;p&gt;One important thing to note here is that the parameter on the &lt;em&gt;constructor should match the type of object you&amp;rsquo;ll be passing in&lt;/em&gt;.&amp;nbsp; In this case, the zip is going to be a string, so there should be a 1-parameter ctor that takes a string. AgFx will look for this to automatically create the LoadContext.&lt;/p&gt;
&lt;p&gt;We can reuse this LoadContext for the zip code service as well.&amp;nbsp; Handy!&lt;/p&gt;
&lt;h2&gt;Step 3: Define your ViewModel object (or model, if you want to do it that way&amp;hellip;)&lt;/h2&gt;
&lt;p&gt;Now that we&amp;rsquo;ve got the LoadContext, we can create our ViewModel.&amp;nbsp; ViewModels should derive from &lt;strong&gt;ModelItemBase&amp;lt;T&amp;gt;,&lt;/strong&gt; which you&amp;rsquo;ll want to be familiar with.&amp;nbsp; So let&amp;rsquo;s look at some of the members&amp;nbsp; you&amp;rsquo;ll be using:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ModelItemBase.LastUpdated&lt;/strong&gt; &amp;ndash; this property tells you the last time an object&amp;rsquo;s data was fetched.&amp;nbsp; It will be the same even after the data is loaded from the cache, it only updates when new data is loaded.&amp;nbsp; This property is data-bindable, so you can bind it to a field in your UI to show the user when the data for this particular object was last loaded. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ModelItemBase.IsUpdating&lt;/strong&gt; -&amp;nbsp; This property is also data-bindable, and flips to true whenever AgFx is loading new data for your object.&amp;nbsp; It doesn&amp;rsquo;t flip to true for cache loads (those should be fast!), just when it&amp;rsquo;s loading new data, usually from the network.&amp;nbsp; You can bind this to an &amp;ldquo;Updating&amp;rdquo; UI item that you want to be enabled (like a progress bar) or visible only when an update is occuring.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ModelItemBase.Refresh() &amp;ndash; &lt;/strong&gt;This method allows you to refresh any loaded item with new data, at any time before or after it&amp;rsquo;s expiration date.&amp;nbsp; You can call this in the click handler for a link or a button to cause a data refresh to happen (which, will cause IsUpdating to be true, and then LastUpdated to be changed as part of that process).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;ModelItemBase&lt;/strong&gt; derives from &lt;strong&gt;NotifyPropertyChangedBase&lt;/strong&gt;, which is a default implementation of &lt;strong&gt;INotifyPropertyChanged&lt;/strong&gt; and also adds some helpful functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NotifyPropertyChangedBase.RaisePropertyChanged&lt;/strong&gt; &amp;ndash; helper for firing INotifyPropertyChanged.PropertyChanged &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NotifyPropertyChangedBase.AddDependentProperty&lt;/strong&gt; &amp;ndash; if you have properties that are dependent on one another, it can be annoying to have to notify property changes from a bunch of different places.&amp;nbsp; This allows you, in the object&amp;rsquo;s ctor, to declare properties that are dependent on each other.&amp;nbsp; So imagine your ViewModel has a Price property and a Discount property.&amp;nbsp; The price is dependent on the discount, so if Discount changes, then Price will have new value.&amp;nbsp; You want any UI bound to Price to automatically change, so you&amp;rsquo;d just do this:&amp;nbsp; &lt;strong&gt;AddDependentProperty(&amp;ldquo;Discount&amp;rdquo;, &amp;ldquo;Price&amp;rdquo;),&lt;/strong&gt; which says that when Discount changes, fire a PropertyChanged notification for Price. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NotifyPropertyChangedBase.NotificationContext&lt;/strong&gt; &amp;ndash; if you have done any work off of the UI thread, you know that you can&amp;rsquo;t change the properties of UI objects from other threads.&amp;nbsp; Likewise, if you make property changes to an object that is databound to UI, then you also can&amp;rsquo;t fire change notifications off thread.&amp;nbsp; This property allows the thread switch to happen automatically.&amp;nbsp; Just initialize this property with the SynchronizationContext from the desired thread (typically you just pass DispatcherSynchronizationContext.Current) and you&amp;rsquo;re done. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Okay, that&amp;rsquo;s it for ModelItemBase.&amp;nbsp; Let&amp;rsquo;s create our ViewModel for the weather forecast:&lt;/p&gt;
&lt;p&gt;First, let&amp;rsquo;s create the constructors:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; WeatherForecastVm : ModelItemBase&amp;lt;ZipCodeLoadContext&amp;gt;   {&lt;/pre&gt;
&lt;pre class="csharpcode"&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; WeatherForecastVm()  {  }
        
 &lt;span class="kwrd"&gt;public&lt;/span&gt; WeatherForecastVm(&lt;span class="kwrd"&gt;string&lt;/span&gt; zipcode): 
        &lt;span class="kwrd"&gt;base&lt;/span&gt;(&lt;span class="kwrd"&gt;new&lt;/span&gt; ZipCodeLoadContext(zipcode))   {     }

&lt;span class="rem"&gt;//...&lt;/span&gt;
}&lt;/pre&gt;
&lt;p&gt;This is pretty simple, but it&amp;rsquo;s important to note two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You &lt;strong&gt;must&lt;/strong&gt; have a default constructor &lt;/li&gt;
&lt;li&gt;You &lt;strong&gt;should&lt;/strong&gt; have a constructor that takes your identifier and creates a LoadContext for it.&amp;nbsp; It&amp;rsquo;s not critical, but you&amp;rsquo;ll find it helpful. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Okay, now we add some properties to the ViewModel.&lt;/p&gt;
&lt;p&gt;Most properties look like this:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; _city;
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; City
{
    get
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; _city;
    }
    set
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (_city != &lt;span class="kwrd"&gt;value&lt;/span&gt;)
        {
            _city = &lt;span class="kwrd"&gt;value&lt;/span&gt;;
            RaisePropertyChanged(&lt;span class="str"&gt;"City"&lt;/span&gt;);
        }
    }
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Note the &amp;ldquo;&lt;strong&gt;RaisePropertyChanged&lt;/strong&gt;&amp;rdquo; call at the bottom, which calls down to &lt;strong&gt;NotifyPropertyChangedBase&lt;/strong&gt; declared above.&amp;nbsp; This let&amp;rsquo;s the UI know that it should update this value.&lt;/p&gt;
&lt;p&gt;For collection properties, things are just a little bit different.&amp;nbsp;&amp;nbsp; When you databind to collection properties, you typically use an &lt;strong&gt;ObservableCollection&amp;lt;T&amp;gt;&lt;/strong&gt; so that any databound UI will automatically update when you make changes to your items.&amp;nbsp; That still works fine here, too, but with a small tweak&lt;/p&gt;
&lt;p&gt;For collection properties in your ViewModel, that you should do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Make your collection property read/write&lt;/strong&gt;.&amp;nbsp; These properties are often just read only but for AgFx it&amp;rsquo;s much simpler if they are read write. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don&amp;rsquo;t replace&lt;/strong&gt; the value of the collection in the setter, clear your collection, then &lt;strong&gt;copy the items over from the new value&lt;/strong&gt;. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The reason for this is because AgFx knows which instance of your object is bound to your UI, and always updates that instance (it uses the same instance across your application).&amp;nbsp; So when an update happens, it &amp;ldquo;copies&amp;rdquo; the property values from the fresh instance into the one currently held by the system.&amp;nbsp; Rather than doing this automatically, because you may want to manage how the copying happens, you&amp;rsquo;ll typically just do this:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;private ObservableCollection&amp;lt;WeatherPeriod&amp;gt; _wp = &lt;span class="kwrd"&gt;new&lt;/span&gt; ObservableCollection&amp;lt;WeatherPeriod&amp;gt;();
&lt;span class="kwrd"&gt;public&lt;/span&gt; ObservableCollection&amp;lt;WeatherPeriod&amp;gt; WeatherPeriods {
    get {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; _wp;
    }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; set {&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;        if (value == null) throw new ArgumentNullException();
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (_wp != &lt;span class="kwrd"&gt;null&lt;/span&gt;) {
            _wp.Clear();

            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var wp &lt;span class="kwrd"&gt;in&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;) {
               _wp.Add(wp);
            }
            
        }
       
        RaisePropertyChanged(&lt;span class="str"&gt;"WeatherPeriods"&lt;/span&gt;);
    }
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;So now you can add all of your properties to fill out the shape of your ViewModel.&lt;/p&gt;
&lt;h2&gt;Step 4: Define your caching policy&lt;/h2&gt;
&lt;p&gt;When you fetch data from your service, how long is it good for? AgFx defines a very simple way to define how long data should be cached for in your object.&lt;/p&gt;
&lt;p&gt;The way this is done is with the &lt;strong&gt;CachePolicyAttribute.&amp;nbsp; &lt;/strong&gt;The constructor for CachePolicyAttribute takes two parameters:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The CachePolicy itself&lt;/strong&gt;.&amp;nbsp; CachePolicy can be one of the following values &lt;ol&gt;
&lt;li&gt;&lt;strong&gt;CachePolicy.NoCache&lt;/strong&gt; &amp;ndash; this object should not be cached.&amp;nbsp; Each time an application asks for this object, fetch an updated value.&amp;nbsp; This won&amp;rsquo;t be used very often, but hey, it could happen. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CachePolicy.ValidCacheOnly &amp;ndash; &lt;/strong&gt;in this case, the data will only be returned from AgFx if it&amp;rsquo;s valid.&amp;nbsp; In other words, AgFx will check the cache, and return that value if it&amp;rsquo;s within it&amp;rsquo;s expiration time.&amp;nbsp; If not, new data will be fetched and returned when it is available.&amp;nbsp; In our sample here, the Weather data is set as ValidCacheOnly.&amp;nbsp; No use in showing weather data from last week! &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CachePolicy.CacheThenRefresh&lt;/strong&gt; &amp;ndash; this is likely the most commonly used policy. What this means is that AgFx should go ahead look for a cached value, and if it finds one, &lt;em&gt;regardless of it&amp;rsquo;s expiration date&lt;/em&gt; it should return that value to the caller. At that point, if the data is expired, automatically kick off a refresh. Imagine a Facebook application. When the user starts the app, imagine the app shows the user&amp;rsquo;s News Feed. The app could either always just show a blank News Feed with &amp;ldquo;Updating&amp;hellip;&amp;rdquo; and then go get new data (this would be the &lt;strong&gt;ValidCacheOnly&lt;/strong&gt; behavior). Or it could show the feed in the last state that it was in, and then update that with any new items since the last check. Most apps chose the latter, and this setting does exactly that. If you were to be databound to a &amp;ldquo;NewsVeedVm&amp;rdquo;, the feed would load from the cache then automatically update when new data was available. No code necessary, AgFx does this for you. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CachePolicy.AutoRefresh&lt;/strong&gt; &amp;ndash; This goes one step further and automatically kicks off a refresh of the data when the data reaches the end of it&amp;rsquo;s designated lifespan. &lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A cache time (in seconds).&lt;/strong&gt;&amp;nbsp; This defines how long your data should be cached for.&amp;nbsp; For something like weather data, this might be 15 minutes (60 * 15), and for ZipCode data it&amp;rsquo;s basically forever, so you can just put a really long cache period in there. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So we just apply this to our ViewModels as in the following:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;[CachePolicy(CachePolicy.ValidCacheOnly, 60 * 15)] 
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; WeatherForecastVm : ModelItemBase&amp;lt;ZipCodeLoadContext&amp;gt;{&amp;hellip;}

&lt;span class="rem"&gt;// this basically never changes, but we'll say &lt;/span&gt;
&lt;span class="rem"&gt;// it's valid for a year.&lt;/span&gt;
[CachePolicy(CachePolicy.CacheThenRefresh, 3600 * 24 * 365)] 
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ZipCodeVm : ModelItemBase&amp;lt;ZipCodeLoadContext&amp;gt;{&amp;hellip;}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s it.&lt;/p&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;h2&gt;Step 5: Defining your DataLoader&lt;/h2&gt;
&lt;p&gt;Okay, now is when the real party starts.&amp;nbsp;&amp;nbsp; The DataLoader is the beating heart of your ViewModel objects.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;The DataLoader has two primary jobs:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Configure a request for data to populate the object &lt;/li&gt;
&lt;li&gt;Take the raw data and create a model or ViewModel object out of it &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Fortunately both of these are pretty easy.&lt;/p&gt;
&lt;p&gt;Your DataLoader is an object that implements &lt;strong&gt;IDataLoader&amp;lt;T&amp;gt;&lt;/strong&gt; where T is your LoadContext type from earlier.&amp;nbsp; Your DataLoader should be a &lt;strong&gt;public nested type &lt;/strong&gt;in your view model.&amp;nbsp; This isn&amp;rsquo;t &lt;em&gt;strictly&lt;/em&gt; necessary (see AgFx.DataLoaderAttribute) but I haven&amp;rsquo;t yet found a case where I need to do it otherwise.&amp;nbsp; If it&amp;rsquo;s a nested type, AgFx will automatically find and instantiate it.&lt;/p&gt;
&lt;p&gt;IDataLoader&amp;lt;T&amp;gt; It has two methods:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;IDataLoader.GetLoadRequest&lt;/strong&gt; &amp;ndash; this returns an object that describes how to fetch data for your ViewModel.&amp;nbsp; In the vast majority of cases this will just be a URI, and there is a special class called &lt;strong&gt;WebLoadRequest&lt;/strong&gt; for that.&amp;nbsp; GetLoadRequest actually returns an object of the abstract type LoadRequest, so you can do fancy stuff here if you need to.&amp;nbsp; At the end of the day, this takes information from your LoadContext (basically whatever you need to build the URI in most cases) and then tells AgFx how to convert this into a Stream.&amp;nbsp; Usually this means just doing a web request and returning the ResponseStream. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IDataLoader.Deserialize &amp;ndash; &lt;/strong&gt;given the Stream from (1) above, Deserialize is responsible for turning that into an object of the type that AgFx is asking for (in other words, your view Model type). &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Implementing these is also simple.&amp;nbsp; Here&amp;rsquo;s how GetLoadRequest usually looks:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ZipCodeUriFormat = &lt;span class="str"&gt;"http://www.webservicex.net/uszip.asmx/GetInfoByZIP?USZip={0}"&lt;/span&gt;;

&lt;span class="kwrd"&gt;public&lt;/span&gt; LoadRequest GetLoadRequest(ZipCodeLoadContext loadContext, Type objectType)
{
    &lt;span class="rem"&gt;// build the URI, return a WebLoadRequest.&lt;/span&gt;
    &lt;span class="kwrd"&gt;string&lt;/span&gt; uri = String.Format(ZipCodeUriFormat, loadContext.ZipCode);
    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; WebLoadRequest(loadContext, &lt;span class="kwrd"&gt;new&lt;/span&gt; Uri(uri));
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Make sense?&amp;nbsp; It&amp;rsquo;s pretty simple.&amp;nbsp; If you needed more parameters on the request, then you&amp;rsquo;d add more properties to your LoadContext and then use that to build out the URI.&lt;/p&gt;
&lt;p&gt;AgFx will take that object and it will result in a network request.&amp;nbsp; When that network request returns, the stream that it provided will be passed along back to the DataLoader for processing.&lt;/p&gt;
&lt;p&gt;Processing the network data is typically straight-forward.&amp;nbsp; I&amp;rsquo;m doing manual XML walking here.&amp;nbsp; If your web service exposes a WSDL that the Windows Phone Developer Tools can handle, you can use that to make parsing a snap, usually using DataContractSerializer,, but for clarity I&amp;rsquo;ll just do the brute force method below.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; Deserialize(ZipCodeLoadContext loadContext, Type objectType, System.IO.Stream stream)
{

    &lt;span class="rem"&gt;// the XML will look like the following, so we parse it.&lt;/span&gt;

    &lt;span class="rem"&gt;//&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;//&amp;lt;NewDataSet&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;//  &amp;lt;Table&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;//    &amp;lt;CITY&amp;gt;Kirkland&amp;lt;/CITY&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;//    &amp;lt;STATE&amp;gt;WA&amp;lt;/STATE&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;//    &amp;lt;ZIP&amp;gt;98033&amp;lt;/ZIP&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;//    &amp;lt;AREA_CODE&amp;gt;425&amp;lt;/AREA_CODE&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;//    &amp;lt;TIME_ZONE&amp;gt;P&amp;lt;/TIME_ZONE&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;//  &amp;lt;/Table&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;//&amp;lt;/NewDataSet&amp;gt;                &lt;/span&gt;

    var xml = XElement.Load(stream);


    var table = (
                from t &lt;span class="kwrd"&gt;in&lt;/span&gt; xml.Elements(&lt;span class="str"&gt;"Table"&lt;/span&gt;)
                select t).FirstOrDefault();

    &lt;span class="kwrd"&gt;if&lt;/span&gt; (table == &lt;span class="kwrd"&gt;null&lt;/span&gt;) {
        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentException(&lt;span class="str"&gt;"Unknown zipcode "&lt;/span&gt; + loadContext.ZipCode);
    }

    ZipCodeVm vm = &lt;span class="kwrd"&gt;new&lt;/span&gt; ZipCodeVm(loadContext.ZipCode);
    vm.City = table.Element(&lt;span class="str"&gt;"CITY"&lt;/span&gt;).Value;
    vm.State = table.Element(&lt;span class="str"&gt;"STATE"&lt;/span&gt;).Value;
    vm.AreaCode = table.Element(&lt;span class="str"&gt;"AREA_CODE"&lt;/span&gt;).Value;
    vm.TimeZone = table.Element(&lt;span class="str"&gt;"TIME_ZONE"&lt;/span&gt;).Value;
    &lt;span class="kwrd"&gt;return&lt;/span&gt; vm;
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;So what we do here is get into the XML stream with XLINQ, then just create a new ViewModel object (of type ZipCodeVm) and populate it&amp;rsquo;s properties with the values that we got out of XML.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Note the &lt;strong&gt;objectType&lt;/strong&gt; property.&amp;nbsp; The returned object MUST be an instance of this type (derived types are OK).&amp;nbsp; AgFx will enforce this.&amp;nbsp; You can take a look at the Deserialize method in the WeatherForecastVm as well, it&amp;rsquo;s pretty much the same, but it handles much more complex XML from the NOAA service via a helper class.&lt;/p&gt;
&lt;p&gt;Now we just compile to make sure it&amp;rsquo;s all building.&lt;/p&gt;
&lt;h2&gt;Step 6: Bind to your UI with Expression Blend&lt;/h2&gt;
&lt;p&gt;Believe it or not, our application is just about done.&amp;nbsp; Using the great sample data features of Expression Blend, it&amp;rsquo;s really easy to create our UI.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll walk through a simple case of just the zip code information that we deserialized above.&amp;nbsp; To make this easy to understand, what we want to do is create a UserControl that shows the city and state, along with the LastUpdated date.&amp;nbsp; For the whole weather application, it&amp;rsquo;s the same process with a little more detail.&lt;/p&gt;
&lt;p&gt;For this, I add a new Windows Phone User Control to my project, right click on the XAML file in Solution Explorer and choose &amp;ldquo;Open in Expression Blend&amp;hellip;&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Once Blend opens with the UserControl showing on the design surface, the first thing we&amp;rsquo;ll do is create sample data for our ViewModel:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/0184.image_5F00_554CE6DA.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/3817.image_5F00_thumb_5F00_3A3417CC.png" width="368" height="108" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now we choose &amp;ldquo;Create Sample Data From Class&amp;rdquo;:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/0184.image_5F00_7D9C192E.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/0675.image_5F00_thumb_5F00_6AE71F77.png" width="381" height="110" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This will show us the public types in our project assemblies.&amp;nbsp; We&amp;rsquo;re looking for &amp;ldquo;ZipCodeVm&amp;rdquo;, which is one of the VM objects we created up in step 3.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/0675.image_5F00_2A44D308.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/6038.image_5F00_thumb_5F00_6FE95D26.png" width="400" height="445" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Hit OK, and now just drag the ZipCodeVm item onto the design surface:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/7103.image_5F00_27BBA14A.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/4786.image_5F00_thumb_5F00_66AD21E5.png" width="524" height="353" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now we just build out our UI like so by dragging on some TextBlock objects from the Blend toolbar:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/2620.image_5F00_259EA281.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/6102.image_5F00_thumb_5F00_3D55D9E7.png" width="687" height="289" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, for each of the items that says &amp;ldquo;TextBlock&amp;rdquo; we can just databind to our data fields by dragging them onto the object on the design surface, as demonstrated by the red arrow below.&amp;nbsp; We&amp;rsquo;ll see sample (bogus) data that lets us just visualize how the UI will look at runtime.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/2308.image_5F00_780D5CF0.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/3872.image_5F00_thumb_5F00_2BD55342.png" width="690" height="298" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Remember, it&amp;rsquo;s bogus sample data., it just allows us to see the layout.&amp;nbsp; This prevents the tweak-F5-tweak-F5 method that many of use are used to.&lt;/p&gt;
&lt;p&gt;After a little cleanup, here is what the XAML looks like.&amp;nbsp;&amp;nbsp; Notice the Binding statements to the properties we added in our ViewModel.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt; &lt;span class="attr"&gt;Orientation&lt;/span&gt;&lt;span class="kwrd"&gt;="Horizontal"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;="{Binding &lt;strong&gt;City&lt;/strong&gt;}"&lt;/span&gt; &lt;span class="attr"&gt;FontWeight&lt;/span&gt;&lt;span class="kwrd"&gt;="Bold"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;=", "&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;="{Binding &lt;strong&gt;State&lt;/strong&gt;}"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt; &lt;span class="attr"&gt;Orientation&lt;/span&gt;&lt;span class="kwrd"&gt;="Horizontal"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;="Updated: "&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;="{Binding &lt;strong&gt;LastUpdated&lt;/strong&gt;}"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;h2&gt;Step 7: Load your object data into your UI&lt;/h2&gt;
&lt;p&gt;Okay now we&amp;rsquo;ve got our View Models built, our data processing done, and our databinding done.&amp;nbsp; Now we just have to load the data.&lt;/p&gt;
&lt;p&gt;The primary object for data access and management in AgFx is &lt;strong&gt;DataManager&lt;/strong&gt;.&amp;nbsp; &lt;strong&gt;DataManager&lt;/strong&gt; is a singleton class that is accessed via the &lt;strong&gt;DataManager.Current&lt;/strong&gt; property.&lt;/p&gt;
&lt;p&gt;DataManager only exposes a few operations, but they really are key to tying the whole thing together.&lt;/p&gt;
&lt;p&gt;As a starter example, we&amp;rsquo;d load data into the UserControl that we built above as follows:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;zipCodeUserControl1.DataContext =
          DataManager.Current.Load&amp;lt;ZipCodeVm&amp;gt;(&lt;span class="str"&gt;"98052"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;p&gt;Which gives us this at runtime:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/0741.image_5F00_03C2A423.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/5050.image_5F00_thumb_5F00_5C885AED.png" width="210" height="54" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Notice we are passing the zip code as a string.&amp;nbsp; Remember form our &lt;strong&gt;ZipCodeLoadContext&lt;/strong&gt;,&amp;nbsp; that we added a constructor with just a single string parameter.&amp;nbsp; AgFx will take that &amp;ldquo;98052&amp;rdquo; and automatically pass it to that constructor.&amp;nbsp; Also notice that we don&amp;rsquo;t have to do anything to manage caching or networking here.&amp;nbsp; AgFx figures out if the value is already available in the cache, if the cache is valid, or if it needs to be refreshed from the network.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s important to keep in mind that the instance returned from the Load call will be &lt;em&gt;the same instance that is returned from any future Load or Refresh calls&lt;/em&gt;.&amp;nbsp; This identity-tracking is one of the key features of AgFx.&amp;nbsp; What this means, is that once I&amp;rsquo;ve databound to a value in my UI, future calls to Refresh or Load will update this same instance.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;In other words, if in a button click you simply do this:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; btnRefreshZipcode_Click(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, RoutedEventArgs e) {
     DataManager.Current.Refresh&amp;lt;ZipCodeVm&amp;gt;(&lt;span class="str"&gt;"98052"&lt;/span&gt;);
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;then the UI above &lt;em&gt;will update.&amp;nbsp; &lt;/em&gt;Note we never touch the user control or it&amp;rsquo;s DataContext.&amp;nbsp; It just works.&lt;/p&gt;
&lt;p&gt;DataManager gives you a broad set of operations to interact with your data.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Remember these are all accessed via &lt;strong&gt;DataManager.Current&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DataManager.Load&amp;lt;&amp;gt; &lt;/strong&gt;as noted above takes either the shortcut value or an actual LoadContext object that you construct yourself. You would construct a LoadContext if you needed to set additional parameters, like a page number or result set size.&amp;nbsp; Load executes asynchronously &lt;strong&gt;except&lt;/strong&gt; in the case that there is already a value in memory, in which case that value is returned immediately.&amp;nbsp; If that value has expired, a reload is kicked off, and the current value is returned and will be updated when the load completes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DataManager.Refresh&amp;lt;&amp;gt;&lt;/strong&gt;, which reloads the data for the given item, as if the value has expired.&amp;nbsp; It otherwise works in the same way as Load&amp;lt;&amp;gt;. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DataManager.LoadFromCache&amp;lt;&amp;gt;&lt;/strong&gt; works also similarly to Load&amp;lt;&amp;gt;, but it will only load from the cache &lt;em&gt;&lt;strong&gt;and is synchronous&lt;/strong&gt;&lt;/em&gt;.&amp;nbsp; This is generally used in app startup as a way to load things up before the UI kicks off, for a example credentials and whatnot.&amp;nbsp;&amp;nbsp; You probably won&amp;rsquo;t use it often.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DataManager.Clear&amp;lt;&amp;gt;&lt;/strong&gt; &amp;ndash; clears the given object out of the DataManager&amp;rsquo;s&amp;nbsp; data structures.&amp;nbsp; Calling Load again will create a new instance, reload it&amp;rsquo;s live data, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DataManager.RegisterProxy&amp;lt;&amp;gt; &amp;ndash; &lt;/strong&gt;this exists for some advanced scenarios that I won&amp;rsquo;t cover here, but basically this allows you to register other objects that you would like to be updated in addition to the main instance that DataManager is managing. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DataManager.UnhandledError&lt;/strong&gt; (event) &amp;ndash; this allows you to catch any unhandled errors that occur within a DataLoader&amp;rsquo;s code and potentially handle them before they bubble up to the app. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DataManager.IsLoading &amp;ndash; &lt;/strong&gt;this property is set to true whenever any object&amp;rsquo;s loader is currently fetching new data.&amp;nbsp;&amp;nbsp; &lt;strong&gt;DataManager&lt;/strong&gt; implements &lt;strong&gt;INotifyPropertyChanged&lt;/strong&gt;, so you can bind this property to UI that runs a ProgressBar or something if you want to show UI whenever network activity is occurring.&amp;nbsp;&amp;nbsp; This will &lt;em&gt;not&lt;/em&gt; be set to true for cache loads, only for live loads (just like the &lt;strong&gt;ModelItemBase.IsUpdating&lt;/strong&gt; property). &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For &lt;strong&gt;Load &lt;/strong&gt;and &lt;strong&gt;Refresh&lt;/strong&gt;, there are overloads that allow you to get handle both completion and error scenarios in code.&amp;nbsp; The signatures look like this:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; T Load&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;object&lt;/span&gt; id, Action&amp;lt;T&amp;gt; completed, Action&amp;lt;Exception&amp;gt; error) ;&lt;/pre&gt;
&lt;p&gt;

which allows you to pass in a lambda that will be called when the operation completes or fails, like so:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;this&lt;/span&gt;.DataContext = DataManager.Current.Load&amp;lt;WeatherForecastVm&amp;gt;(txtZipCode.Text,
        (vm) =&amp;gt;
        {
            &lt;span class="rem"&gt;// upon a succesful load, show the info panel.&lt;/span&gt;
            &lt;span class="rem"&gt;// this is a bit of a hack, but we can't databind against&lt;/span&gt;
            &lt;span class="rem"&gt;// a non-existant data context...&lt;/span&gt;
            info.Visibility = Visibility.Visible;
        },
        (ex) =&amp;gt;
        {
            MessageBox.Show(&lt;span class="str"&gt;"Error: "&lt;/span&gt; + ex.Message);
        });   &lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Note that if you pass in a handler for error, then the &lt;strong&gt;DataManager.UnhandledError&lt;/strong&gt; event will &lt;em&gt;not &lt;/em&gt;be invoked, regardless of what happens in the handler.&amp;nbsp; You either handle via the lambda, or the global event, not both.&lt;/p&gt;
&lt;p&gt;The &amp;ldquo;vm&amp;rdquo; parameter in the success handler will be the same instance as the object returned from the Load&amp;lt;&amp;gt; function as well, so any operations on this object will also be reflected in the UI.&amp;nbsp; These handlers &lt;em&gt;will invoke on the UI thread.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Finally, as I&amp;rsquo;ve mentioned before, it&amp;rsquo;s best to let DataManager do all the instance management for you.&amp;nbsp; It does a lot of caching so don&amp;rsquo;t cache instances yourself unless you have to.&amp;nbsp; For ViewModels that have properties that are other ViewModels (a pattern I really like because it encourages on-demand network activity as a user moves through an app), use this pattern:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class="rem"&gt;/// ZipCode info is the name of the city for the zipcode.  This is a separate &lt;/span&gt;
&lt;span class="rem"&gt;/// service lookup, so we treat it separately.&lt;/span&gt;
&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;public&lt;/span&gt; ZipCodeVm ZipCodeInfo
{
    get
    {                
        &lt;span class="kwrd"&gt;return&lt;/span&gt; DataManager.Current.Load&amp;lt;ZipCodeVm&amp;gt;(LoadContext.ZipCode);
    }
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Just use the Load method to return the right value.&lt;/p&gt;
&lt;p&gt;So back to our weather example, here is the parts of the UI that are serviced by the various objects we&amp;rsquo;ve been discussing:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/3872.image_5F00_42B424BE.png"&gt;&lt;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="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/5037.image_5F00_thumb_5F00_280788A5.png" width="488" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Step 8: Debugging&lt;/h2&gt;
&lt;p&gt;If you build a debug version of AgFx, you&amp;rsquo;ll find some useful debugging output that will help you determine what AgFx is up to.&amp;nbsp; In the case of a first-time run of the weather application, here&amp;rsquo;s the output you&amp;rsquo;ll seee:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: xx-small;"&gt;No cache found for NWSWeather.Sample.ViewModels.WeatherForecastVm&lt;/span&gt;&lt;span style="font-size: xx-small;"&gt;&lt;strong&gt; (1) &lt;br /&gt;&lt;/strong&gt;3/17/2011 2:22:35 PM: Queuing load for WeatherForecastVm &lt;strong&gt;(2)&lt;/strong&gt; &lt;br /&gt;No cache found for NWSWeather.Sample.ViewModels.ZipCodeVm &lt;br /&gt;3/17/2011 2:22:35 PM: Queuing load for ZipCodeVm &lt;br /&gt;3/17/2011 2:22:35 PM: Checking cache for ZipCodeVm &lt;br /&gt;3/17/2011 2:22:37 PM: Deserializing live data for NWSWeather.Sample.ViewModels.WeatherForecastVm&lt;strong&gt; (3)&lt;/strong&gt; &lt;br /&gt;Writing cache for WeatherForecastVm, IsOptimized=False, Will expire 3/17/2011 2:37:37 PM &lt;strong&gt;(4)&lt;/strong&gt; &lt;br /&gt;3/17/2011 2:23:43 PM: Deserializing live data for NWSWeather.Sample.ViewModels.ZipCodeVm &lt;br /&gt;Writing cache for ZipCodeVm, IsOptimized=False, Will expire 3/16/2012 2:23:43 PM&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Because these operations all happen off of the UI thread, you get interleaving between the call to the weather service and the zip code service.&amp;nbsp; That&amp;rsquo;s good!&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve added the numbers in &lt;strong&gt;(bold)&lt;/strong&gt; to the right to describe that this output means:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;When the Load&amp;lt;WeatherForecastVm&amp;gt;(&amp;ldquo;98052&amp;rdquo;) call was made, the cache was checked and no value existed.&lt;/li&gt;
&lt;li&gt;Because no cache existed a load (network) was queued for this item&lt;/li&gt;
&lt;li&gt;The load completed and asked the DataLoader to deserialize the value&lt;/li&gt;
&lt;li&gt;The deserialize completed, so the stream is being written to the cache with the specified expiration date.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you&amp;rsquo;re writing an app and it&amp;rsquo;s not doing what you think it should, this output will really help you understand what the problem might be.&amp;nbsp; If you see a lot of this output when you don&amp;rsquo;t expect to, that means something is going on that may be resulting in extra data loads that you don&amp;rsquo;t need.&amp;nbsp; So you can use this as a perf tuning input as well.&lt;/p&gt;
&lt;p&gt;As a comparison, here&amp;rsquo;s the output from a second run, after the app has been exited and restarted a few minutes later.&amp;nbsp; Note there are no &amp;ldquo;queuing load&amp;rdquo; or &amp;ldquo;writing cache&amp;rdquo; entries.&amp;nbsp; This shows that cached data is actually being loaded, when it was last updated, and when it will expire.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: xx-small;"&gt;3/17/2011 2:35:12 PM: Checking cache for WeatherForecastVm &lt;br /&gt;3/17/2011 2:35:12 PM: Checking cache for ZipCodeVm &lt;br /&gt;3/17/2011 2:35:12 PM: Loading cached data for ZipCodeVm, Last Updated=3/17/2011 2:23:43 PM, Expiration=3/16/2012 2:23:43 PM &lt;br /&gt;3/17/2011 2:35:12 PM: Deserializing cached data for NWSWeather.Sample.ViewModels.ZipCodeVm, IsOptimized=False &lt;br /&gt;3/17/2011 2:35:12 PM: Loading cached data for WeatherForecastVm, Last Updated=3/17/2011 2:22:37 PM, Expiration=3/17/2011 2:37:37 PM &lt;br /&gt;3/17/2011 2:35:12 PM: Deserializing cached data for NWSWeather.Sample.ViewModels.WeatherForecastVm, IsOptimized=False&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Wrap up&lt;/h2&gt;
&lt;p&gt;Phew, that&amp;rsquo;s a lot of stuff!&amp;nbsp; Believe it or not, there&amp;rsquo;s more but I&amp;rsquo;ll leave it at that for now.&amp;nbsp; I&amp;rsquo;ve had a lot of fun putting this framework together, with help from Jeff among others.&amp;nbsp; And I&amp;rsquo;ve had even more fun writing apps on top of it.&amp;nbsp; Hopefully you will too, please let me know how it goes!&lt;/p&gt;
&lt;p&gt;Download AgFx with the NOAA Weather sample &lt;a href="http://agfx.codeplex.com"&gt;here&lt;/a&gt;.&amp;nbsp; Note when you open this project, you'll get a few warnings about Silverlight project.&amp;nbsp; These are expected and harmless because the base code is an Silverlight class library (so it can be used on Silverlight too).&amp;nbsp; Just hit OK.&lt;/p&gt;
&lt;p&gt;Shawn&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10142810" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/sburke/archive/tags/Windows+Phone+7/">Windows Phone 7</category><category domain="http://blogs.msdn.com/b/sburke/archive/tags/AgFx/">AgFx</category></item><item><title>Build great Windows Phone applications the easy way!</title><link>http://blogs.msdn.com/b/sburke/archive/2011/03/11/build-great-windows-phone-applications-the-easy-way.aspx</link><pubDate>Sat, 12 Mar 2011 02:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10140123</guid><dc:creator>Shawn Burke - MSFT</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/sburke/rsscomments.aspx?WeblogPostID=10140123</wfw:commentRss><comments>http://blogs.msdn.com/b/sburke/archive/2011/03/11/build-great-windows-phone-applications-the-easy-way.aspx#comments</comments><description>&lt;h2&gt;Introducing AgFx&lt;/h2&gt;
&lt;p&gt;One of the things we&amp;rsquo;ve spent a fair amount of time on is working with various application writers, helping them build great Windows Phone 7 applications.&amp;nbsp; Many of the top applications that you&amp;rsquo;ll find on Windows Phone 7 devices today spent some time in a debugger on my desktop, or &lt;a target="_blank" href="http://www.jeff.wilcox.name/"&gt;Jeff&amp;rsquo;s&lt;/a&gt;, or another one of the folks around here.&lt;/p&gt;
&lt;p&gt;In doing this process, we saw a lot of common trouble spots for developers looking to write Windows Phone 7 applications and as I started to think more about the problem. &lt;/p&gt;
&lt;p&gt;I thought the same thing I always think: &amp;ldquo;hmmmm, how can I build a framework that will make these things easy for the developer so they can worry about other stuff!&amp;rdquo;&lt;/p&gt;
&lt;p&gt;And so it was born, and I&amp;rsquo;m currently calling it AgFx.&amp;nbsp; Fortunately I&amp;rsquo;m a lot better at building frameworks than I am at naming things, so I&amp;rsquo;ll leave it at that.&amp;nbsp; But if you&amp;rsquo;re wondering what the &amp;ldquo;Ag&amp;rdquo; is about, &amp;ldquo;Ag&amp;rdquo; is the symbol for Silver, and this framework happens to work on desktop Silverlight as well, so you can use it to build the guts of applications that are shareable across phone and desktop.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;
&lt;h3&gt;AgFx is available via CodePlex&amp;nbsp;&lt;a href="http://agfx.codeplex.com"&gt;here&lt;/a&gt;. &amp;nbsp;&lt;/h3&gt;
&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h2&gt;What does it do?&lt;/h2&gt;
&lt;p&gt;AgFx provides a set of base class helpers and a data management engine that allow you to write your View Models (or just models, if you&amp;rsquo;re so inclined) in a very simple and consistent way.&amp;nbsp; It contains some other helpful stuff too, but the data management engine is the heart of it, which I&amp;rsquo;ll introduce in this post.&lt;/p&gt;
&lt;p&gt;Most applications do some variant of the following sequence:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Fetch data off of Internet &lt;/li&gt;
&lt;li&gt;Process said data into some data structures &lt;/li&gt;
&lt;li&gt;Bind said structures to some UI &lt;/li&gt;
&lt;li&gt;Cache structures on disk &lt;/li&gt;
&lt;li&gt;Next time a request comes in (say after tombstoning), check the cache &lt;ol&gt;
&lt;li&gt;If cache is valid, goto 2 &lt;/li&gt;
&lt;li&gt;If cache is not valid, goto 1 &lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;Repeat &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And while the above sounds simple, it turns out it&amp;rsquo;s not.&amp;nbsp; In fact, it&amp;rsquo;s a lot of work to get it right AND even when it works you have lots of opportunities to cause performance problems or other things that you&amp;rsquo;ll have to go out and figure out later.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;But fortunately the patterns are consistent enough that we can build an infrastructure to automate most of the above.&amp;nbsp; If you are thinking of writing an application that&amp;rsquo;s similar to the above pattern, this will make it MUCH easier.&lt;/p&gt;
&lt;p&gt;When thinking about most data-connected applications, it turns out there are only two key pieces of information required from the developer.&amp;nbsp; Consider a stock quote from a web service.&amp;nbsp; In order to display that stock quote in an application, we need to know:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;How to go fetch the data.&amp;nbsp; In this hypothetical case, it&amp;rsquo;s the URL to some service:&amp;nbsp; &lt;a href="http://www.contoso.com/services/stockquotes?symbol=msft"&gt;http://www.contoso.com/services/stockquotes?symbol=msft&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;How to process the data into an object that is consumable by my application.&amp;nbsp; Typically it means parsing JSON or XML&amp;nbsp; that comes back from the request. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Everything else can be managed by the system, off of the UI thread in most cases:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Checking for cached data and/or requesting new data &lt;/li&gt;
&lt;li&gt;Processing/Parsing the data &lt;/li&gt;
&lt;li&gt;Creating objects from the data &lt;/li&gt;
&lt;li&gt;Caching the data back to disk &lt;/li&gt;
&lt;li&gt;Handling data updates (these must be on the UI thread) &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And it turns out that this is exactly what AgFx does.&amp;nbsp; It manages all of the above so you don&amp;rsquo;t have to.&lt;/p&gt;
&lt;h2&gt;Eh&amp;hellip;code please.&lt;/h2&gt;
&lt;p&gt;Okay, let&amp;rsquo;s use a concrete example.&amp;nbsp;&amp;nbsp; The app that I&amp;rsquo;ll be including with the bits here is a simple app that goes against the &lt;a target="_blank" href="http://www.nws.noaa.gov/xml/"&gt;NOAA XML&lt;/a&gt; web services for weather reports.&amp;nbsp; Basically they take a US zip code and return a weather forecast.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/1033.image_5F00_52BA48C1.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97/4426.nws.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Oh, the joys of winter in Seattle&amp;hellip;.&lt;/p&gt;
&lt;p&gt;Anyway, as mentioned above, we need two pieces of information from the developer:&amp;nbsp; how to go find the data, and how to deserlialize it.&amp;nbsp; AgFx handles the rest.&amp;nbsp; The vast majority of your code when writing with AgFx is building these view model objects and deserializing data into them.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with some examples.&amp;nbsp; First, AgFx view models usually look something like this:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;    [CachePolicy(CachePolicy.ValidCacheOnly, 60 * 15)] 
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; WeatherForecastVm : ModelItemBase&amp;lt;ZipCodeLoadContext&amp;gt;
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; WeatherForecastVm()
        {
        }
        
        &lt;span class="kwrd"&gt;public&lt;/span&gt; WeatherForecastVm(&lt;span class="kwrd"&gt;string&lt;/span&gt; zipcode):&amp;nbsp;&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&lt;span style="white-space:pre"&gt;		&lt;/span&gt;base&lt;/span&gt;(&lt;span class="kwrd"&gt;new&lt;/span&gt; ZipCodeLoadContext(zipcode))
        {
        }
    
       &lt;span class="rem"&gt;//...properties, methods&lt;/span&gt;
     }&lt;/pre&gt;
&lt;p&gt;

A few things to note there.&amp;nbsp; First is the &lt;strong&gt;CachePolicyAttribute&lt;/strong&gt; at the top.&amp;nbsp; This tells the system how to handle the caching for this object type.&amp;nbsp;&amp;nbsp; &amp;ldquo;60 * 15&amp;rdquo; is 15 minutes &amp;ndash; meaning these values are valid for 15 minutes.&amp;nbsp; CachePolicy.&lt;strong&gt;ValidCacheOnly&lt;/strong&gt; means that the system should only return cached values that are within that cache time window, otherwise, it should go fetch an updated version.&lt;/p&gt;
&lt;p&gt;Now, you&amp;rsquo;ll notice that the above is a generic type, deriving from &lt;strong&gt;ModelItemBase&amp;lt;T&amp;gt;&lt;/strong&gt;, and is referencing something called a &amp;ldquo;ZipCodeLoadContext&amp;rdquo;.&amp;nbsp; Any object that AgFx is handling needs to have a LoadContext which is essentially the identifier for an instance of an item, as well as the place where you set extra state needed for loading.&amp;nbsp; It will become clear why it&amp;rsquo;s called a LoadContext shortly.&amp;nbsp; But the identifier should be unique for that type of item.&amp;nbsp; On many services it might be the user id (for users) or the item id (for some data item).&amp;nbsp; In this case the identifier is a zip code because zip codes map 1:1 with weather forecasts.&amp;nbsp; Given a zip code, we&amp;rsquo;ll always get the right forecast data (we all know we might not get the right forecast!).&lt;/p&gt;
&lt;p&gt;In this case, the ZipCodeLoadContext looks like the following:&lt;/p&gt;
&lt;pre class="csharpcode"&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ZipCodeLoadContext : LoadContext {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ZipCode {
            get {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;)Identity;
            }            
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; ZipCodeLoadContext(&lt;span class="kwrd"&gt;string&lt;/span&gt; zipcode)
            : &lt;span class="kwrd"&gt;base&lt;/span&gt;(zipcode) {

        }
    }&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Given that this is a simple case, you&amp;rsquo;re just wrapping the zipcode string, really.&amp;nbsp; The framework allows you to shortcut that if that&amp;rsquo;s the case, but I am including it here for completeness and so we get a nice strongly typed &amp;ldquo;ZipCode&amp;rdquo; property.&lt;/p&gt;
&lt;p&gt;Now to the important part.&amp;nbsp; The final piece is the &lt;strong&gt;DataLoader&lt;/strong&gt; which is what holds this all together.&amp;nbsp; Here&amp;rsquo;s the DataLoader for the WeatherForecastVm, as a nested class inside the WeatherForecastVm class itself:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; WeatherForecastVm : ModelItemBase&amp;lt;ZipCodeLoadContext&amp;gt;
    {
       &lt;span class="rem"&gt;// ... VM Body removed&lt;/span&gt;

        &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// Our loader, which knows how to do two things:&lt;/span&gt;
        &lt;span class="rem"&gt;/// 1. Build the URI for requesting data for a given zipcode&lt;/span&gt;
        &lt;span class="rem"&gt;/// 2. Parse the return value from that URI&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;strong&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; WeatherForecastVmLoader : IDataLoader&amp;lt;ZipCodeLoadContext&amp;gt;&lt;/strong&gt;
        {
           &lt;strong&gt; &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; NWS_Rest_Format = &lt;span class="str"&gt;"http://www.weather.gov/forecasts/xml/sample_products/browser_interface/ndfdBrowserClientByDay.php?zipCodeList={0}&amp;amp;format=12+hourly&amp;amp;startDate={1:yyyy-MM-dd}"&lt;/span&gt;;
            
            &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
            &lt;span class="rem"&gt;/// Build a LoadRequest that knows how to fetch new data for our object.&lt;/span&gt;
            &lt;span class="rem"&gt;/// In this case, it's just a URL so we construct the URL and then pass it to the&lt;/span&gt;
            &lt;span class="rem"&gt;/// default WebLoadRequest object, along with our LoadContext&lt;/span&gt;
            &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;public&lt;/span&gt; LoadRequest GetLoadRequest(ZipCodeLoadContext lc, Type objectType)
            {
                &lt;span class="kwrd"&gt;string&lt;/span&gt; uri = String.Format(NWS_Rest_Format, lc.ZipCode, DateTime.Now.Date);
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; WebLoadRequest(lc, &lt;span class="kwrd"&gt;new&lt;/span&gt; Uri(uri));
            }

            &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
            &lt;span class="rem"&gt;/// Once our LoadRequest has executed, we'll be handed back a stream containing the response from the &lt;/span&gt;
            &lt;span class="rem"&gt;/// above URI, which we'll parse.&lt;/span&gt;
            &lt;span class="rem"&gt;/// &lt;/span&gt;
            &lt;span class="rem"&gt;/// Note this will execute in two cases:&lt;/span&gt;
            &lt;span class="rem"&gt;/// 1. When we fetch fresh data from the Internet&lt;/span&gt;
            &lt;span class="rem"&gt;/// 2. When we are deserializing cached data off the disk. &amp;nbsp;&lt;/span&gt;&lt;/strong&gt;&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;&lt;strong&gt;&lt;span class="rem"&gt;&lt;span style="white-space:pre"&gt;	&lt;/span&gt;    /// The operation is equivelent at this point.&lt;/span&gt;
            &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; Deserialize(ZipCodeLoadContext lc,&amp;nbsp;&lt;/strong&gt;&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;&lt;strong&gt;&lt;span style="white-space:pre"&gt;					&lt;/span&gt;Type objectType,&amp;nbsp;&lt;/strong&gt;&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;&lt;strong&gt;&lt;span style="white-space:pre"&gt;					&lt;/span&gt;System.IO.Stream stream)
            {
                &lt;span class="rem"&gt;// Parse the XML out of the stream.&lt;/span&gt;
                var locs = NWSParser.ParseWeatherXml(&lt;/strong&gt;&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;&lt;strong&gt;&lt;span class="kwrd"&gt;&lt;span style="white-space:pre"&gt;				&lt;/span&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] { lc.ZipCode }, stream);

                &lt;span class="rem"&gt;// make sure we got the right data&lt;/span&gt;
                var loc = locs.FirstOrDefault();

                &lt;span class="kwrd"&gt;if&lt;/span&gt; (loc == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; FormatException(&lt;span class="str"&gt;"Didn't get any weather data."&lt;/span&gt;);
                }

                &lt;span class="rem"&gt;// Create our VM.  Note this is the same type as our containing object&lt;/span&gt;
                var vm = &lt;span class="kwrd"&gt;new&lt;/span&gt; WeatherForecastVm(lc.ZipCode);                

                &lt;span class="rem"&gt;// push in the weather periods&lt;/span&gt;
                &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var wp &lt;span class="kwrd"&gt;in&lt;/span&gt; loc.WeatherPeriods)
                {
                    vm.WeatherPeriods.Add(wp);
                }

                &lt;span class="kwrd"&gt;return&lt;/span&gt; vm;

            }
        }&lt;/strong&gt;

    }&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Again, the loader does two things, loads the new value (GetLoadRequest) and then parses it (Deserialize).&amp;nbsp;&amp;nbsp; Note we never have to write any serialization code for caching, just deserialize and AgFx does the rest.&lt;/p&gt;
&lt;h2&gt;Using your data&lt;/h2&gt;
&lt;p&gt;All of your view models will follow the same pattern above &amp;ndash; you&amp;rsquo;ll define the type, define it&amp;rsquo;s LoadContext (if necessary), then define it&amp;rsquo;s DataLoader.&amp;nbsp; At that point, you&amp;rsquo;re pretty much done.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;The way that all of these objects (viewmodels or strict models) are accessed is the same in AgFx, and that&amp;rsquo;s with the &lt;strong&gt;DataManager&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;So, what&amp;rsquo;s the code to use the data in this application?&amp;nbsp; It&amp;rsquo;s just this:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; btnAddZipCode_Click(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)
{
  &lt;span class="rem"&gt;// Load up a new ViewModel based on the zip.&lt;/span&gt;
  &lt;span class="rem"&gt;// This will either fetch new data from the Internet, or load the cached data off disk&lt;/span&gt;
  &lt;span class="rem"&gt;// as appropriate.&lt;/span&gt;
  &lt;span class="rem"&gt;//&lt;/span&gt;
&lt;strong&gt;  &lt;span class="kwrd"&gt;this&lt;/span&gt;.DataContext = DataManager.Current.Load&amp;lt;WeatherForecastVm&amp;gt;(txtZipCode.Text);
&lt;/strong&gt;}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s really it.&amp;nbsp; The rest of the code is databindings in the XAML, and some other code to save the zip code so it automatically loads again the next time.&lt;/p&gt;
&lt;p&gt;What we are doing here is asking the DataManager to load an object of type &lt;strong&gt;WeatherForecastVm&lt;/strong&gt;, with the given zip code as the &lt;strong&gt;identifier&lt;/strong&gt;.&amp;nbsp; The framework takes care of the rest.&lt;/p&gt;
&lt;p&gt;So, again, what are the steps that happen for me automatically upon calling that one line of code?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Look in the cache for data that a WeatherForecastVm can load, with the unique identifier of the specified zip code. &lt;/li&gt;
&lt;li&gt;If the data is there, check it&amp;rsquo;s &amp;ldquo;expiration date&amp;rdquo;, if it&amp;rsquo;s &lt;strong&gt;not expired&lt;/strong&gt;, return the data. &lt;/li&gt;
&lt;li&gt;If it &lt;strong&gt;is expired&lt;/strong&gt;, go get new data from the web, then save it to disk &lt;/li&gt;
&lt;li&gt;Deserialize data from (2) or (3) &lt;/li&gt;
&lt;li&gt;Create a WeatherForecastVm object and populate it from the deserialized data &lt;/li&gt;
&lt;li&gt;Return the WeatherForecastVm instance so it can be used for databinding. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Almost all of this happens off of the UI thread (basically everything up to step 6).&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Furthermore, the DataManager tracks instances, so the instance that&amp;rsquo;s returned from the Load call will *always* be the same (for the given identity value) for your entire application.&amp;nbsp; This means that as long as you use this Load call, and databind to that object, any future refreshes of that data will automatically be reflected in your UI, regardless of where it is in your application.&amp;nbsp; You don&amp;rsquo;t need to worry about any of this, it just works.&amp;nbsp; More on this below.&amp;nbsp; AgFx does the caching and fast lookup for you, so don&amp;rsquo;t hold references to these values if you don&amp;rsquo;t absolutely have to.&lt;/p&gt;
&lt;h2&gt;Loading On Demand&lt;/h2&gt;
&lt;p&gt;Using &lt;strong&gt;DataManager.Load&amp;lt;&amp;gt;&lt;/strong&gt; allows the framework to control when and where items are loaded.&amp;nbsp; This also allows your app to do work only as it&amp;rsquo;s needed to populate your UI.&amp;nbsp; And once you break up the work into discreet view model objects, you can also control their caching policy independently.&amp;nbsp; If you look at the WeatherForecastVm in the sample, you&amp;rsquo;ll see the following property:&lt;/p&gt;
&lt;pre class="csharpcode"&gt; &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
 &lt;span class="rem"&gt;/// ZipCode info is the name of the city for the zipcode.  This is a sepearate &lt;/span&gt;
 &lt;span class="rem"&gt;/// service lookup, so we treat it seperately.&lt;/span&gt;
&lt;span class="rem"&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
 &lt;span class="kwrd"&gt;public&lt;/span&gt; ZipCodeVm ZipCodeInfo
 {
    get
    {                
      &lt;strong&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; DataManager.Current.Load&amp;lt;ZipCodeVm&amp;gt;(LoadContext.ZipCode);&lt;/strong&gt;
    }
 }&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Note that this property results in a call to another VM class &amp;ndash; &amp;ldquo;ZipCodeVm&amp;rdquo;.&amp;nbsp; If you look at the image up above, you&amp;rsquo;ll see that the name &amp;ldquo;Redmond&amp;rdquo; is shown under the 98052 zip code.&amp;nbsp; This information didn&amp;rsquo;t come down with the weather data, I had to fetch it from another service.&amp;nbsp; But since it&amp;rsquo;s based off the same identifier (&amp;ldquo;98052&amp;rdquo;) as the weather forecast, we just pass that along.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;When I want my UI to show the city, as above, I&amp;rsquo;ll databind a TextBlock like so:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt; &lt;strong&gt;&lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;="{Binding ZipCodeInfo.City}"&lt;/span&gt;&lt;/strong&gt; &lt;span class="attr"&gt;FontWeight&lt;/span&gt;&lt;span class="kwrd"&gt;="Bold"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;To which the databinding engine does the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;On the current DataContext, look for a property called &amp;ldquo;ZipCodeInfo&amp;rdquo; &lt;/li&gt;
&lt;li&gt;Fetch that value, and then (if not null) look for a property called &amp;ldquo;City&amp;rdquo; &lt;/li&gt;
&lt;li&gt;Fetch that value and set it as the Text property &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So, back to our &lt;strong&gt;WeatherForecastVm&lt;/strong&gt; object, when the databinding engine asks for the &lt;strong&gt;ZipCodeInfo &lt;/strong&gt;property value,that request will be kicked off.&amp;nbsp; But here&amp;rsquo;s the trick.&amp;nbsp; It&amp;rsquo;s kicked off asynchronously.&amp;nbsp; Execution won&amp;rsquo;t be held up while that value is fetched.&amp;nbsp; So what &lt;em&gt;does&lt;/em&gt; it return?&lt;/p&gt;
&lt;p&gt;I mentioned above that the instance returned from then Load call will always been the same for a given instance*.&amp;nbsp; So here&amp;rsquo;s what happens:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The Load&amp;lt;&amp;gt; call is made &lt;/li&gt;
&lt;li&gt;A default instance of ZipCodeVm is created and returned.&amp;nbsp; The UI will databind against this instance &lt;/li&gt;
&lt;li&gt;AgFx does the off-thread work of getting the value from the web service, deserializing it into a ZipCodeVm object, and caching it on disk. &lt;/li&gt;
&lt;li&gt;AgFx then takes and &lt;strong&gt;copies&lt;/strong&gt; the updated values into the properties of the instance that was created.&amp;nbsp; Since it is this instance that is being databound against, the UI will automatically update with these new values. &lt;/li&gt;
&lt;li&gt;Any future Load calls, if new data is fetched, will also update this instance. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The net result is that UI anywhere in the application that is bound to a value retrieved via the &lt;strong&gt;Load&amp;lt;&amp;gt;&lt;/strong&gt; method will always be kept up to date.&amp;nbsp; No code wiring needed.&lt;/p&gt;
&lt;p&gt;Finally, another upside to breaking up object like this is that you can specify a different cache policy.&amp;nbsp; If you remember, the &lt;strong&gt;WeatherForecastVm&lt;/strong&gt; policy was &lt;strong&gt;ValidOnly&lt;/strong&gt;, for 15 minutes.&lt;/p&gt;
&lt;p&gt;Zip codes don&amp;rsquo;t change much so we&amp;rsquo;re doing this instead:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// this basically never changes, but we'll say it's valid for a year.&lt;/span&gt;
&lt;strong&gt;[CachePolicy(CachePolicy.CacheThenRefresh, 3600 * 24 * 365)]&lt;/strong&gt; 
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ZipCodeVm : ModelItemBase&amp;lt;ZipCodeLoadContext&amp;gt;{...}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CacheThenRefresh&lt;/strong&gt; means that if a request is made and there is a cached value that has expired, go ahead and return that cached value and &lt;em&gt;automatically &lt;/em&gt;kick off a refresh.&amp;nbsp; Just as in the case above, the refresh will update the instance that was created out of the cache and your UI will update when the refresh happens.&amp;nbsp; A common case for this is an app that shows a Twitter feed.&amp;nbsp; When you launch Twitter, you may want to see the feed as it was last time you opened the app, then have the new posts show as they come in off the network.&lt;/p&gt;
&lt;p&gt;* this isn&amp;rsquo;t strictly true &amp;ndash; if no one is holding the value, it can be garbage collected so it&amp;rsquo;s not using memory, and then a new instance will be created on demand at the next request.&amp;nbsp; But since it&amp;rsquo;s not being held in memory, your code will never know that.&lt;/p&gt;
&lt;h2&gt;Take a look&lt;/h2&gt;
&lt;p&gt;That&amp;rsquo;s a quick introduction to AgFx, and there is a LOT more.&amp;nbsp; We&amp;rsquo;ve been writing apps internally on top of it for a while now and we&amp;rsquo;re having great success and there are a bunch of more features that allow you to handle things your app might need to do quickly and efficiently.&amp;nbsp; So for now, grab the code and run the app and get a feel for the framework.&amp;nbsp; Ask questions in the comments and I&amp;rsquo;ll start digging into more advanced features in posts I&amp;rsquo;ll do shortly. &lt;/p&gt;
&lt;h3&gt;AgFx is available via CodePlex&amp;nbsp;&lt;a href="http://agfx.codeplex.com"&gt;here&lt;/a&gt;. &amp;nbsp;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10140123" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/sburke/archive/tags/Silverlight/">Silverlight</category><category domain="http://blogs.msdn.com/b/sburke/archive/tags/Windows+Phone+7/">Windows Phone 7</category><category domain="http://blogs.msdn.com/b/sburke/archive/tags/AgFx/">AgFx</category></item><item><title>Using ObservableCollection with the Portable Library Tools CTP</title><link>http://blogs.msdn.com/b/sburke/archive/2011/02/03/using-observablecollection-with-the-portable-library-tools-ctp.aspx</link><pubDate>Thu, 03 Feb 2011 19:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10124522</guid><dc:creator>Shawn Burke - MSFT</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/sburke/rsscomments.aspx?WeblogPostID=10124522</wfw:commentRss><comments>http://blogs.msdn.com/b/sburke/archive/2011/02/03/using-observablecollection-with-the-portable-library-tools-ctp.aspx#comments</comments><description>&lt;p&gt;One of the main goals of the Portable Library Tools is to be able to implement your ViewModel in the Portable Library such that you can share it between your UI in your Silverlight, Windows Phone, or even WPF project.&amp;nbsp; Unfortunately, this is a bit of a challenge with the Portable Library Tools CTP, because it does not include ObservableCollection&amp;lt;T&amp;gt; or INotifyCollectionChanged.&lt;/p&gt;
&lt;p&gt;The reason for this is simple.&amp;nbsp; The CTP doesn&amp;rsquo;t have references for System.Windows, and both ObservableCollection&amp;lt;T&amp;gt; and INotifyCollectionChanged are defined in System.Windows.&amp;nbsp; That they are defined in this assembly isn&amp;rsquo;t the best in terms of layering, and we have been discussing what to do about that.&amp;nbsp; But they are there, and we&amp;rsquo;re looking to address this issue in a future release of the Portable Library Tools.&amp;nbsp; But that doesn&amp;rsquo;t help you now, does it?&lt;/p&gt;
&lt;p&gt;In fact, ObservableCollection is one of a few common classes that you may find you would like to be able to address from your portable code.&amp;nbsp; The other one that I&amp;rsquo;ve run into is HttpUtility.UrlEncode/UrlDecode, so I&amp;rsquo;ll handle that here as well.&lt;/p&gt;
&lt;p&gt;There are two ways to handle this, in general:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If you have a common class or interface that is available to all callers, you can key off of you can use a service locator pattern or some kind of dependency injection (ISomething impl = Factory.GetInstance&amp;lt;ISomething&amp;gt;();)&lt;/li&gt;
&lt;li&gt;If you don&amp;rsquo;t have a common class or interface, you can create a class that allows you to define the specific operations you&amp;rsquo;re interested in&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the case of ObservableCollection, we have case (2).&amp;nbsp; Because ObservableCollection/INotifyCollectionChanged aren&amp;rsquo;t available as part of the Portable Library Tools references.&amp;nbsp; So there is no way to do the following:&lt;/p&gt;
&lt;pre class="csharpcode"&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MyViewModel {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;ObservableCollection&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;&lt;/span&gt; _strings = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;ObservableCollection&lt;/span&gt;&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;ObservableCollection&lt;/span&gt;&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; Strings {
            get {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; _strings;
            }
        }
    }&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;This is an interesting case where a Dependency Injection strategy won&amp;rsquo;t work.&lt;/p&gt;
&lt;p&gt;However, if we look closer at ObservableCollection, we see that it derives from IList, which has the methods that we care about (Add, Remove, etc.).&amp;nbsp; But what we really care about this is consumers of our ViewModel &amp;ndash; specifically Silverlight&amp;rsquo;s databinding engine.&amp;nbsp;&amp;nbsp; Fortunately, the databinding engine uses reflection to check for INotifyCollectionChanged on the collection itself rather than the object being used as the DataContext.&amp;nbsp; So it doesn&amp;rsquo;t matter what the type is on our ViewModel, it matters what type that object actually is.&lt;/p&gt;
&lt;p&gt;With this knowledge in hand, our strategy is simple, and we implement it as follows.&lt;/p&gt;
&lt;p&gt;First, we type our ViewModel collection property as IList:&lt;/p&gt;
&lt;pre class="csharpcode"&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; PortableViewModel : INotifyPropertyChanged {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; IList&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; _stringList;
        &lt;span class="kwrd"&gt;public&lt;/span&gt; IList&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; Strings {
            get {                
                &lt;span class="kwrd"&gt;return&lt;/span&gt; _stringList;
            }
        }
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Now, we define a class that is abstract in our Portable Library, but will be implemented in the application projects.&amp;nbsp; The idea is to keep this as simple as possible:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; PortabilityFactory {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; PortabilityFactory _factory;

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; PortabilityFactory Current {
            get {
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (_factory == &lt;span class="kwrd"&gt;null&lt;/span&gt;) {
                    &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; InvalidOperationException();
                }
                &lt;span class="kwrd"&gt;return&lt;/span&gt; _factory;
            }
            set {
                _factory = &lt;span class="kwrd"&gt;value&lt;/span&gt;;
            }
        }

        &lt;span class="kwrd"&gt;protected&lt;/span&gt; PortabilityFactory() {
           &lt;span class="rem"&gt;// note we auto-set current here,&lt;/span&gt;
           &lt;span class="rem"&gt;// which saves an extra step for the caller&lt;/span&gt;
            Current = &lt;span class="kwrd"&gt;this&lt;/span&gt;;            
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; IList&amp;lt;T&amp;gt; CreateList&amp;lt;T&amp;gt;() {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;T&amp;gt;();
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; UrlEncode(&lt;span class="kwrd"&gt;string&lt;/span&gt; url);
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; UrlDecode(&lt;span class="kwrd"&gt;string&lt;/span&gt; url);
    }&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;We go back to our ViewModel, and specify the right call:&lt;/p&gt;
&lt;pre class="csharpcode"&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; IList&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; Strings {
       get {
           &lt;span class="kwrd"&gt;if&lt;/span&gt; (_stringList == &lt;span class="kwrd"&gt;null&lt;/span&gt;) {
               _stringList = PortabilityFactory.Current.CreateList&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();
           }
           &lt;span class="kwrd"&gt;return&lt;/span&gt; _stringList;
        }
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Now, we go to our project and implement.&amp;nbsp; Here&amp;rsquo;s the Phone example, and the Silverlight example, respectively.&amp;nbsp; The best place to create this is in App.xaml.cs so it happens at app start up.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; WindowsPhoneApplication1 {
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; App : Application {

        &lt;span class="kwrd"&gt;private&lt;/span&gt; PortabilityFactory _pf = &lt;span class="kwrd"&gt;new&lt;/span&gt; PhonePortabilityFactory();

        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; PhonePortabilityFactory : PortabilityFactory {
            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; IList&amp;lt;T&amp;gt; CreateList&amp;lt;T&amp;gt;() {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ObservableCollection&amp;lt;T&amp;gt;();
            }

            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; UrlDecode(&lt;span class="kwrd"&gt;string&lt;/span&gt; url) {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; System.Net.HttpUtility.UrlDecode(url);
            }

            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; UrlEncode(&lt;span class="kwrd"&gt;string&lt;/span&gt; url) {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; System.Net.HttpUtility.UrlEncode(url);
            } 
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; SilverlightApplication1
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; App : Application
    {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; PortabilityFactory _pf = &lt;span class="kwrd"&gt;new&lt;/span&gt; SilverlightPortabilityFactory();

        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SilverlightPortabilityFactory : PortabilityFactory {
            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; IList&amp;lt;T&amp;gt; CreateList&amp;lt;T&amp;gt;() {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ObservableCollection&amp;lt;T&amp;gt;();
            }

            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; UrlDecode(&lt;span class="kwrd"&gt;string&lt;/span&gt; url) {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; System.Windows.Browser.HttpUtility.UrlDecode(url);
            }

            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; UrlEncode(&lt;span class="kwrd"&gt;string&lt;/span&gt; url) {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; System.Windows.Browser.HttpUtility.UrlEncode(url);
            }
        }
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Now you&amp;rsquo;ve done all you need to, and the rest of the system will work properly, and you can use the ViewModel directly as a datacontext:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; MainPage()
{
      InitializeComponent();
      &lt;span class="kwrd"&gt;this&lt;/span&gt;._vm = &lt;span class="kwrd"&gt;new&lt;/span&gt; PortableObservableCollection.PortableViewModel();
      &lt;span class="kwrd"&gt;this&lt;/span&gt;.DataContext = _vm;
}&lt;/pre&gt;
&lt;p&gt;Even when Portable Library Tools reaches it&amp;rsquo;s version 1, there will still be things that aren&amp;rsquo;t in the portable subset.&amp;nbsp; You can use variations of the above techniques to handle those types as well.&amp;nbsp; For some more complex features, you can use more of a Service Locator or Dependency Injection pattern.&amp;nbsp;&amp;nbsp; An example of this in the CTP is IsolatedStorage, which is not currently in the subset.&amp;nbsp;&amp;nbsp; For this you can imagine creating an IFileStorage interface and having it&amp;rsquo;s implementation plumb through to the Isolated Storage APIs, but use it generically in your portable library code.&amp;nbsp; We are looking to minimize these situations as time goes on.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve attached the project from which the code snippets came.&amp;nbsp; Note you&amp;rsquo;ll need to install the &lt;a target="_blank" href="http://go.microsoft.com/fwlink/?LinkId=207130"&gt;Visual Studio 2010 SP1 Beta&lt;/a&gt;, and the &lt;a target="_blank" href="http://go.microsoft.com/fwlink/?LinkID=206334&amp;amp;clcid=0x409"&gt;Portable Library Tools CTP&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10124522" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-12-45-22/PortableObservableCollection.zip" length="50391" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/b/sburke/archive/tags/PortableLibraries/">PortableLibraries</category></item><item><title>3-Screen Coding Is Here: Portable Library Tools allow you to target multiple .NET platforms with one binary!</title><link>http://blogs.msdn.com/b/sburke/archive/2011/01/23/3-screen-coding-is-here-portable-library-tools-allow-you-to-target-multiple-net-platforms-with-one-binary.aspx</link><pubDate>Sun, 23 Jan 2011 02:07:46 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10119091</guid><dc:creator>Shawn Burke - MSFT</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/sburke/rsscomments.aspx?WeblogPostID=10119091</wfw:commentRss><comments>http://blogs.msdn.com/b/sburke/archive/2011/01/23/3-screen-coding-is-here-portable-library-tools-allow-you-to-target-multiple-net-platforms-with-one-binary.aspx#comments</comments><description>&lt;p&gt;Earlier this week, we released the &lt;a href="http://go.microsoft.com/fwlink/?LinkID=206334&amp;amp;clcid=0x409"&gt;Portable Library Tools CTP&lt;/a&gt;.&amp;#160; You’ll need to install the &lt;a href="http://go.microsoft.com/fwlink/?LinkId=207130"&gt;VS 2010 SP1 Beta&lt;/a&gt; first, then it’s a quick install on top of that.&lt;/p&gt;  &lt;h3&gt;What is it?&lt;/h3&gt;  &lt;p&gt;Back at PDC in October, I did a PDC talk called &lt;a href="http://bit.ly/aUlqkU" target="_blank"&gt;&lt;strong&gt;3-Screen Coding: Sharing Code Between Windows Phone, Silverlight, and .NET&lt;/strong&gt;&lt;/a&gt;.&amp;#160; If you want to spend some time to get the full scoop on what the Portable Library Tools are all about, you watch it online by clicking &lt;a href="http://bit.ly/aUlqkU" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;But if you don’t have time for that, the basic idea is as follows:&lt;/p&gt;  &lt;p&gt;A &lt;strong&gt;Portable Library&lt;/strong&gt; is a DLL that will run compatibly across a set of .NET platforms.&amp;#160; The set of platforms currently supported for this CTP are .NET 4, Windows Phone 7, Silverlight 4, and XNA Framework 4.0 for XBox 360.&amp;#160; &lt;/p&gt;  &lt;p&gt;The &lt;strong&gt;Portable Library Tools CTP&lt;/strong&gt; introduces a new project type called the &lt;strong&gt;Portable Class Library&lt;/strong&gt;, which does two things:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Allows you to pick which of the supported platforms you’d wish to target, and &lt;/li&gt;    &lt;li&gt;Gives you a “view” (Intellisense, Object Browser, Compiler, etc.) of the APIs that are command and compatible among those platforms &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;So essentially what this does is guide you in building code that you can trust will behave the same way on a set of platforms.&amp;#160; And, naturally, if you choose all the platforms, you get a smaller “view” of the world than if you choose a set of similar platforms.&amp;#160; This is because, as soon as one platform doesn’t have a given API, it can’t be in the widest set.&lt;/p&gt;  &lt;p&gt;You can build portable libraries with VB or C#.&amp;#160; The project type is currently under the “Windows” node in the Add New Project dialog.&amp;#160; For more details, check out &lt;a href="http://blogs.msdn.com/b/bclteam/archive/2011/01/19/announcing-portable-library-tools-ctp-justin-van-patten.aspx" target="_blank"&gt;Justin’s post on the CLR team blog&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Why is a given API in (or not in) the subset?&lt;/h3&gt;  &lt;p&gt;When you start building a portable library, you’ll notice that the list of APIs available is smaller than you’re used to, but we think it’s still big enough to get things done.&lt;/p&gt;  &lt;p&gt;How did we decide what to put in there and what not to?&lt;/p&gt;  &lt;p&gt;Well, the process was pretty straight forward.&amp;#160; First we thought about what would be necessary to build reasonably sophisticated code that one would want to share among different platforms – the minimum useful subset.&amp;#160; We thought it was something like core BCL, plus basic networking, plus basic XML handling.&amp;#160; As we went through scenarios and writing test projects, we verified that that was the minimum set of things you needed to write useful code, at least for the scenarios we tried.&lt;/p&gt;  &lt;p&gt;So we then took and converted that into the set of assemblies that contain such functionality:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;mscorlib &lt;/li&gt;    &lt;li&gt;system &lt;/li&gt;    &lt;li&gt;system.core &lt;/li&gt;    &lt;li&gt;system.net &lt;/li&gt;    &lt;li&gt;system.xml &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;We mapped out all of their types, properties, methods, and events for all of the platforms, then took the intersection of that list.&amp;#160; This gave us the list of API signatures that were present in on all platforms.&amp;#160; We went through this list and discovered some things that &lt;em&gt;should&lt;/em&gt; have been on a given platform but weren’t, and we filed work items to get those added.&lt;/p&gt;  &lt;p&gt;Second, we walked through that intersection and tried to remove obsolete and duplicate ways of doing things.&amp;#160; For example, we did not include the old type-unsafe collection types, such as ArrayList.&amp;#160; We removed many of the formatting methods that did not take an IFormatProvider parameter, because supplying that has been a clear best practice.&amp;#160; And so on.&lt;/p&gt;  &lt;p&gt;As this is a CTP, this is an ongoing process and open to feedback from you.&amp;#160; We’ll be repeating the process with some of the platform subsets, so you’ll get a larger set of APIs if you only want to target Silverlight 4 and Windows Phone 7, for example.&amp;#160; &lt;/p&gt;  &lt;p&gt;So if you find an API that you &lt;em&gt;think&lt;/em&gt; should be in the subset, ensure that it’s actually available on all of the platforms (it has to be the &lt;em&gt;exact&lt;/em&gt; same signature), and then see the above caveats.&amp;#160; I’m sure we missed some things, so let us know in the comments if there’s something you really think should be there and we’ll look at it!&lt;/p&gt;  &lt;p&gt;As it currently is, here’s what’s where:&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="91"&gt;         &lt;p&gt;&lt;b&gt;Feature&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="180"&gt;         &lt;p&gt;&lt;b&gt;Assemblies&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="102"&gt;         &lt;p&gt;&lt;b&gt;.NET Framework 4&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="90"&gt;         &lt;p&gt;&lt;b&gt;Silverlight 4&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="72"&gt;         &lt;p&gt;&lt;b&gt;Windows Phone 7&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="90"&gt;         &lt;p&gt;&lt;b&gt;Xbox 360&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="91"&gt;         &lt;p&gt;Core BCL&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="180"&gt;         &lt;p&gt;mscorlib.dll&lt;/p&gt;          &lt;p&gt;System.dll&lt;/p&gt;          &lt;p&gt;System.Core.dll&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="102"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="90"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="72"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="90"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="91"&gt;         &lt;p&gt;Core XML&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="180"&gt;         &lt;p&gt;System.Xml.dll&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="102"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="90"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="72"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="90"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="91"&gt;         &lt;p&gt;Core HTTP&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="180"&gt;         &lt;p&gt;System.Net.dll&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="102"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="90"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="72"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="90"&gt;         &lt;p&gt;-&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="91"&gt;         &lt;p&gt;WCF Client&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="180"&gt;         &lt;p&gt;System.ServiceModel.dll&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="102"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="90"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="72"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="90"&gt;         &lt;p&gt;-&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="91"&gt;         &lt;p&gt;XML Serialization&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="180"&gt;         &lt;p&gt;System.Xml.Serialization.dll&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="102"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="90"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="72"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="90"&gt;         &lt;p&gt;-&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="91"&gt;         &lt;p&gt;MEF&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="180"&gt;         &lt;p&gt;System.ComponentModel.Composition.dll&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="102"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="90"&gt;         &lt;p&gt;X&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="72"&gt;         &lt;p&gt;-&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="90"&gt;         &lt;p&gt;-&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;Note the inclusion of an assembly in this list &lt;em&gt;does not mean all of it’s functionality is supported&lt;/em&gt;, only the functionality that is common between the platforms that it exists on.&lt;/p&gt;  &lt;h3&gt;How to use the Portable Library Tools to build an application&lt;/h3&gt;  &lt;p&gt;If you are careful in how you design your application, you’ll find that you can build a large part of it as a portable library.&amp;#160; The basic pattern is to put all of the code that you want to be portable into the portable library, and then have all the code that references a specific platform into a platform project.&lt;/p&gt;  &lt;p&gt;So you could imagine your solution looks like the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/1488.image_5F00_7A04A09D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-97-metablogapi/5102.image_5F00_thumb_5F00_58A4FB01.png" width="307" height="484" /&gt;&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;    &lt;p&gt;Where you have one portable library that defines the service access, business logic, and view models for both a Silverlight 4 and a Window Phone 7 application.&lt;/p&gt;  &lt;h3&gt;What about UI?&lt;/h3&gt;  &lt;p&gt;When I first started working on the Window Phone 7 project in July of 2009, there was quite a bit of talk about what the right application model was between Silverlight and the phone.&amp;#160; Should I just be able to run Silverlight applications straight away on the phone?&amp;#160; Should all the XAML be portable?&amp;#160; Should VS have a mode where you can select your platform and modify your project for either Silverlight or for the Phone and then somehow automatically switch between the “right” code at runtime?&amp;#160;&amp;#160; Should there be some kind of a importer thing that magically reformats your Silverlight app into a phone application?&amp;#160;&amp;#160; The point is, there were no shortage of creative ideas on this topic.&amp;#160; But most of them seemed (at best) complex or error-prone.&lt;/p&gt;  &lt;p&gt;One of the challenges to application portability – meaning the exact same application just runs on platform A and B – is that there are often different or missing facilities.&amp;#160;&amp;#160;&amp;#160; Consider the functionality that’s in System.Windows.Browser in Silverlight, which is primarily focused on accessing the DOM of the browser that Silverlight (if in-browser) is hosted in.&amp;#160; This has no clear analogue on Windows Phone, where Silverlight is natively hosted as a full screen application.&amp;#160; So such functionality is either going to missing (meaning your app crashes at runtime) or stubbed out (meaning your app probably crashes at runtime!).&amp;#160; There are a wide range of these types of differences and it’s not easy to deal with them in a consistent way.&amp;#160; To do is a lot of extra work devoted to things that most developers won’t ever try to use in their platform-specific applications anyway.&amp;#160; &lt;/p&gt;  &lt;p&gt;More importantly, is that for an app to be really useful, it needs to conform to the UI paradigms and input methods of the target platform.&amp;#160; Consider the DataGrid control in Silverlight, and how it is used.&amp;#160; This is a control that’s really designed to be used with a mouse and keyboard.&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;I spent some time writing applications for Silverlight and then writing them for the phone, and as I did so it became clear that sharing UI wasn’t as great as it sounded.&amp;#160; In fact, with well written ViewModels, it was much, much easier to craft nice, specific XAML for each platform and then just quickly use Blend or Visual Studio to wire it up and take advantage of the powerful, flexible databinding system that the Silverlight runtime provides.&amp;#160; Creating the UI specifically for each platform is critical to delivering applications with a great user experience.&lt;/p&gt;  &lt;p&gt;The Portable Library Tools CTP doesn’t yet allow you to reference System.Windows.dll, functionality, but that is planned for a future release.&amp;#160; This gives you access to the Silverlight UI types like Button, Grid, UIElement, and Storyboard.&amp;#160; So while sharing UI isn’t that useful, being able to write sharable components that reference or modify UI can be.&amp;#160;&amp;#160; For example, it’s nice to be able to share things like value converters.&lt;/p&gt;  &lt;h3&gt;What’s missing?&lt;/h3&gt;  &lt;p&gt;Our goal for this CTP was to get something usable out there and see what people were able to do with it, and then let feedback drive what we focus on.&amp;#160; Many things we know about and are working to get them added, but there are probably some important small things that we missed.&lt;/p&gt;  &lt;p&gt;For things that can’t be in the portable subset because they are different across each platform, there are ways of dealing with this cleanly (okay, fairly cleanly) within your application.&amp;#160; I’ll cover that in an upcoming post.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10119091" width="1" height="1"&gt;</description></item><item><title>iPhone SDK vs. Windows Phone 7 Series SDK Challenge, Part 2: MoveMe</title><link>http://blogs.msdn.com/b/sburke/archive/2010/03/27/iphone-sdk-vs-windows-phone-7-series-sdk-challenge-part-2-moveme.aspx</link><pubDate>Sat, 27 Mar 2010 01:42:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9986045</guid><dc:creator>Shawn Burke - MSFT</dc:creator><slash:comments>15</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/sburke/rsscomments.aspx?WeblogPostID=9986045</wfw:commentRss><comments>http://blogs.msdn.com/b/sburke/archive/2010/03/27/iphone-sdk-vs-windows-phone-7-series-sdk-challenge-part-2-moveme.aspx#comments</comments><description>&lt;P&gt;&lt;EM&gt;In this series, I will be taking sample applications from the iPhone SDK and implementing them on Windows Phone 7 Series.&amp;nbsp; My goal is to do as much of an “apples-to-apples” comparison as I can.&amp;nbsp; This series will be written to not only compare and contrast how easy or difficult it is to complete tasks on either platform, how many lines of code, etc., but I’d also like it to be a way for iPhone developers to either get started on Windows Phone 7 Series development, or for developers in general to learn the platform.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Here’s my methodology:&lt;/EM&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;EM&gt;Run the iPhone SDK app in the iPhone Simulator to get a feel for what it does and how it works, without looking at the implementation&lt;/EM&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;Implement the equivalent functionality on Windows Phone 7 Series using Silverlight.&lt;/EM&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;Compare the two implementations based on complexity, functionality, lines of code, number of files, etc.&lt;/EM&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;Add some functionality to the Windows Phone 7 Series app that shows off a way to make the scenario more interesting or leverages an aspect of the platform, or uses a better design pattern to implement the functionality.&lt;/EM&gt; &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;EM&gt;You can download Microsoft Visual Studio 2010 Express for Windows Phone CTP &lt;A href="http://developer.windowsphone.com/windows-phone-7-series/" mce_href="http://developer.windowsphone.com/windows-phone-7-series/"&gt;here&lt;/A&gt;, and the Expression Blend 4 Beta &lt;A href="http://blogs.msdn.com/expression/archive/2010/03/15/expression-blend-4-beta-and-information-on-windows-phone-development.aspx" mce_href="http://blogs.msdn.com/expression/archive/2010/03/15/expression-blend-4-beta-and-information-on-windows-phone-development.aspx"&gt;here&lt;/A&gt;.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;If you’re seeing this series for the first time, check out &lt;/EM&gt;&lt;A href="http://blogs.msdn.com/sburke/archive/2010/03/23/iphone-sdk-vs-windows-phone-7-series-sdk-challenge-part-1-hello-world.aspx" mce_href="http://blogs.msdn.com/sburke/archive/2010/03/23/iphone-sdk-vs-windows-phone-7-series-sdk-challenge-part-1-hello-world.aspx"&gt;Part 1: Hello World.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;A note on methodology…in the prior post there was some feedback about lines of code not being a very good metric for this exercise.&amp;nbsp; I don’t really disagree, there’s a lot more to this than lines of code but I believe that is a relevant metric, even if it’s not the ultimate one.&amp;nbsp; And there’s no perfect answer here.&amp;nbsp; So I am going to continue to report the number of lines of code that I, as a developer would need to write in these apps as a data point, and I’ll leave it up to the reader to determine how that fits in with overall complexity, etc.&amp;nbsp; The first example was so basic that I think it was difficult to talk about in real terms.&amp;nbsp; I think that as these apps get more complex, the subjective differences in concept count and will be more important.&amp;nbsp; &lt;/EM&gt;&lt;/P&gt;
&lt;H2&gt;MoveMe&lt;/H2&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/MoveMe%5B1%5D_4.jpg" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/MoveMe%5B1%5D_4.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; MARGIN: 0px 5px 0px 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=MoveMe[1] border=0 alt=MoveMe[1] align=left src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/MoveMe%5B1%5D_thumb_1.jpg" width=125 height=240 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/MoveMe%5B1%5D_thumb_1.jpg"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;The &lt;A href="http://developer.apple.com/iphone/library/samplecode/MoveMe/index.html" mce_href="http://developer.apple.com/iphone/library/samplecode/MoveMe/index.html"&gt;MoveMe&lt;/A&gt; app is the main end-to-end app writing example in the iPhone SDK, called &lt;A href="http://developer.apple.com/iphone/library/referencelibrary/GettingStarted/Creating_an_iPhone_App/index.html" mce_href="http://developer.apple.com/iphone/library/referencelibrary/GettingStarted/Creating_an_iPhone_App/index.html"&gt;Creating an iPhone Application&lt;/A&gt;.&amp;nbsp; This application demonstrates a few concepts, including handling touch input, how to do animations, and how to do some basic transforms.&lt;/P&gt;
&lt;P&gt;The behavior of the application is pretty simple.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User touches the button&lt;/STRONG&gt;: The button does a “throb” type animation where it scales up and then back down briefly.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User drags the button&lt;/STRONG&gt;: After a touch begins, moving the touch point will drag the button around with the touch.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User lets go of the button: &lt;/STRONG&gt;The button animates back to its original position, but does a few small bounces as it reaches it’s original point, which makes the app fun and gives it an extra bit of interactivity.&lt;/P&gt;
&lt;P&gt;Now, how would I write an app that meets this spec for Windows Phone 7 Series, and how hard would it be?&amp;nbsp; Let’s find out!&lt;/P&gt;
&lt;H2&gt;&amp;nbsp;&lt;/H2&gt;
&lt;H2&gt;&amp;nbsp;&lt;/H2&gt;
&lt;H2&gt;Implementing the UI&lt;/H2&gt;
&lt;P&gt;Okay, let’s build the UI for this application.&amp;nbsp; In the &lt;A href="http://blogs.msdn.com/sburke/archive/2010/03/23/iphone-sdk-vs-windows-phone-7-series-sdk-challenge-part-1-hello-world.aspx" mce_href="http://blogs.msdn.com/sburke/archive/2010/03/23/iphone-sdk-vs-windows-phone-7-series-sdk-challenge-part-1-hello-world.aspx"&gt;HelloWorld&lt;/A&gt; example, we did all the UI design in Visual Studio and/or by hand in XAML.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;In this example, we’re going to use the &lt;A href="http://blogs.msdn.com/expression/archive/2010/03/15/expression-blend-4-beta-and-information-on-windows-phone-development.aspx" mce_href="http://blogs.msdn.com/expression/archive/2010/03/15/expression-blend-4-beta-and-information-on-windows-phone-development.aspx"&gt;Expression Blend 4 Beta&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;You might be wondering when to use Visual Studio, when to use Blend, and when to do XAML by hand.&amp;nbsp; Different people will have different takes on this, but here’s mine:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;XAML by hand – simple UI that doesn’t contain animations, gradients, etc., and or UI that I want to really optimize and craft when I know exactly what I want to do. &lt;/LI&gt;
&lt;LI&gt;Visual Studio – Basic UI layout, property setting, data binding, etc. &lt;/LI&gt;
&lt;LI&gt;Blend – Any serious design work needs to be done in Blend, including animations, handling states and transitions, styling and templating, editing resources. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;As in Part 1, go ahead and fire up Visual Studio 2010 Express for Windows Phone (yes, soon it will take longer to say the name of our products than to start them up!), and create a new Windows Phone Application.&amp;nbsp; As in Part 1, clear out the XAML from the designer.&amp;nbsp; An easy way to do this is to just:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Click on the design surface &lt;/LI&gt;
&lt;LI&gt;Hit Control+A &lt;/LI&gt;
&lt;LI&gt;Hit Delete &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;There’s a little bit left over (the “Grid.RowDefinitions” element), just go ahead and delete that element so we’re starting with a clean state of only one outer Grid element.&lt;/P&gt;
&lt;P&gt;To use Blend, we need to save this project.&amp;nbsp; See, when you create a project with Visual Studio Express, it doesn’t commit it to the disk (well, in a place where you can find it, at least) until you actually save &lt;EM&gt;the project&lt;/EM&gt;.&amp;nbsp; This is handy if you’re doing some fooling around, because it doesn’t clutter your disk with WindowsPhoneApplication23-like directories.&amp;nbsp; But it’s also kind of dangerous, since when you close VS, if you don’t save &lt;EM&gt;the project&lt;/EM&gt;…it’s all gone.&amp;nbsp; Yes, this has bitten me since I was saving files and didn’t remember that, so be careful to save the project/solution via “Save All”, at least once.&lt;/P&gt;
&lt;P&gt;So, save and note the location on disk.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Start Expression Blend 4 Beta, and chose File –&amp;gt; Open Project/Solution, and load your project.&amp;nbsp; You should see just about the same thing you saw over in VS: a blank, black designer surface.&lt;/P&gt;
&lt;P&gt;Now, thinking about this application, we don’t really need a button, even though it looks like one.&amp;nbsp; We never click it.&amp;nbsp; So we’re just going to create a visual and use that.&amp;nbsp; This is also true in the iPhone example above, where the visual is actually not a button either but a jpg image with a nice gradient and round edges.&amp;nbsp; We’ll do something simple here that looks pretty good.&lt;/P&gt;
&lt;P&gt;In Blend, look in the tool pane on the left for the icon that looks like the below (the highlighted one on the left), and hold it down to get the popout menu, and choose “Border”:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_52.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_52.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_25.png" width=186 height=161 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_25.png"&gt;&lt;/A&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Okay, now draw out a box in the middle of the design surface of about 300x100.&amp;nbsp; The &lt;STRONG&gt;Properties Pane &lt;/STRONG&gt;to the left should show the properties for this item.&lt;/P&gt;
&lt;P&gt;First, let’s make it more visible by giving it a border brush.&amp;nbsp; Set the BorderBrush to white by clicking BorderBrush and dragging the color selector all the way to the upper right in the palette.&amp;nbsp; Then, down a bit farther, make the BorderThickness 4 all the way around, and the CornerRadius set to 6.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_8.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_8.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_3.png" width=265 height=460 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_3.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;In the Layout section, do the following to Width, Height, Horizontal and Vertical Alignment, and Margin (all 4 margin values):&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_6.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_6.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_2.png" width=222 height=244 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_2.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;You’ll see the outline now is in the middle of the design surface.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Now let’s give it a background color.&amp;nbsp; Above “BorderBrush” select “Background”, and click the third tab over: Gradient Brush.&amp;nbsp; You’ll see a gradient slider at the bottom, and if you click the markers, you can edit the gradient stops individually (or add more).&amp;nbsp; In this case, you can select something you like, but where’s what I chose:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_12.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_12.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_5.png" width=258 height=364 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_5.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Left stop: #BFACCFE2 (I just picked a spot on the palette and set opacity to 75%, no magic here, feel free to fiddle these or just enter these numbers into the hex area and be done with it)&lt;/P&gt;
&lt;P&gt;Right stop: #FF3E738F&lt;/P&gt;
&lt;P&gt;Okay, looks pretty good.&amp;nbsp; Finally set the name of the element in the “&lt;STRONG&gt;Name&lt;/STRONG&gt;” field at the top of the Properties pane to “&lt;STRONG&gt;welcome&lt;/STRONG&gt;”. &lt;/P&gt;
&lt;P&gt;Now let’s add some text.&amp;nbsp; Just hit “T” and it’ll select the TextBlock tool automatically:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_14.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_14.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_6.png" width=41 height=107 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_6.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Now draw out some are inside our “welcome” visual and type “Welcome!”, then click on the design surface (to exit text entry mode) and hit “V” to go back into selection mode (or the top item in the tool pane that looks like a mouse pointer).&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Click on the text again to select it in the tool pane.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Just like the border, we want to center this.&amp;nbsp; So set HorizontalAlignment and VerticalAlignment to “Center”, and clear the Margins:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_16.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_16.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_7.png" width=244 height=161 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_7.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;That’s it for the UI.&amp;nbsp; Here’s how it looks, on the design surface:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_18.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_18.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_8.png" width=279 height=484 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_8.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Not bad!&amp;nbsp; Okay, now the fun part…&lt;/P&gt;
&lt;H2&gt;Adding Animations&lt;/H2&gt;
&lt;P&gt;Using Blend to build animations is a lot of fun, and it’s easy.&amp;nbsp; In XAML, I can not only declare elements and visuals, but also I can declare animations that will affect those visuals.&amp;nbsp; These are called &lt;STRONG&gt;Storyboards&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;To recap, we’ll be doing two animations:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;The “throb” animation when the element is touched &lt;/LI&gt;
&lt;LI&gt;The “center” animation when the element is released after being dragged. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;The throb animation is just a&lt;STRONG&gt; scale transform&lt;/STRONG&gt;, so we’ll do that first.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;In the &lt;STRONG&gt;Objects and Timeline Pane &lt;/STRONG&gt;(left side, bottom half), click the little + icon to add a new Storyboard called “touchStoryboard”:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_22.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_22.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_10.png" width=331 height=86 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_10.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;The timeline view will appear.&amp;nbsp; In there, click a bit to the right of “0” to create a keyframe at .2 seconds:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_24.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_24.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_11.png" width=282 height=108 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_11.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Now, click on our “welcome” element (the Border, not the TextBlock in it), and scroll to the bottom of the Properties Pane.&amp;nbsp; Open up &lt;STRONG&gt;Transform&lt;/STRONG&gt;, click the third tab ("&lt;STRONG&gt;Scale&lt;/STRONG&gt;”), and set X and Y to 1.2:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_26.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_26.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_12.png" width=244 height=134 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_12.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;This all of this says that, at .2 seconds, I want the X and Y size of this element to scale to 1.2. &lt;/P&gt;
&lt;P&gt;In fact you can see this happen.&amp;nbsp; Push the “Play” arrow in the timeline view, and you’ll see the animation run!&lt;/P&gt;
&lt;P&gt;Let’s make two tweaks.&amp;nbsp; First, we want the animation to automatically reverse so it scales up then back down nicely.&lt;/P&gt;
&lt;P&gt;Click in the dropdown that says “touchStoryboard” in Objects and Timeline, then in the Properties pane check “&lt;STRONG&gt;Auto Reverse&lt;/STRONG&gt;”:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_30.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_30.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_14.png" width=155 height=96 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_14.png"&gt;&lt;/A&gt; &lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_32.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_32.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_15.png" width=166 height=78 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_15.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Now run it again, and you’ll see it go both ways. Let’s even make it nicer by adding an easing function.&lt;/P&gt;
&lt;P&gt;First, click on the “Render Transform” item in the Objects tree, then, in the Property Pane, you’ll see a bunch of easing functions to choose from.&amp;nbsp; Feel free to play with this, then seeing how each runs.&amp;nbsp; I chose “&lt;STRONG&gt;Circle In&lt;/STRONG&gt;”, but some other ones are fun.&amp;nbsp; Try them out!&amp;nbsp; Elastic In is kind of fun, but we’ll stick with Circle In.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_34.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_34.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_16.png" width=161 height=199 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_16.png"&gt;&lt;/A&gt; &lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_36.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_36.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_17.png" width=132 height=244 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_17.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;That’s it for that animation.&lt;/P&gt;
&lt;P&gt;Now, we also want an animation to move the Border back to it’s original position when the user ends the touch gesture.&amp;nbsp; This is exactly the same process as above, but just targeting a different transform property.&lt;/P&gt;
&lt;P&gt;Create a new animation called “releaseStoryboard”&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Select a timeline point at 1.2 seconds. &lt;/LI&gt;
&lt;LI&gt;Click on the “welcome” Border element again &lt;/LI&gt;
&lt;LI&gt;Scroll to the “Transforms” panel at the bottom of the Properties Pane &lt;/LI&gt;
&lt;LI&gt;Choose the first tab (“Translate”), which may already be selected &lt;/LI&gt;
&lt;LI&gt;Set both X and Y values to 0.0 (we do this just to make the values stick, because the value is already 0 and we need Blend to know we want to save that value) &lt;/LI&gt;
&lt;LI&gt;Click on “RenderTransform” in the Objects tree &lt;/LI&gt;
&lt;LI&gt;In the properties pane, choose “&lt;STRONG&gt;Bounce Out&lt;/STRONG&gt;” &lt;/LI&gt;
&lt;LI&gt;Set “Bounces” to 6, and “Bounciness” to 4 (feel free to play with these as well) &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_40.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_40.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_19.png" width=244 height=156 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_19.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Okay, we’re done.&lt;/P&gt;
&lt;P&gt;Note, if you want to test this Storyboard, you have to do something a little tricky because the final value is the same as the initial value, so playing it does nothing.&amp;nbsp; If you want to play with it, do the following:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Next to the selection dropdown, hit the little "x” (&lt;STRONG&gt;Close Storyboard&lt;/STRONG&gt;) &lt;/LI&gt;
&lt;LI&gt;Go to the Translate Transform value for “welcome” &lt;/LI&gt;
&lt;LI&gt;Set X,Y to –50, –200, respectively (or whatever) &lt;/LI&gt;
&lt;LI&gt;Select “releaseStoryboard” again from the dropdown &lt;/LI&gt;
&lt;LI&gt;Hit play, see it run &lt;/LI&gt;
&lt;LI&gt;Go into the object tree and select “RenderTransform” to change the easing function. &lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;When you’re done, hit the Close Storyboard “x” again and set the values in Transform/Translate back to 0&lt;/STRONG&gt; &lt;/LI&gt;&lt;/OL&gt;
&lt;H2&gt;Wiring Up the Animations&lt;/H2&gt;
&lt;P&gt;Okay, now go back to Visual Studio.&amp;nbsp; You’ll get a prompt due to the modification of MainPage.xaml.&amp;nbsp; Hit “Yes”.&lt;/P&gt;
&lt;P&gt;In the designer, click on the “welcome” Border element.&amp;nbsp; In the &lt;STRONG&gt;Property Browser, &lt;/STRONG&gt;hit the “Events” button, then double click each of “ManipulationStarted”, “ManipulationDelta”, “ManipulationCompleted”.&amp;nbsp; You’ll need to flip back to the designer from code, after each double click.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_44.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_44.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_21.png" width=377 height=379 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_21.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;It’s code time.&amp;nbsp; Here we go.&lt;/P&gt;
&lt;P&gt;Here, three event handlers have been created for us:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;welcome_ManipulationStarted&lt;/STRONG&gt;: This will execute when a manipulation begins.&amp;nbsp; Think of it as MouseDown.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;welcome_ManipulationDelta&lt;/STRONG&gt;: This executes each time a manipulation changes.&amp;nbsp; Think MouseMove.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;welcome_ManipulationCompleted&lt;/STRONG&gt;: This will&amp;nbsp; execute when the manipulation ends. Think MouseUp.&lt;/P&gt;
&lt;P&gt;Now, in ManipuliationStarted, we want to kick off the “throb” animation that we called “touchAnimation”.&amp;nbsp; That’s easy:&lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; welcome_ManipulationStarted(&lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; sender, ManipulationStartedEventArgs e)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;{&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;    touchStoryboard.Begin();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;Likewise, when the manipulation completes, we want to re-center the welcome visual with our bounce animation:&lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; welcome_ManipulationCompleted(&lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; sender, ManipulationCompletedEventArgs e)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;{&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;    releaseStoryboard.Begin();  &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;Note there is actually a way to kick off these animations from Blend directly via something called “Triggers”, but I think it’s clearer to show what’s going on like this.&amp;nbsp; A Trigger basically allows you to say “When this event fires, trigger this Storyboard”, so it’s the exact same logical process as above, but without the code.&lt;/P&gt;
&lt;P&gt;But how do we get the object to move?&amp;nbsp; Well, for that we really don’t want an animation because we want it to respond immediately to user input.&lt;/P&gt;
&lt;P&gt;We do this by directly modifying the transform to match the offset for the manipulation, and then we’ll let the animation bring it back to zero when the manipulation completes.&amp;nbsp; The manipulation events do a great job of keeping track of all the stuff that you usually had to do yourself when doing drags: where you started from, how far you’ve moved, etc.&lt;/P&gt;
&lt;P&gt;So we can easily modify the position as below:&lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; welcome_ManipulationDelta(&lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; sender, ManipulationDeltaEventArgs e)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;{&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;    CompositeTransform transform = (CompositeTransform)welcome.RenderTransform;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;    transform.TranslateX = e.CumulativeManipulation.Translation.X;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;    transform.TranslateY = e.CumulativeManipulation.Translation.Y;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;That’s it!&lt;/P&gt;
&lt;P&gt;Go ahead and run the app in the emulator.&amp;nbsp; I suggest running without the debugger, it’s a little faster (CTRL+F5).&amp;nbsp; If you’ve got a machine that supports DirectX 10, you’ll see nice smooth GPU accelerated graphics, which also what it looks like on the phone, running at about 60 frames per second.&amp;nbsp; If your machine does not support DX10 (like the laptop I’m writing this on!), it won’t be quite a smooth so you’ll have to take my word for it!&lt;/P&gt;
&lt;H2&gt;&lt;/H2&gt;
&lt;H2&gt;Comparing Against the iPhone&lt;/H2&gt;
&lt;P&gt;This is an example where the flexibility and power of XAML meets the tooling of Visual Studio and Blend, and the whole experience really shines.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;So, for several things that are declarative and 100% toolable with the Windows Phone 7 Series, this example does them with code on the iPhone.&amp;nbsp; In parens is the lines of code that I count to do these operations.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;PlacardView.m&lt;/STRONG&gt;: 19 total LOC 
&lt;UL&gt;
&lt;LI&gt;Creating the view that hosts the button-like image and the text &lt;/LI&gt;
&lt;LI&gt;Drawing the image that is the background of the button &lt;/LI&gt;
&lt;LI&gt;Drawing the “Welcome” text over the image (I think you could &lt;EM&gt;technically&lt;/EM&gt; do this step and/or the prior one using Interface Builder) &lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;MoveMeView.m&lt;/STRONG&gt;:&amp;nbsp; 63 total LOC 
&lt;UL&gt;
&lt;LI&gt;Constructing and running the scale (“throb”) animation (25) &lt;/LI&gt;
&lt;LI&gt;Constructing the path describing the animation back to center plus bounce effect (38) &lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Beyond the code count, yy experience with doing this kind of thing in code is that it’s VERY time intensive.&amp;nbsp; When I was a developer back on Windows Forms, doing GDI+ drawing, we did this stuff a lot, and it took forever!&amp;nbsp; You write some code and even once you get it basically working, you see it’s not quite right, you go back, tweak the interval, or the math a bit, run it again, etc.&amp;nbsp; You can take a look at the iPhone code &lt;A href="http://developer.apple.com/iphone/library/samplecode/MoveMe/listing4.html" mce_href="http://developer.apple.com/iphone/library/samplecode/MoveMe/listing4.html"&gt;here&lt;/A&gt; to judge for yourself.&amp;nbsp; Scroll down to “animatePlacardViewToCenter” toward the bottom.&amp;nbsp; I don’t think this code is terribly complicated, but it’s not what I’d call simple and it’s not at all simple to get right.&lt;/P&gt;
&lt;P&gt;And then there’s a few other lines of code running around for setting up the ViewController and the Views, about 15 lines between MoveMeAppDelegate, PlacardView, and MoveMeView, plus the assorted decls in the h files.&lt;/P&gt;
&lt;P&gt;Adding those up, I conservatively get something like &lt;STRONG&gt;100 lines of code (19+63+15+decls) on iPhone &lt;/STRONG&gt;that I have to write, by hand, to make this project work.&lt;/P&gt;
&lt;P&gt;The lines of code that I wrote in the examples above is &lt;STRONG&gt;5 lines of code on Windows Phone 7 Series.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In terms of incremental concept counts beyond the HelloWorld app, here’s a shot at that:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;iPhone&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Drawing Images &lt;/LI&gt;
&lt;LI&gt;Drawing Text &lt;/LI&gt;
&lt;LI&gt;Handling touch events &lt;/LI&gt;
&lt;LI&gt;Creating animations &lt;/LI&gt;
&lt;LI&gt;Scaling animations &lt;/LI&gt;
&lt;LI&gt;Building a path and animating along that &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Windows Phone 7 Series:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Laying out UI in Blend &lt;/LI&gt;
&lt;LI&gt;Creating &amp;amp; testing basic animations in Blend &lt;/LI&gt;
&lt;LI&gt;Handling touch events &lt;/LI&gt;
&lt;LI&gt;Invoking animations from code &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;This was actually the first example I tried converting, even before I did the HelloWorld, and I was pretty surprised.&amp;nbsp; Some of this is luck that this app happens to match up with the Windows Phone 7 Series platform just perfectly.&amp;nbsp; In terms of time, I wrote the above application, from scratch, in about 10 minutes.&amp;nbsp; I don’t know how long it would take a very skilled iPhone developer to write MoveMe on that iPhone from scratch, but if I was to write it on Silverlight in the same way (e.g. all via code), I think it would likely take me at least an hour or two to get it all working right, maybe more if I ended up picking the wrong strategy or couldn’t get the math right, etc.&lt;/P&gt;
&lt;H2&gt;&lt;/H2&gt;
&lt;H2&gt;Making Some Tweaks&lt;/H2&gt;
&lt;P&gt;Silverlight contains a feature called “Projections” to do a variety of 3D-like effects with a 2D surface.&lt;/P&gt;
&lt;P&gt;So let’s play with that a bit.&lt;/P&gt;
&lt;P&gt;Go back to Blend and select the “welcome” Border in the object tree.&amp;nbsp; In it’s properties, scroll down to the bottom, open Transform, and see &lt;STRONG&gt;Projection &lt;/STRONG&gt;at the bottom.&amp;nbsp; Set X,Y,Z to 90.&amp;nbsp; You’ll see the element kind of disappear, replaced by a thin blue line.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_46.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_46.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_22.png" width=382 height=139 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_22.png"&gt;&lt;/A&gt; &lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_48.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_48.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_23.png" width=136 height=244 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_23.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Now…&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Create a new animation called “startupStoryboard”. &lt;/LI&gt;
&lt;LI&gt;Set it’s key time to .5 seconds in the timeline view &lt;/LI&gt;
&lt;LI&gt;Set the projection values above to 0 for X, Y, and Z. &lt;/LI&gt;
&lt;LI&gt;Save &lt;/LI&gt;
&lt;LI&gt;Go back to Visual Studio, and in the constructor, add the following bold code (lines 7-9 to the constructor: &lt;/LI&gt;&lt;/OL&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; MainPage()&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;{&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;    InitializeComponent();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;    SupportedOrientations = SupportedPageOrientation.Portrait;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;STRONG&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;this&lt;/SPAN&gt;.Loaded += (s, e) =&amp;gt;&lt;/STRONG&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;STRONG&gt;&lt;SPAN class=lnum&gt;   8:  &lt;/SPAN&gt;    {&lt;/STRONG&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;STRONG&gt;&lt;SPAN class=lnum&gt;   9:  &lt;/SPAN&gt;        startupStoryboard.Begin();&lt;/STRONG&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;STRONG&gt;&lt;SPAN class=lnum&gt;  10:  &lt;/SPAN&gt;    };&lt;/STRONG&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  11:  &lt;/SPAN&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;If the code above looks funny, it’s using something called a lambda in C#, which is an inline anonymous method.&amp;nbsp; It’s just a handy shorthand for creating a handler like the manipulation ones above.&lt;/P&gt;
&lt;P&gt;So with this you’ll get a nice 3D looking fly in effect when the app starts up.&amp;nbsp; Here it is, in flight:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_50.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_50.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_24.png" width=250 height=484 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPh.WindowsPhone7SeriesSDKChallengePart2_8C17/image_thumb_24.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Pretty cool!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9986045" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-98-60-45/MoveMe.zip" length="23679" type="application/x-zip-compressed" /></item><item><title>iPhone SDK vs Windows Phone 7 Series SDK Challenge, Part 1: Hello World!</title><link>http://blogs.msdn.com/b/sburke/archive/2010/03/23/iphone-sdk-vs-windows-phone-7-series-sdk-challenge-part-1-hello-world.aspx</link><pubDate>Tue, 23 Mar 2010 14:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9983355</guid><dc:creator>Shawn Burke - MSFT</dc:creator><slash:comments>20</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/sburke/rsscomments.aspx?WeblogPostID=9983355</wfw:commentRss><comments>http://blogs.msdn.com/b/sburke/archive/2010/03/23/iphone-sdk-vs-windows-phone-7-series-sdk-challenge-part-1-hello-world.aspx#comments</comments><description>&lt;P&gt;&lt;EM&gt;In this series, I will be taking sample applications from the iPhone SDK and implementing them on Windows Phone 7 Series.&amp;nbsp; My goal is to do as much of an “apples-to-apples” comparison as I can.&amp;nbsp; This series will be written to not only compare and contrast how easy or difficult it is to complete tasks on either platform, how many lines of code, etc., but I’d also like it to be a way for iPhone developers to either get started on Windows Phone 7 Series development, or for developers in general to learn the platform.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Here’s my methodology:&lt;/EM&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;EM&gt;Run the iPhone SDK app in the iPhone Simulator to get a feel for what it does and how it works, without looking at the implementation&lt;/EM&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;Implement the equivalent functionality on Windows Phone 7 Series using Silverlight.&lt;/EM&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;Compare the two implementations based on complexity, functionality, lines of code, number of files, etc.&lt;/EM&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;Add some functionality to the Windows Phone 7 Series app that shows off a way to make the scenario more interesting or leverages an aspect of the platform, or uses a better design pattern to implement the functionality.&lt;/EM&gt; &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;EM&gt;You can download Microsoft Visual Studio 2010 Express for Windows Phone CTP &lt;A href="http://developer.windowsphone.com/windows-phone-7-series/" mce_href="http://developer.windowsphone.com/windows-phone-7-series/"&gt;here&lt;/A&gt;, and the Expression Blend 4 Beta &lt;A href="http://blogs.msdn.com/expression/archive/2010/03/15/expression-blend-4-beta-and-information-on-windows-phone-development.aspx" mce_href="http://blogs.msdn.com/expression/archive/2010/03/15/expression-blend-4-beta-and-information-on-windows-phone-development.aspx"&gt;here&lt;/A&gt;.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;/EM&gt;&lt;/P&gt;
&lt;H2&gt;Hello World!&lt;/H2&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/simulator%5B1%5D_2.jpg" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/simulator%5B1%5D_2.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; MARGIN: 0px 5px 0px 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=simulator[1] border=0 alt=simulator[1] align=left src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/simulator%5B1%5D_thumb.jpg" width=130 height=240 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/simulator%5B1%5D_thumb.jpg"&gt;&lt;/A&gt; Of course no first post would be allowed if it didn’t focus on the “hello world” scenario.&amp;nbsp; The iPhone SDK follows that tradition with the &lt;A href="http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhone101/Articles/00_Introduction.html" mce_href="http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhone101/Articles/00_Introduction.html"&gt;Your First iPhone Application walkthrough&lt;/A&gt;.&amp;nbsp; I will say that the developer documentation for iPhone is pretty good.&amp;nbsp; There are plenty of walkthoughs and they break things down into nicely sized steps and do a good job of bringing the user along.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;As expected, this application is quite simple.&amp;nbsp; It comprises of a text box, a label, and a button.&amp;nbsp; When you push the button, the label changes to “Hello” plus the&amp;nbsp; word you typed into the text box.&amp;nbsp; Makes perfect sense for a starter application.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;There’s not much to this but it covers a few basic elements:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Laying out basic UI &lt;/LI&gt;
&lt;LI&gt;Handling user input &lt;/LI&gt;
&lt;LI&gt;Hooking up events &lt;/LI&gt;
&lt;LI&gt;Formatting text &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;So, let’s get started building a similar app for Windows Phone 7 Series! &lt;/P&gt;
&lt;H2&gt;Implementing the UI:&lt;/H2&gt;
&lt;P&gt;UI in Silverlight (and therefore Windows Phone 7) is defined in XAML, which is a declarative XML language also used by WPF on the desktop.&amp;nbsp; For anyone that’s familiar with similar types of markup, it’s relatively straightforward to learn, but has a lot of power in it once you get it figured out.&amp;nbsp; We’ll talk more about that.&lt;/P&gt;
&lt;P&gt;This UI is very simple.&amp;nbsp; When I look at this, I note a couple of things:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Elements are arranged vertically &lt;/LI&gt;
&lt;LI&gt;They are all centered &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;So, let’s create our Application and then start with the UI.&amp;nbsp; Once you have the the VS 2010 Express for Windows Phone tool running, create a new Windows Phone Project, and call it Hello World:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/image_2.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/image_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/image_thumb.png" width=644 height=446 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/image_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Once created, you’ll see the designer on one side and your XAML on the other:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/image_4.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/image_4.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/image_thumb_1.png" width=644 height=438 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/image_thumb_1.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Now, we can create our UI in one of three ways:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Use the designer in Visual Studio to drag and drop the components &lt;/LI&gt;
&lt;LI&gt;Use the designer in Expression Blend 4 to drag and drop the components &lt;/LI&gt;
&lt;LI&gt;Enter the XAML by hand in either of the above &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;We’ll start with (1), then kind of move to (3) just for instructional value.&lt;/P&gt;
&lt;P&gt;To develop this UI in the designer:&lt;/P&gt;
&lt;P&gt;First, delete all of the markup between inside of the Grid element (LayoutRoot).&amp;nbsp; You should be left with just this XAML for your MainPage.xaml (i shortened all the xmlns declarations below for brevity):&lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;phoneNavigation:PhoneApplicationPage&lt;/SPAN&gt; &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;    &lt;SPAN class=attr&gt;x:Class&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="HelloWorld.MainPage"&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;   &lt;SPAN class=attr&gt;xmlns&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="...[snip]"&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;    &lt;SPAN class=attr&gt;FontFamily&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="{StaticResource PhoneFontFamilyNormal}"&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;    &lt;SPAN class=attr&gt;FontSize&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="{StaticResource PhoneFontSizeNormal}"&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;    &lt;SPAN class=attr&gt;Foreground&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="{StaticResource PhoneForegroundBrush}"&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   8:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;Grid&lt;/SPAN&gt; &lt;SPAN class=attr&gt;x:Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="LayoutRoot"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Background&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="{StaticResource PhoneBackgroundBrush}"&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   9:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  10:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;Grid&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  11:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  12:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;phoneNavigation:PhoneApplicationPage&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;STYLE type=text/css&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;We’ll be adding XAML at line 9, so that’s the important part.&lt;/P&gt;
&lt;P&gt;Now, &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Click on the center area of the phone surface &lt;/LI&gt;
&lt;LI&gt;Open the Toolbox and double click “StackPanel” &lt;/LI&gt;
&lt;LI&gt;Double click “TextBox” &lt;/LI&gt;
&lt;LI&gt;Double click “TextBlock” &lt;/LI&gt;
&lt;LI&gt;Double click “Button” &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;That will create the necessary UI elements but they won’t be arranged quite right.&amp;nbsp; We’ll fix it in a second.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Here’s the XAML that we end up with:&lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;StackPanel&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Height&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="100"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;HorizontalAlignment&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Left"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Margin&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="10,10,0,0"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="stackPanel1"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;VerticalAlignment&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Top"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Width&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="200"&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;         &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;TextBox&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Height&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="32"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="textBox1"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Text&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="TextBox"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Width&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="100"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;         &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;TextBlock&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Height&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="23"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="textBlock1"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Text&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="TextBlock"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;         &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;Button&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Content&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Button"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Height&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="70"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="button1"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Width&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="160"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;StackPanel&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;STYLE type=text/css&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;The designer does it’s best at guessing what we want, but in this case we want things to be a bit simpler. &lt;/P&gt;
&lt;P&gt;So we’ll just clean it up a bit.&amp;nbsp; We want the items to be centered and we want them to have a little bit of a margin on either side, so here’s what we end up with.&amp;nbsp; I’ve also made it match the values and style from the iPhone app:&lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;StackPanel&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Margin&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="10"&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;TextBox&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="textBox1"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;HorizontalAlignment&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Stretch"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Text&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="You"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;TextAlignment&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Center"&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;TextBlock&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="textBlock1"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;HorizontalAlignment&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Center"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Margin&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="0,100,0,0"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Text&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Hello You!"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;Button&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="button1"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;HorizontalAlignment&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Center"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Margin&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="0,150,0,0"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Content&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Hello"&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;StackPanel&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;  &lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;STYLE type=text/css&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;STYLE type=text/css&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;Now let’s take a look at what we’ve done there.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Line 1: We removed all of the formatting from the StackPanel, except for Margin, as that’s all we need.&amp;nbsp; Since our parent element is a Grid, by default the StackPanel will be sized to fit in that space.&amp;nbsp; The Margin says that we want to reserve 10 pixels on each side of the StackPanel. &lt;/LI&gt;
&lt;LI&gt;Line 2: We’ve set the HorizontalAlignment of the TextBox to “Stretch”, which says that it should fill it’s parent’s size horizontally.&amp;nbsp; We want to do this so the TextBox is always full-width.&amp;nbsp; We also set TextAlignment to Center, to center the text. &lt;/LI&gt;
&lt;LI&gt;Line 3: In contrast to the TextBox above, we don’t care how wide the TextBlock is, just so long as it is big enough for it’s text.&amp;nbsp; That’ll happen automatically, so we just set it’s Horizontal alignment to Center.&amp;nbsp; We also set a Margin above the TextBlock of 100 pixels to bump it down a bit, per the iPhone UI. &lt;/LI&gt;
&lt;LI&gt;Line 4: We do the same things here as in Line 3. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Here’s how the UI looks in the designer:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/image_6.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/image_6.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/image_thumb_2.png" width=644 height=438 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/image_thumb_2.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Believe it or not, we’re almost done!&lt;/P&gt;
&lt;H2&gt;Implementing the App Logic&lt;/H2&gt;
&lt;P&gt;Now, we want the TextBlock to change it’s text when the Button is clicked.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;In the designer, double click the Button to be taken to the Event Handler for the Button’s Click event.&amp;nbsp; In that event handler, we take the Text property from the TextBox, and format it into a string, then set it into the TextBlock.&amp;nbsp; That’s it!&lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; button1_Click(&lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; sender, RoutedEventArgs e)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;{&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; name = textBox1.Text;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;    &lt;SPAN class=rem&gt;// if there isn't a name set, just use "World"&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (String.IsNullOrEmpty(name))&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;    {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   8:  &lt;/SPAN&gt;        name = &lt;SPAN class=str&gt;"World"&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   9:  &lt;/SPAN&gt;    }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  10:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  11:  &lt;/SPAN&gt;    &lt;SPAN class=rem&gt;// set the value into the TextBlock&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  12:  &lt;/SPAN&gt;    textBlock1.Text = String.Format(&lt;SPAN class=str&gt;"Hello {0}!"&lt;/SPAN&gt;, name);&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  13:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  14:  &lt;/SPAN&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;We use the String.Format() method to handle the formatting for us.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Now all that’s left is to test the app in the Windows Phone Emulator and verify it does what we think it does!&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/image_8.png" mce_href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/image_8.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/image_thumb_3.png" width=398 height=772 mce_src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/iPhoneSDKvsWindowsPhone7SeriesSDKChallen_FF7B/image_thumb_3.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;And it does!&lt;/P&gt;
&lt;H2&gt;Comparing against the iPhone&lt;/H2&gt;
&lt;P&gt;Looking at the iPhone example, there are basically three things that you have to touch as the developer:&lt;/P&gt;
&lt;P&gt;1) The UI in the Nib file&lt;/P&gt;
&lt;P&gt;2) The app delegate&lt;/P&gt;
&lt;P&gt;3) The view controller&lt;/P&gt;
&lt;P&gt;Counting lines is a bit tricky here, but to try to keep this even, I’m going to only count lines of code that I could not have (or would not have) generated with the tooling.&amp;nbsp; Meaning, I’m not counting XAML and I’m not counting operations that happen in the Nib file with the XCode designer tool.&amp;nbsp; So in the case of the above, even though I modified the XAML, I could have done all of those operations using the visual designer tool.&amp;nbsp; And normally I would have, but the XAML is more instructive (and less steps!).&amp;nbsp; I’m interested in things that I, as the developer have to figure out in code.&amp;nbsp; I’m also not counting lines that just have a curly brace on them, or lines that are generated for me (e.g. method names that are generated for me when I make a connection, etc.)&lt;/P&gt;
&lt;P&gt;So, by that count, here’s what I get from the code listing for the iPhone app &lt;A href="http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhone101/Articles/A1_CodeListings.html" mce_href="http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhone101/Articles/A1_CodeListings.html"&gt;found here&lt;/A&gt;:&lt;/P&gt;
&lt;P&gt;HelloWorldAppDelegate.h: 6&lt;/P&gt;
&lt;P&gt;HelloWorldAppDelegate.m: 12&lt;/P&gt;
&lt;P&gt;MyViewController.h: 8&lt;/P&gt;
&lt;P&gt;MyViewController.m: 18&lt;/P&gt;
&lt;P&gt;Which gives me a grand total of about &lt;STRONG&gt;44 lines of code on iPhone&lt;/STRONG&gt;.&amp;nbsp; I really do recommend &lt;A href="http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhone101/Articles/A1_CodeListings.html" mce_href="http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhone101/Articles/A1_CodeListings.html"&gt;looking at the iPhone code&lt;/A&gt; for a comparison to the above.&lt;/P&gt;
&lt;P&gt;Now, for the Windows Phone 7 Series application, the only code I typed was in the event handler above&lt;/P&gt;
&lt;P&gt;Main.Xaml.cs: 4&lt;/P&gt;
&lt;P&gt;So a total of&lt;STRONG&gt; 4 lines of code on Windows Phone 7&lt;/STRONG&gt;.&amp;nbsp; And more importantly, the process is just A LOT simpler.&amp;nbsp; For example, I was surprised that the User Interface Designer in XCode doesn’t automatically create instance variables for me and wire them up to the corresponding elements.&amp;nbsp; I assumed I wouldn’t have to write this code myself (and risk getting it wrong!).&amp;nbsp; I don’t need to worry about view controllers or anything.&amp;nbsp; I just write my code.&amp;nbsp; This blog post up to this point has covered almost every aspect of this app’s development in a few pages.&amp;nbsp; The &lt;A href="http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhone101/Articles/00_Introduction.html" mce_href="http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhone101/Articles/00_Introduction.html"&gt;iPhone tutorial&lt;/A&gt; has 5 top level steps with 2-3 sub sections of each. &lt;/P&gt;
&lt;P&gt;Now, it’s worth pointing out that the iPhone development model uses the Model View Controller (MVC) pattern, which is a very flexible and powerful pattern that enforces proper separation of concerns.&amp;nbsp; But it’s fairly complex and difficult to understand when you first walk up to it.&amp;nbsp; Here at Microsoft we’ve dabbled in MVC a bit, with frameworks like MFC on Visual C++ and with the ASP.NET MVC framework now.&amp;nbsp; Both are very powerful frameworks.&amp;nbsp; But one of the reasons we’ve stayed away from MVC with client UI frameworks is that it’s difficult to tool.&amp;nbsp; We haven’t seen the type of value that beats “double click, write code!” for the broad set of scenarios.&lt;/P&gt;
&lt;P&gt;Another thing to think about is “how many of those lines of code were focused on my app’s functionality?”.&amp;nbsp; Or, the converse of “How many lines of code were boilerplate plumbing?”&amp;nbsp; In both examples, the actual number of “functional” code lines is similar.&amp;nbsp; I count most of them in MyViewController.m, in the changeGreeting method.&amp;nbsp; It’s about 7 lines of code that do the work of taking the value from the TextBox and putting it into the label.&amp;nbsp; Versus 4 on the Windows Phone 7 side.&amp;nbsp; But, unfortunately, on iPhone I still have to write that other 37 lines of code, just to get there.&lt;/P&gt;
&lt;P&gt;10% of the code, 1 file instead of 4, it’s just much simpler.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;Making Some Tweaks&lt;/H2&gt;
&lt;P&gt;It turns out, I can actually do this application with&lt;STRONG&gt; ZERO&amp;nbsp; lines of code&lt;/STRONG&gt;, if I’m willing to change the spec a bit. The data binding functionality in Silverlight is incredibly powerful.&amp;nbsp; And what I can do is databind the TextBox’s value directly to the TextBlock.&amp;nbsp; Take some time looking at this XAML below.&amp;nbsp; You’ll see that I have added another nested StackPanel and two more TextBlocks.&amp;nbsp; Why?&amp;nbsp; Because that’s how I build that string, and the nested StackPanel will lay things out Horizontally for me, as specified by the Orientation property.&lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;StackPanel&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Margin&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="10"&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;TextBox&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="textBox1"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;HorizontalAlignment&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Stretch"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Text&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="You"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;TextAlignment&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Center"&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;StackPanel&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Orientation&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Horizontal"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;HorizontalAlignment&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Center"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Margin&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="0,100,0,0"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;        &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;TextBlock&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Text&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Hello "&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;        &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;TextBlock&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="textBlock1"&lt;/SPAN&gt;  &lt;STRONG&gt;&lt;SPAN class=attr&gt;Text&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="{Binding ElementName=textBox1, Path=Text}"&lt;/SPAN&gt;&lt;/STRONG&gt;  &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;        &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;TextBlock&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Text&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="!"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;StackPanel&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;            &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   8:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;Button&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="button1"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;HorizontalAlignment&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Center"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Margin&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="0,150,0,0"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Content&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Hello"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Click&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="button1_Click"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   9:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;StackPanel&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;Now, the real action is there in the bolded &lt;STRONG&gt;TextBlock.Text&lt;/STRONG&gt; property:&lt;/P&gt;&lt;PRE class=csharpcode&gt;Text="{Binding ElementName=textBox1, Path=Text}" &lt;/PRE&gt;
&lt;STYLE type=text/css&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;That does all the heavy lifting.&amp;nbsp; It sets up a databinding between the &lt;STRONG&gt;TextBox.Text&lt;/STRONG&gt; property on textBox1 and the &lt;STRONG&gt;TextBlock.Text&lt;/STRONG&gt; property on textBlock1. As I change the text of the TextBox, the label updates automatically.&lt;/P&gt;
&lt;P&gt;In fact, I don’t even need the button any more, so I could get rid of that altogether.&amp;nbsp; And no button means no event handler.&amp;nbsp; No event handler means no C# code at all.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Want to see more? Check out &lt;A href="http://blogs.msdn.com/sburke/archive/2010/03/27/iphone-sdk-vs-windows-phone-7-series-sdk-challenge-part-2-moveme.aspx" mce_href="http://blogs.msdn.com/sburke/archive/2010/03/27/iphone-sdk-vs-windows-phone-7-series-sdk-challenge-part-2-moveme.aspx"&gt;Part Two&lt;/A&gt;.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9983355" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-98-33-55/HelloWorld.zip" length="22909" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/b/sburke/archive/tags/Windows+Phone+7/">Windows Phone 7</category><category domain="http://blogs.msdn.com/b/sburke/archive/tags/iPhone+Challenge/">iPhone Challenge</category></item><item><title>Silverlight Toolkit March 2009 Release</title><link>http://blogs.msdn.com/b/sburke/archive/2009/03/20/silverlight-toolkit-march-2009-release.aspx</link><pubDate>Sat, 21 Mar 2009 00:17:38 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9493583</guid><dc:creator>Shawn Burke - MSFT</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/sburke/rsscomments.aspx?WeblogPostID=9493583</wfw:commentRss><comments>http://blogs.msdn.com/b/sburke/archive/2009/03/20/silverlight-toolkit-march-2009-release.aspx#comments</comments><description>&lt;p&gt;This week we released an updated Silverlight Toolkit - the &lt;a href="http://silverlight.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=20430"&gt;Silverlight Toolkit March 2009&lt;/a&gt; release.&amp;#160;&amp;#160; This release has some new components, but we spent a lot of time working to make sure that the Toolkit can be updated in an agile way, but still fits in nicely with other platform and tools releases.&lt;/p&gt;  &lt;h3&gt;Goals for the March 2009 Release&lt;/h3&gt;  &lt;h4&gt;1. Align the Toolkit with the SDK&lt;/h4&gt;  &lt;p&gt;The main thing that we wanted to establish was a smooth flow of components from the Toolkit into the platform, in this case the SDK.&amp;#160; Most Toolkit components are things that people will want to have in their default tooling experience, and one of our goals is to minimize the number of things that developers must download to get productive with the platform.&amp;#160; So the first order of business was to setup the Toolkit to be primarily an incubation vehicle for SDK components.&amp;#160; So most components start in the Toolkit, and end up eventually in the SDK that comes with Visual Studio or Expression Blend.&lt;/p&gt;  &lt;p&gt;This also meant pulling the existing SDK controls into the Toolkit package.&amp;#160; With the March 2009 release, you'll find the source code for all of the Silverlight 3 versions of the SDK controls - DataGrid, Calendar, TabControl, etc.&amp;#160; As with the rest of the Toolkit, this code is licensed under MS-PL so you're free to modify it or use it in your application.&lt;/p&gt;  &lt;h4&gt;2. Do the work to support Silverlight 2 and Silverlight 3&lt;/h4&gt;  &lt;p&gt;With Silverlight 3 coming into the picture, we needed to structure the Toolkit project to be able to handle both versions.&amp;#160;&amp;#160; Our philosophy is to do as much work in the Silverlight 2 Toolkit as possible, then just do things in Silverlight 3 that have a dependency on the new runtime.&amp;#160; We'll continue to support Silverlight 2 up through the release of Silverlight 3, then we'll focus on Silverlight 3 exclusively as customers upgrade.&amp;#160; On the &lt;a href="http://silverlight.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=20430"&gt;Release&lt;/a&gt; page you'll see a Silverlight 3 Beta and Silverlight 2 installer.&lt;/p&gt;  &lt;h4&gt;3. Fully support the Blend and Visual Studio development environments&lt;/h4&gt;  &lt;p&gt;I've always been a big believer in delivering great design-time experiences.&amp;#160; We've done a lot of work with the tools teams to make sure that our components work well with the designers, including having items in the Toolbox and having the right properties show up in the tool. This turned out to be more work than we had anticipated and we're hopeful that any customers that are writing components can use what we've done as a good example of how to make all of this stuff work. We'll keep pushing on making this a great experience over time.&lt;/p&gt;  &lt;h4&gt;4. Address critical customer feedback&lt;/h4&gt;  &lt;p&gt;The biggest piece of feedback we've gotten is to have our Samples available in VB.NET as well as C#, so we did the work to make that happen.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/SilverlightToolkitMarch2009Release_C18A/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/SilverlightToolkitMarch2009Release_C18A/image_thumb.png" width="644" height="263" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In addition, we've fixed the highest-voted bugs in components across the Toolkit including Charting,&amp;#160; AutoCompleteBox, and TreeView.&amp;#160; Thanks to everyone that took the time to file issues or vote, that data is very helpful to us.&amp;#160; One catch here is that some of our components (like TreeView) need to maintain API compat with WPF, so that limits the type of changes that we can make.&lt;/p&gt;  &lt;p&gt;We also now have an MSI-based installer package that installs the Toolkit for you and gets the Toolkit control items into the Visual Studio Toolbox or Blend Asset Panel automatically.&amp;#160; This helps with the discovery of components and makes them easier to add to your projects.&amp;#160; It also sets up a nice Start Menu entry as well:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/SilverlightToolkitMarch2009Release_C18A/image_6.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/SilverlightToolkitMarch2009Release_C18A/image_thumb_2.png" width="404" height="222" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h4&gt;5. Add new controls&lt;/h4&gt;  &lt;p&gt;We've also added some new controls - Accordion, DomainUpDown, and TimePicker, all of which are in the Preview band for this release.&amp;#160; Check them out!&lt;/p&gt;  &lt;h3&gt;Toolkit Namespace and Assembly Changes&lt;/h3&gt;  &lt;p&gt;If you're upgrading from a prior version of the Toolkit, you'll notice that the namespace names for most components have changed from Microsoft.* to System.*.&amp;#160; So for this upgrade, you'll need to go through the process of updating your code, so sorry for that up front.&lt;/p&gt;  &lt;p&gt;This was something we spent a *lot* of time talking through.&amp;#160; The original reason for making the Toolkit components be in Microsoft was so that we could add components to the SDK or the Core and not have them conflict with Toolkit versions.&amp;#160; We wanted there to be an opt-in change when developers moved from a Toolkit control to the platform version - we'd delay the need for the user to make a change until the very end.&amp;#160; But the user would need to update source code.&amp;#160; The more we thought about this, and talked to customers, the more it seemed like this wasn't the right thing to do since it means more-and-more code that you'll need to fix up if you wait longer.&amp;#160; Instead, for the components we expected to make it into the platform, it was better to put them into their final namespace and then physically move them into the platform assembly when they were fully mature.&amp;#160; This meant having a new Toolkit build with each platform release that has those types removed.&amp;#160; But that's something we do anyway, and doing it this way means that customers only need to update their references and maybe their XAML xml namespace, and that's it.&amp;#160; Code should continue to run.&amp;#160; We decided that was a better model.&lt;/p&gt;  &lt;p&gt;In conjunction with that, we needed to make sure that installing or using the Toolkit was something that didn't disturb the supported platform release.&amp;#160; So that meant Toolkit assemblies had to be able to sit side-by-side with SDK assemblies.&amp;#160; To accomplish that, we appended the word &amp;quot;Toolkit&amp;quot; to the Toolkit assemblies and that makes an easy mapping for where things are in the Toolkit to where they will end up in the SDK.&lt;/p&gt;  &lt;p&gt;Here is an example:&lt;/p&gt;  &lt;p&gt;Today, &lt;strong&gt;System.Windows.Controls.Accordion&lt;/strong&gt; is in &lt;strong&gt;System.Windows.Controls.Layout.&lt;em&gt;Toolkit&lt;/em&gt;.dll.&lt;/strong&gt;&amp;#160; Someday in the future, Accordion will reach the Mature Quality Band and then a platform release will happen and it will be moved into the SDK.&amp;#160; When the next version of Silverlight ships, we will ship a corresponding Toolkit and SDK.&amp;#160; The Accordion component will move into &lt;strong&gt;System.Windows.Controls.Layout.DLL (&lt;/strong&gt;note no &amp;quot;Toolkit&amp;quot; in there), which is part of the SDK itself&lt;strong&gt;.&amp;#160; &lt;/strong&gt;Developers using this component will need to add a reference to that SDK assembly and (optionally) remove the reference to System.Windows.Controls.Layout.Toolkit.dll if it's not needed anymore.&amp;#160; The developer would also need to update their XML namespace definition to point to the SDK version of the DLL so that the XAML parser knows where to find it.&amp;#160; That should be it, and the project will now be using the SDK version of the component with no code changes.&lt;/p&gt;  &lt;p&gt;What this unfortunately means is that we've got quite a few assemblies coming out of the Toolkit.&amp;#160; We've tried to intelligently bucket the Toolkit controls into a few different assemblies so you don't have to pay to have a bunch of components in your XAP you're not using.&amp;#160; We'll do the same thing for the SDK.&amp;#160; But given the above, you get 2 assemblies for each bucket.&amp;#160; Unfortunately, that's the simplest solution even if it's a little verbose.&lt;/p&gt;  &lt;h3&gt;Rebuilding SDK Components&lt;/h3&gt;  &lt;p&gt;As I mentioned above, the full source for the SDK components is now present in the Toolkit project.&amp;#160; The Toolkit only includes source for these components, not the components themselves.&amp;#160; Many parts of the system (for example Blend) are tested and built against the released version of the SDK components.&amp;#160; We don't want the Toolkit updating these by default, but we do want to allow developers to make fixes to these components and deploy them with their applications if needed.&amp;#160; In the Toolkit you'll find a Toolkit solution and an SDK solution so there is a nice separation there.&amp;#160; If you do make a change to one of these components, you can just update the reference in your project to your rebuilt version and run against that.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/SilverlightToolkitMarch2009Release_C18A/image_12.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/SilverlightToolkitMarch2009Release_C18A/image_thumb_5.png" width="644" height="91" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;Other Improvements&lt;/h3&gt;  &lt;p&gt;The Toolkit also includes two great new themes: Bubble Cream and Twilight Blue.&lt;/p&gt;  &lt;p&gt;We've added AreaSeries in the Charts&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/SilverlightToolkitMarch2009Release_C18A/image_8.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/sburke/WindowsLiveWriter/SilverlightToolkitMarch2009Release_C18A/image_thumb_3.png" width="404" height="284" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Looking forward to hearing your feedback!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9493583" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/sburke/archive/tags/Silverlight+Toolkit/">Silverlight Toolkit</category></item></channel></rss>