 <?xml-stylesheet type="text/css" href="http://www.jaykimble.net/Data/style/rss1.css" ?> <?xml-stylesheet type="text/xsl" href="http://www.jaykimble.net/Data/style/rss1.xsl" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
  <channel>
    <title>Windows Dev Posts By a Dev Theologian</title>
    <link>http://www.jaykimble.net/silverlight-blog.aspx</link>
    <description />
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>mojoPortal Blog Module</generator>
    <language>en-US</language>
    <ttl>120</ttl>
    <atom:link href="http://www.jaykimble.net/Blog/RSS.aspx?pageid=2&amp;mid=2" rel="self" type="application/rss+xml" />
    <itunes:owner />
    <itunes:explicit>no</itunes:explicit>
    <item>
      <title>Nokia Create – Submission Tips</title>
      <description><![CDATA[<p>I just wanted to fire off a quick post on entering the Nokia Create contest as there are a few things that can get you. </p> <p>First of all, you will need to do a video of your app. It must be less than 2 minutes long. If you are doing the NFC Mission (which I did), you’ll need to demo outside of the emulator (since the emulator doesn’t support testing NFC). We filmed my app’s demo at a recent community event (where someone else had a Lumia 1020). My video was (of course) slightly too long, so I had to edit it. I bought <a href="http://apps.microsoft.com/webpdp/app/cb587b4e-ba68-4c67-8eee-b22f46f87000">Magix Movie Edit Touch</a> for Win8 which worked great for me; it allowed me to remove some extraneous video and apply transitions making things seem smoother. There are some limitations on what video formats are supported (so pay attention.. .MP4 is what I used).</p> <p>Assuming that your app is already in the store, you will need to fill out the submission form. When it comes to uploading the video, upload the file to skydrive, and get a read-only link to the file (don’t waste your time trying to upload video, as it must have a size limitation of some sort as I tried this 3 times and failed). I tried to do this with DropBox first, but for some reason it told me that the file format was wrong.. Other cloud-based file sharing services may work, but I know that SkyDrive works.</p><br /><a href='http://www.jaykimble.net/nokia-create-–-submission-tips.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/nokia-create-–-submission-tips.aspx</link>
      <author>jkimble@intradynamics.net (Jay Kimble)</author>
      <comments>http://www.jaykimble.net/nokia-create-–-submission-tips.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/nokia-create-–-submission-tips.aspx</guid>
      <pubDate>Wed, 23 Oct 2013 13:18:29 GMT</pubDate>
    </item>
    <item>
      <title>Socket Communicator Intro</title>
      <description><![CDATA[<p>With my Proximity Helper (<a href="http://bit.ly/H3oX8M">intro post here</a>) I quickly discovered that socket communications are a little more involved. After searching around I found a couple extensions methods in the “<a href="http://code.msdn.microsoft.com/Proximity-APIs-in-Windows-6be362cc">big complicated wp proximity sample on MSDN</a>” (the code I have criticized as being way too complex for a sample app). </p> <h1>Background</h1> <p>The reason why sockets are a little more complex is because when you are reading from the socket’s stream, you need to tell it how many bytes you want to ready. The easy answer around this is that when you are writing to the stream you pass the size of the data you are writing to the stream first, so when you are reading data, you first read how big the next set of data is. I say data here, because you could be reading a byte array or a long or a double or a date, etc. This also means that as you are reading things need to stay in the proper order (you have to read things in the same manner they are written… so if I write a byte, long, and a byte array, then I need to read those things back in the same order from the other phone).</p> <p>Anyway, the methods I grabbed have to do with writing a uint, reading a uint, writing a int, reading a int, writing a string, and reading a string. Length of a string is stored as a uint.. so my intention for my apps is to write a JSON or XML string to the socket stream and reading a string (on the other side). This makes things fairly easy to send structured information back and forth. To make things easier for me, I put everything into 2 methods (one for reading and one for writing).</p> <h1>Setup</h1> <p>Setup is easy. If you are using my ProximityHelper and set it up <a href="http://bit.ly/H3oX8M">using the intro post</a>, then you are done already (you already copied the necessary class). If not then head to the <a href="http://bit.ly/GZuHzG">ProximityToy’s respository</a>, and get the latest code (or navigate to the “<a href="http://bit.ly/1752bcs">ProximityToy\Helpers</a>” folder online). The file you need to add to your project is the “ProximityToy\Helpers\SocketCommunicator.cs.” Once you’ve done that you are ready to go.</p> <h1>Code.. Show Me the Code</h1> <p>First of all you will need to instantiate a SocketCommunicator, and it’s easy to do that. Simply do this:</p> <div class="csharpcode"><pre class="alt"><span class="rem">// If you are using the ProximityHelper you could replace the "socket" argument</span></pre><pre><span class="rem">/// with "ProximityHelper.Default.Socket"</span></pre><pre class="alt">var socketCommunicator = <span class="kwrd">new</span> SocketCommunicator(socket);</pre></div>
<style type="text/css">.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; }
</style>

<p>You are now ready to communicate. BTW, SocketCommunicator implements <em>IDisposable</em> so when you are done with it you will want to call “<em>socketCommunicator.Dispose</em>” or use it in a using like this (this is great for quick data exchanges):</p>
<div class="csharpcode"><pre class="alt"><span class="kwrd">using</span>(var socketCommunicator = <span class="kwrd">new</span> SocketCommunicator(socket)) {</pre><pre>&nbsp;</pre><pre class="alt">     <span class="rem">// Communication code goes here</span></pre><pre>&nbsp;</pre><pre class="alt">} <span class="rem">// Dispose is called when execution reaches here</span></pre></div>
<p>Let’s see how we would send a uint and a string:</p>
<div class="csharpcode"><pre class="alt"><span class="kwrd">int</span> someInt = -1;</pre><pre>UInt32 myUInt = 100; </pre><pre class="alt">&nbsp;</pre><pre><span class="rem">// Single API call for all the supported types </span></pre><pre class="alt"><span class="rem">//(only Int32, UInt32, and String are currently supported)</span></pre><pre><span class="rem">// send Int32</span></pre><pre class="alt">await socketCommunicator.SendAsync(someInt);</pre><pre><span class="rem">// Send UInt32</span></pre><pre class="alt">await socketCommunicator.SendAsync(myUInt);</pre><pre><span class="rem">// Send String</span></pre><pre class="alt">await socketCommunicator.SendAsync(<span class="str">"Some text value"</span>);</pre><pre><span class="rem">// Send a json string</span></pre><pre class="alt">await socketCommunicator.SendAsync(<span class="str">"{'id':1, 'name':'Dev Theologian', 'isValid':<span class="kwrd">true</span> }"</span>);</pre></div>
<p>By sending json, you can see how we could basically get every type of covered, and even send complex types.</p>
<p>Now we need to see how to read all this stuff back in:</p>
<div class="csharpcode"><pre class="alt">var someInt = await socketCommunicator.ReceiveAsync&lt;Int32&gt;();</pre><pre>var myInt = await socketCommunicator.ReceiveAsync&lt;UInt32&gt;();</pre><pre class="alt">var myMessage = await socketCommunicator.ReceiveAsync&lt;String&gt;();</pre><pre>var jsonString = await socketCommunicator.ReceiveAsync&lt;String&gt;();</pre><pre class="alt"><span class="rem">// Next steps would be to either deserialize the json or parse and read the values</span></pre></div>
<p>Remember after you are done communicating to make sure that you call Dispose on your instance of the SocketCommunicator class.</p>
<p>I also expose the DataReader and DataWriter instances that are ultimately being used, so if you want to do something outside of what my utility exposes, you can of course interact with these objects.</p>
<p>Finally, just as a reminder, you can get the single class you need right here: <a href="http://bit.ly/1752bcs">SocketCommunicator.cs</a>.</p><br /><a href='http://www.jaykimble.net/socket-communicator-intro.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/socket-communicator-intro.aspx</link>
      <author>jkimble@intradynamics.net (Jay Kimble)</author>
      <comments>http://www.jaykimble.net/socket-communicator-intro.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/socket-communicator-intro.aspx</guid>
      <pubDate>Thu, 17 Oct 2013 17:42:32 GMT</pubDate>
    </item>
    <item>
      <title>WP8 Proximity Simplified</title>
      <description><![CDATA[<p>This blog post will cover the setup of my ProximityHelper class in your apps and help you implement the various scenarios for making proximity connections. You may want to read my introductory <a href="http://bit.ly/GYn64U">post on proximity and WP8</a> (which also includes my reasons for creating this “mini” library).</p> <p>My class makes it easy to set up peer-to-peer (bi-directional) socket connections without having to implement the glue necessary to get the connection off the ground. It handles both the scenarios where you want a tap connection and the ones where you need to browse for a connection.</p> <h1>Setup</h1> <p>Setup is fairly easy. Go to the <a href="http://bit.ly/GZuHzG">respository for Proximity Toy</a> and grab the latest files. You need to copy the ProximityResources.* files from under the “ProximityToy\Resources” folder. Additionally copy the “ProximityToy\Helpers” folder&nbsp; (and subfolders) to your the project (this will get the ProximityHelper class AND the SocketHelper class which will be covered in another blog post; it will also get the UI components that we use to connect to a client during a “polling for clients” scenario). Finally you need the “Coding4Fun.Toolkit.Controls” library from Nuget (we use this to display dialogs in your app). </p> <h1>Implementing Scenarios</h1> <p>If you look at Proximity Toy you see that I have 3 different scenarios. These are roughly the scenarios we need to implement. Proximity Toy uses the words “client” and “server” which is the not best choice of words I have for what is happening. A “server” either polls or initiates the “tap.” The “client” responds to a connection request (initiated by one of these methods). These are not the best uses of the words as once the “conversation” is initiated then the both sides can send and receive asynchronously to the other side. [Maybe “initiator”/”responder” is a better set of names].</p> <h2>Connect (Client) scenario</h2> <p>The “Connect (Client)” sets up a situation where one phone is really listening for a connection and will respond to the connection (client responds to a connect requests). Proximity Helper will actually prompt the user to make sure it’s OK to connect to the other phone (it also identifies the “DisplayName” which is provided to ProximityHelper by “server” phone). You initiate this scenario in code like this:</p> <div class="csharpcode"><pre class="alt"><span class="rem">// In your code make "Client Polling" something meaningful to the other user (like a user name for instance)</span></pre><pre>ProximityHelper.Default.DisplayName = <span class="str">"Client Polling"</span>; </pre><pre class="alt">&nbsp;</pre><pre><span class="rem">// false below indicates that this is not a server (so monitor for connections)</span></pre><pre class="alt">var result = await ProximityHelper.Default.GetConnectionAndSocket(<span class="kwrd">false</span>);</pre><pre>&nbsp;</pre><pre>if(result) {</pre><pre class="alt"><span class="rem">// ******************************************************</span></pre><pre><span class="rem">// Do your communication here using ProximityHelper.Default.Socket</span></pre><pre class="alt"><span class="rem">// ******************************************************</span></pre><pre>}</pre><pre>&nbsp;</pre><pre class="alt"><span class="rem">// At some point when you are done with the connection, do this to close it</span></pre><pre><span class="rem">// NOTE: this might not be in the same routine, just make sure you close the connection before you exit</span></pre><pre class="alt">ProximityHelper.Default.CloseConnection(<span class="kwrd">true</span>);</pre></div>
<style type="text/css">.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; }
</style>

<h2><br>Connect By Tap scenario</h2>
<p>The “Connect By Tap” sets up an NFC initiated (2 phones tapping) connection. In the conversation, the phone using this setting is the “server.” You call code that looks like this (it’s very similar to the last example):</p>
<div class="csharpcode"><pre class="alt"><span class="rem">// Again, make "Server Non-Polling" something meaningful to the other user (like a user name)</span></pre><pre>ProximityHelper.Default.DisplayName = <span class="str">"Server Non-Polling"</span>;</pre><pre class="alt">&nbsp;</pre><pre><span class="rem">// The first parameter (true) in the signature below puts the system in "server" mode where NFC is on, and</span></pre><pre class="alt"><span class="rem">// we are awaiting some event that makes this phone aware of a client</span></pre><pre><span class="rem">// The second parameter (false) tells the Helper that we don't want to poll for clients. If this phone doesn't</span></pre><pre class="alt"><span class="rem">// support NFC then this setting will be automatically toggled to true to poll</span></pre><pre><span class="rem">// (Remember our goal here is to dumb down the mechanism and make it easy to create a connection)</span></pre><pre class="alt">var result = await ProximityHelper.Default.GetConnectionAndSocket(<span class="kwrd">true</span>, <span class="kwrd">false</span>);</pre><pre>&nbsp;</pre><pre>if (result) </pre><pre>{</pre><pre class="alt"><span class="rem">// ******************************************************</span></pre><pre><span class="rem">// Do your communication here using ProximityHelper.Default.Socket</span></pre><pre class="alt"><span class="rem">// ******************************************************</span></pre><pre>}</pre><pre>&nbsp;</pre><pre class="alt"><span class="rem">// After you are done communicating, close the connection (and the communication) down.</span></pre><pre><span class="rem">// NOTE: this might not happen in this routine</span></pre><pre class="alt">ProximityHelper.Default.CloseConnection(<span class="kwrd">true</span>);</pre></div>
<p>&nbsp;<br>Don’t forget that if the phone doesn’t have NFC and you put it into non-polling server mode, we will still poll because non-polling server mode doesn’t make sense on a phone without NFC.</p>
<h2>Connect (Polling Server) scenario</h2>
<p> The “Connect (Polling Server)” does everything that the last one does except that it also sets up to poll for “clients” to connect to when it finds one (or more) it will prompt (via a dialog using the ConnectPrompt user control in “Helpers\UI”) the user for a “client” to try a connection with. Once a “client” has been selected the “client” phone will prompt if it’s ok to connect, and if it is then a socket is retrieved. The code to do this looks like this (if you’ve been paying attention it should be easy to guess what it looks like):</p>
<div class="csharpcode"><pre class="alt"><span class="rem">// Again, make "Server Polling" something meaningful to the other user (like a user name)</span></pre><pre>ProximityHelper.Default.DisplayName = <span class="str">"Server Polling"</span>;</pre><pre class="alt">&nbsp;</pre><pre><span class="rem">// The first parameter (true) in the signature below puts the system in "server" mode where NFC is on, and</span></pre><pre class="alt"><span class="rem">// we are awaiting some event that makes this phone aware of a client</span></pre><pre><span class="rem">// The second parameter (true) tells the Helper that we want to poll for clients. </span></pre><pre class="alt"><span class="rem">//</span></pre><pre><span class="rem">// BTW, in most cases this is what you will want to do for the server</span></pre><pre class="alt">var result = await ProximityHelper.Default.GetConnectionAndSocket(<span class="kwrd">true</span>, <span class="kwrd">true</span>);</pre><pre>&nbsp;</pre><pre class="alt"><span class="kwrd">if</span>(result) </pre><pre>{</pre><pre class="alt">    <span class="rem">// ******************************************************</span></pre><pre>    <span class="rem">// Do your communication here using ProximityHelper.Default.Socket</span></pre><pre class="alt">   <span class="rem">// ******************************************************</span></pre><pre>}</pre><pre class="alt">&nbsp;</pre><pre><span class="rem">// After you are done communicating, close the connection (and the communication) down.</span></pre><pre class="alt"><span class="rem">// NOTE: this might not happen in this routine</span></pre><pre>ProximityHelper.Default.CloseConnection(<span class="kwrd">true</span>); // Note: <span class="kwrd">true</span> clears the list containing available clients</pre></div>
<p>&nbsp;</p>
<h2>Client Tap scenario</h2>
<p> There is also a fourth scenario that is hidden from the UI where we handle an NFC Tap for connection. In this last situation what happens is that the app on one phone is set in one of the “server” modes, and the other phone is not running the app; when the phones are tapped the phone not running the app will prompt the user to open the app or ignore; when they open the app, it launches with a querystring to your main page. We won’t go into the deep details on this, but ProximityHelper can respond to this type of situation and will automatically set up the connection for you. In most cases you want to respond to a tap and instantly get a connection. Here’s the code for that:</p>
<div class="csharpcode"><pre class="alt"><span class="kwrd">private</span> async <span class="kwrd">void</span> handleTap(NavigationEventArgs e)</pre><pre>{</pre><pre class="alt">    <span class="rem">// We still set the DisplayName </span></pre><pre>    <span class="rem">// (by now you should know that you want this to be something that is meaningful)</span></pre><pre class="alt">    ProximityHelper.Default.DisplayName = <span class="str">"Client Tap"</span>;</pre><pre>&nbsp;</pre><pre class="alt">    <span class="rem">// We pass this routine the NavigationEventArgs as well as a bool value.</span></pre><pre>    <span class="rem">// A false for the the bool value indicates we want to just detect that we got the</span></pre><pre class="alt">    <span class="rem">// tap QueryString.</span></pre><pre>    <span class="rem">// A true here indicates that if there was a tap Querystring to go ahead and set up</span></pre><pre class="alt">    <span class="rem">// a connection            </span></pre><pre>    <span class="rem">// True is your most likely value</span></pre><pre class="alt">    var wasTapConnection = await ProximityHelper.Default.DetectTap(e, <span class="kwrd">true</span>);</pre><pre>&nbsp;</pre><pre class="alt">    <span class="kwrd">if</span>(wasTapConnection)</pre><pre>    {</pre><pre class="alt">        <span class="rem">// ***************************************************************</span></pre><pre>        <span class="rem">// Do your communication here using ProximityHelper.Default.Socket</span></pre><pre class="alt">        <span class="rem">// ***************************************************************</span></pre><pre>    </pre><pre class="alt">        <span class="rem">// At some point when you are done communicating, do this to close down the connection</span></pre><pre>        ProximityHelper.Default.CloseConnection(<span class="kwrd">true</span>); <span class="rem">// true indicates clearing list of </span></pre><pre class="alt">                                                                                                                     <span class="rem">// available clients</span></pre><pre>    }</pre><pre class="alt">}</pre><pre>&nbsp;</pre></div>
<h1>Customization Opportunities</h1>
<p>I did want to mention again that if you don’t like my Prompt for client classes you can make changes by editing the xaml of the “Proximity\Helpers\ProximityUI\ConnectPrompt.xaml” file. The big thing to remember is that we are using a little bit of XAML binding (nothing too tricky). Basically we bind the ClientList to the ItemSource of the peerList control (it’s a listbox in our example, but it could be a different type of control entirely if you like); This the ClientList collection includes an IsSelected value that we use to set visibility (using a Converter), so you can use the same thing. Text blocks in the individual rows are bound to the DisplayName property.</p>
<p>Additionally all the static text is stored in the “ProximityTool\Resources\ProximityResources.resx” file. It is also localizable as a result.</p>
<h1>Final thoughts</h1> You now have a library that will make things simple for making Proximity style connections. You are ready for my SocketHelper discussion (look for it later today or early tomorrow). [If you are impatient you can dig into the getData and sendData methods in the codebehind of the MainPage.xaml file to see how this works]. Again the sample project (and helper files) can be found at the <a href="http://bit.ly/GZuHzG">Proximity Toy’s Repository</a>.<br /><a href='http://www.jaykimble.net/wp8-proximity-simplified.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/wp8-proximity-simplified.aspx</link>
      <author>jkimble@intradynamics.net (Jay Kimble)</author>
      <comments>http://www.jaykimble.net/wp8-proximity-simplified.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/wp8-proximity-simplified.aspx</guid>
      <pubDate>Thu, 17 Oct 2013 15:13:23 GMT</pubDate>
    </item>
    <item>
      <title>Proximity and WP8 - Introduction</title>
      <description><![CDATA[<p>About 3 weeks ago, I decided to add what I called “NFC” to my WP8 Friend GPS App (currently called “Where U @?”, but with the next release will be called “Friend Pilot”). This started a journey for me where I had to wrap my head around the whole Proximity library. What I found was that the topic is somewhat confusing. It is not helped by the samples that are out there from Microsoft. I mean there are good examples, BUT those examples assume the type of interaction you are looking to create use BOTH MVVM and IAsync handlers (the former I can follow, the latter hurts my brain, and for the person just learning the mountain is pretty high just to learn how to use the Proximity library). [The one talk I found on the topic using the aforementioned complex/advanced code didn’t help with the reference to “magic happens” (which in his case meant that you tap and things just automatically happen for you.. this is untrue.. you have to call things to make “magic happen”, so therefore it’s not magical to the developer)].</p> <p>In this post I want to give some background behind Proximity so you can understand what is going on. I will follow this up with a post on using my ProximityHelper class, and then will come back and give a few more specifics on Proximity. Essentially I feel the topic has been covered, but doesn’t really lend itself to the beginner or even intermediate developer. I believe that much of the discussions here will also be helpful for Windows Store (C#/VB) development as my perusal of the WinRT framework shows the same Proximity classes.</p> <h2>My Goal</h2> <p>For me I wanted a simple interaction, while running my app on 2 phones (that have NFC), tap them together and exchange information. Additionally I wanted to have some way for a device without NFC to be able to connect and make an exchange of info as well (but I wasn’t sure this was possible originally). I suspect that this is what most people want to do.</p> <h2>Background</h2> <p>First of all, Microsoft’s ProximityFinder class (the heart of the ProximityLibrary) actually combines a number of technologies together into a single API (NFC --if available, Bluetooth, and regular 802.11x Wi-Fi). You don’t need to be a guru with any of these technologies. It just works (when you get everything set up and you don’t need to worry about the underlying technology being used). BTW, you do use this class in different ways to get a connection based on what you are trying to do (like if you are making your phone available for a connection or if you are actively looking for a connection).</p> <p>Second, you need to understand that NFC is really just there to set up a connection on one of the other technologies. NFC is the “tapping” part of the exchange, but after that everything happens over either Bluetooth or 802.11x Wi-Fi. </p> <p>Thirdly, once you make a connection you are given a socket (specifically a “StreamSocket”). At this point you have to implement your own protocol of sorts (which if that sounds hard.. it can be.. As a result of this I created a SocketHelper class that really grabs some of the code from one of the Microsoft Samples).</p> <p>Finally, one of the side benefits I found out was that once you get things set up that once you set one phone up to connect, NFC can be used to both launch your app on the other phone AND create the connection. (This is very cool!)</p> <h2>More on NFC</h2> <p>Some of you may be wondering about NFC at this point. You may have looked at a sample and it looks like you could communicate between two devices, etc. The reality is that you can communicate with NFC this way, but the devices have to remain very close. Ultimately, I think NFC is best used for short messages between 2 devices where 1 way communication is all that you need. I am admittedly still just figuring out NFC, and there are topics like writing to an NFC tag, that I have yet to really press down on. I am planning an NFC helper as well..</p> <h2>Sample App</h2> <p>I wrote an app as a sample app to test all this out. It’s called Proximity Helper and (if it passes certification) should be in the Windows Phone Store today. It let’s you test out various scenarios with my library. It does talk about having a “client” and a “server” phone, but this isn’t entirely accurate. In my app’s case communication is done in a one way fashion. In reality Proximity allows for 2 way communication. If you want to look to see what all I am doing you can, of course, go look at the source for my <a href="http://bit.ly/GZuHzG">sample at it’s repository</a>.</p> <h2>Final Thoughts</h2> <p>This should lay a decent ground work for you to understand Proximity. I will be following this up with a couple more posts. One on how to use my ProximityHelper in your projects to start the communication between 2 apps; one on my SocketHelper and ways you can use it to create a simple protocol for communicating between 2 apps (hint: I’ll be using JSON strings); and finally a post on the technicals of Proximity.. how it works, etc.</p><br /><a href='http://www.jaykimble.net/proximity-and-wp8-introduction.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/proximity-and-wp8-introduction.aspx</link>
      <author>jkimble@intradynamics.net (Jay Kimble)</author>
      <comments>http://www.jaykimble.net/proximity-and-wp8-introduction.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/proximity-and-wp8-introduction.aspx</guid>
      <pubDate>Wed, 16 Oct 2013 18:12:42 GMT</pubDate>
    </item>
    <item>
      <title>WP8 App/Page Base Navigation Classes</title>
      <description><![CDATA[<p>On my utilities page, I need to document a few of the items. The next one up is my App/Page Base Classes which you can get <a href="http://bit.ly/1emxCOF">here at it’s repository</a>.</p> <h2>Background</h2> <p>I created this set of classes in response to a DVLUP challenge criteria (Fast App Switching). The main reason I created these was because I wanted to be able to easily handle the various types of navigation to my pages with minimal thinking on my part. With Fast App Switching, you detect that via the Application_Activated event in the application (it gets passed to you via an event argument object). For me the best solution was to indicate this via a property on the application, and then I needed to remember to clear that property once I had responded to it. This last part was what spawned the new mechanism. Essentially, I split the page’s OnNavigatedTo method into 3 separate methods (that need to be overridden in child pages). The 3 <u>methods</u> are:</p> <ul> <li><em>OnNormalNavigatedTo</em> – a normal page-to-page navigation (or app launch) where you need to do an initial load of data  <li><em>OnResumedFromTombstone</em> – indicates that the page is being launched after a tombstoning situation (where you need to reload the page’s state  <li><em>OnFastSwitchedTo</em> – indicates that the page is being launched after returning from the OS, but nothing needs to be reloaded</li></ul> <p>All of these methods are passed a single argument of type: <em>NavigationEventArgs</em> which is the normal argument passed to the <em>OnNavigatedTo</em> Event. You can of course override the <em>OnNavigatedTo</em> event (and remember to call <em>base.OnNavigatedTo(e)</em> so that the new overrides get called.</p> <h2>Installation</h2> <p>There is a bit of work to wire all this up. First of all you need to grab the 2 new class files and drop them into your project. Next go ahead and compile the project (BTW, these classes MAY also work in WP7 projects). Now you need to wire up the application class. You need to do 2 things.</p> <p>Set the App.xaml.cs class to inherit from <em>DTNet.StateAwareApplication</em> instead of <em>Application. </em>That will look something like this:</p> <div class="csharpcode"><pre class="alt"><span class="kwrd">namespace</span> MyProject</pre><pre>{</pre><pre class="alt">    <span class="kwrd">public</span> <span class="kwrd">partial</span> <span class="kwrd">class</span> App : DTNet.StateAwareApplication</pre><pre>    {</pre></div>
<style type="text/css">.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; }
</style>

<style type="text/css">.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; }
</style>

<p><br>Additionally, you need to change the Application_Activated override method a little. It should look like this</p>
<div class="csharpcode"><pre class="alt">        <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Application_Activated(<span class="kwrd">object</span> sender, ActivatedEventArgs e)</pre><pre>        {</pre><pre class="alt">            <span class="kwrd">base</span>.Application_Activated(sender, e);</pre><pre>            <span class="rem">// Add any additional code you need in this event here</span></pre><pre class="alt">        }</pre></div>
<style type="text/css">.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; }
</style>

<p><br>Next you need to modify the app.xaml file by changing the base class. You probably have something that looks like this:</p>
<div class="csharpcode"><pre class="alt"><span class="kwrd">&lt;</span><span class="html">Application</span></pre><pre>    <span class="attr">x:Class</span><span class="kwrd">="ProximityToy.App"</span></pre><pre class="alt">    <span class="attr">xmlns</span><span class="kwrd">="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span></pre><pre>    <span class="attr">xmlns:x</span><span class="kwrd">="http://schemas.microsoft.com/winfx/2006/xaml"</span></pre><pre class="alt">    <span class="attr">xmlns:phone</span><span class="kwrd">="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"</span></pre><pre>    <span class="attr">xmlns:shell</span><span class="kwrd">="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"</span><span class="kwrd">&gt;</span></pre><pre class="alt">&nbsp;</pre><pre>    <span class="rem">&lt;!--Application Resources--&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;</span><span class="html">Application.Resources</span><span class="kwrd">&gt;</span></pre><pre>        <span class="kwrd">&lt;</span><span class="html">local:LocalizedStrings</span> <span class="attr">xmlns:local</span><span class="kwrd">="clr-namespace:ProximityToy"</span> <span class="attr">x:Key</span><span class="kwrd">="LocalizedStrings"</span><span class="kwrd">/&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;/</span><span class="html">Application.Resources</span><span class="kwrd">&gt;</span></pre><pre>&nbsp;</pre><pre class="alt">    <span class="kwrd">&lt;</span><span class="html">Application.ApplicationLifetimeObjects</span><span class="kwrd">&gt;</span></pre><pre>        <span class="rem">&lt;!--Required object that handles lifetime events for the application--&gt;</span></pre><pre class="alt">        <span class="kwrd">&lt;</span><span class="html">shell:PhoneApplicationService</span></pre><pre>            <span class="attr">Launching</span><span class="kwrd">="Application_Launching"</span> <span class="attr">Closing</span><span class="kwrd">="Application_Closing"</span></pre><pre class="alt">            <span class="attr">Activated</span><span class="kwrd">="Application_Activated"</span> <span class="attr">Deactivated</span><span class="kwrd">="Application_Deactivated"</span><span class="kwrd">/&gt;</span></pre><pre>    <span class="kwrd">&lt;/</span><span class="html">Application.ApplicationLifetimeObjects</span><span class="kwrd">&gt;</span></pre><pre class="alt">&nbsp;</pre><pre><span class="kwrd">&lt;/</span><span class="html">Application</span><span class="kwrd">&gt;</span></pre></div>
<style type="text/css">.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; }
</style>

<p>&nbsp;</p>
<p>You will need to add the DTNet namespace and change the “&lt;Application” (or “&lt;/Application”)&nbsp; to “&lt;dtnet:StateAwareApplication “ (or “&lt;/dtnet:StateAwareApplication”). To convert the above xaml it would look like this:</p>
<div class="csharpcode"><pre class="alt"><span class="kwrd">&lt;</span><span class="html">dtnet:StateAwareApplication</span> </pre><pre>    <span class="attr">x:Class</span><span class="kwrd">="ProximityToy.App"</span></pre><pre class="alt">    <span class="attr">xmlns</span><span class="kwrd">="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span></pre><pre>    <span class="attr">xmlns:x</span><span class="kwrd">="http://schemas.microsoft.com/winfx/2006/xaml"</span></pre><pre class="alt">    <span class="attr">xmlns:phone</span><span class="kwrd">="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"</span></pre><pre>    <span class="attr">xmlns:shell</span><span class="kwrd">="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"</span></pre><pre class="alt">    <span class="attr">xmlns:dtnet</span><span class="kwrd">="clr-namespace:DTNet"</span><span class="kwrd">&gt;</span></pre><pre>&nbsp;</pre><pre class="alt">    <span class="rem">&lt;!--Application Resources--&gt;</span></pre><pre>    <span class="kwrd">&lt;</span><span class="html">dtnet:StateAwareApplication.Resources</span><span class="kwrd">&gt;</span></pre><pre class="alt">        <span class="kwrd">&lt;</span><span class="html">local:LocalizedStrings</span> <span class="attr">xmlns:local</span><span class="kwrd">="clr-namespace:ProximityToy"</span> <span class="attr">x:Key</span><span class="kwrd">="LocalizedStrings"</span><span class="kwrd">/&gt;</span></pre><pre>    <span class="kwrd">&lt;/</span><span class="html">dtnet:StateAwareApplication.Resources</span><span class="kwrd">&gt;</span></pre><pre class="alt">&nbsp;</pre><pre>    <span class="kwrd">&lt;</span><span class="html">dtnet:StateAwareApplication.ApplicationLifetimeObjects</span><span class="kwrd">&gt;</span></pre><pre class="alt">        <span class="rem">&lt;!--Required object that handles lifetime events for the application--&gt;</span></pre><pre>        <span class="kwrd">&lt;</span><span class="html">shell:PhoneApplicationService</span></pre><pre class="alt">            <span class="attr">Launching</span><span class="kwrd">="Application_Launching"</span> <span class="attr">Closing</span><span class="kwrd">="Application_Closing"</span></pre><pre>            <span class="attr">Activated</span><span class="kwrd">="Application_Activated"</span> <span class="attr">Deactivated</span><span class="kwrd">="Application_Deactivated"</span><span class="kwrd">/&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;/</span><span class="html">dtnet:StateAwareApplication.ApplicationLifetimeObjects</span><span class="kwrd">&gt;</span></pre><pre>&nbsp;</pre><pre class="alt"><span class="kwrd">&lt;/</span><span class="html">dtnet:StateAwareApplication</span><span class="kwrd">&gt;</span></pre></div>
<style type="text/css">.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; }
</style>

<p>See how event the resources change. This is all that needs to be done to the application file.<br><br>You need to make similar changes for <strong><em>every page</em></strong>. Here’s a sample Xaml page that (with nothing in it):</p>
<div class="csharpcode"><pre class="alt"><span class="kwrd">&lt;</span><span class="html">phone:PhoneApplicationPage</span></pre><pre>    <span class="attr">x:Class</span><span class="kwrd">="ProximityToy.MainPage"</span></pre><pre class="alt">    <span class="attr">xmlns</span><span class="kwrd">="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span></pre><pre>    <span class="attr">xmlns:x</span><span class="kwrd">="http://schemas.microsoft.com/winfx/2006/xaml"</span></pre><pre class="alt">    <span class="attr">xmlns:phone</span><span class="kwrd">="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"</span></pre><pre>    <span class="attr">xmlns:shell</span><span class="kwrd">="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"</span></pre><pre class="alt">    <span class="attr">xmlns:d</span><span class="kwrd">="http://schemas.microsoft.com/expression/blend/2008"</span></pre><pre>    <span class="attr">xmlns:mc</span><span class="kwrd">="http://schemas.openxmlformats.org/markup-compatibility/2006"</span></pre><pre class="alt">    <span class="attr">mc:Ignorable</span><span class="kwrd">="d"</span></pre><pre>    <span class="attr">FontFamily</span><span class="kwrd">="{StaticResource PhoneFontFamilyNormal}"</span></pre><pre class="alt">    <span class="attr">FontSize</span><span class="kwrd">="{StaticResource PhoneFontSizeNormal}"</span></pre><pre>    <span class="attr">Foreground</span><span class="kwrd">="{StaticResource PhoneForegroundBrush}"</span></pre><pre class="alt">    <span class="attr">SupportedOrientations</span><span class="kwrd">="Portrait"</span> <span class="attr">Orientation</span><span class="kwrd">="Portrait"</span></pre><pre>    <span class="attr">shell:SystemTray</span>.<span class="attr">IsVisible</span><span class="kwrd">="True"</span><span class="kwrd">&gt;</span></pre><pre class="alt">&nbsp;</pre><pre>    <span class="rem">&lt;!--LayoutRoot is the root grid where all page content is placed--&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;</span><span class="html">Grid</span> <span class="attr">x:Name</span><span class="kwrd">="LayoutRoot"</span> <span class="attr">Background</span><span class="kwrd">="Transparent"</span><span class="kwrd">&gt;</span></pre><pre>    <span class="kwrd">&lt;/</span><span class="html">Grid</span><span class="kwrd">&gt;</span>    </pre><pre class="alt"><span class="kwrd">&lt;/</span><span class="html">phone:PhoneApplicationPage</span><span class="kwrd">&gt;</span></pre></div>
<style type="text/css">.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; }
</style>

<p>We need to make this page reference the base class of the DTNet.StateAwareNavigationPage. We’ll do this just like we did for the App.xaml by adding the namespace reference and changing every occurrence of “&lt;phone:PhoneApplicationPage” or “&lt;/phone:PhoneApplicationPage” to “&lt;dtnet:StateAwareNavigationPage” or “&lt;/dtnet:StateAwareNavigationPage.” Here’s the xaml from above fixed:</p>
<div class="csharpcode"><pre class="alt"><span class="kwrd">&lt;</span><span class="html">dtnet:StateAwareNavigationPage</span></pre><pre>    <span class="attr">x:Class</span><span class="kwrd">="ProximityToy.MainPage"</span>    </pre><pre class="alt">    <span class="attr">xmlns</span><span class="kwrd">="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>    </pre><pre>    <span class="attr">xmlns:x</span><span class="kwrd">="http://schemas.microsoft.com/winfx/2006/xaml"</span>    </pre><pre class="alt">    <span class="attr">xmlns:phone</span><span class="kwrd">="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"</span>    </pre><pre>    <span class="attr">xmlns:shell</span><span class="kwrd">="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"</span>    </pre><pre class="alt">    <span class="attr">xmlns:d</span><span class="kwrd">="http://schemas.microsoft.com/expression/blend/2008"</span>    </pre><pre>    <span class="attr">xmlns:mc</span><span class="kwrd">="http://schemas.openxmlformats.org/markup-compatibility/2006"</span>    </pre><pre class="alt">    <span class="attr">mc:Ignorable</span><span class="kwrd">="d"</span>    </pre><pre>    <span class="attr">FontFamily</span><span class="kwrd">="{StaticResource PhoneFontFamilyNormal}"</span>    </pre><pre class="alt">    <span class="attr">FontSize</span><span class="kwrd">="{StaticResource PhoneFontSizeNormal}"</span>    </pre><pre>    <span class="attr">Foreground</span><span class="kwrd">="{StaticResource PhoneForegroundBrush}"</span>    </pre><pre class="alt">    <span class="attr">SupportedOrientations</span><span class="kwrd">="Portrait"</span> <span class="attr">Orientation</span><span class="kwrd">="Portrait"</span>    </pre><pre>    <span class="attr">shell:SystemTray</span>.<span class="attr">IsVisible</span><span class="kwrd">="True"</span></pre><pre class="alt">    <span class="attr">xmlns:dtnet</span><span class="kwrd">="clr-namespace:DTNet"</span> <span class="kwrd">&gt;</span>     </pre><pre>    </pre><pre class="alt">    <span class="rem">&lt;!--LayoutRoot is the root grid where all page content is placed--&gt;</span>    </pre><pre>    <span class="kwrd">&lt;</span><span class="html">Grid</span> <span class="attr">x:Name</span><span class="kwrd">="LayoutRoot"</span> <span class="attr">Background</span><span class="kwrd">="Transparent"</span><span class="kwrd">&gt;</span>    </pre><pre class="alt">    <span class="kwrd">&lt;/</span><span class="html">Grid</span><span class="kwrd">&gt;</span>    </pre><pre><span class="kwrd">&lt;/</span><span class="html">dtnet:StateAwareNavigationPage</span><span class="kwrd">&gt;</span></pre></div>
<style type="text/css">.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; }
</style>

<p>(the above example only had 2 text changes plus the namespace reference, but if you may have more references to “phone:PhoneApplicationPage” you will have to change them, so be aware).</p>
<p>Next you make the codebehind’s (aka <em>PAGE</em>.xaml.cs file) class derive from DTNet.StateAwareNavigationPage. This is pretty easy. You’ll also want to add the 3 new method overrides. It will look something like this:</p>
<div class="csharpcode"><pre class="alt"><span class="rem">// Using above this line</span></pre><pre><span class="kwrd">namespace</span> MyProject</pre><pre class="alt">{</pre><pre>    <span class="kwrd">public</span> <span class="kwrd">partial</span> <span class="kwrd">class</span> MainPage:DTNet.StateAwareNavigationPage     </pre><pre class="alt">    {</pre><pre>        <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnFastSwitchedTo(System.Windows.Navigation.NavigationEventArgs e)</pre><pre class="alt">        {</pre><pre>        }</pre><pre class="alt">&nbsp;</pre><pre>        <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnResumedFromTombstone(System.Windows.Navigation.NavigationEventArgs e)</pre><pre class="alt">        {</pre><pre>        }</pre><pre class="alt">&nbsp;</pre><pre>        <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnNormalNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)</pre><pre class="alt">        {</pre><pre>        }</pre><pre class="alt">        </pre><pre>        // more code follows</pre></div>
<style type="text/css">.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; }
</style>

<p>&nbsp;</p>
<p>Finally you will want to take the <em>OnNavigatedTo</em> Event (in your code) and remove the code placing it into the appropriate methods (you will probably create a method with the common code to reduce duplication of code). Finally delete the <em>OnNavigatedTo</em> Event (or at the least add a line that routine to call the base.<em>OnNavigatedTo</em> routine).</p>
<p> Just in case you missed this point, you do the page changes to every page you want to enable this functionality in.</p>
<p>Admittedly it is a lot of work for an existing project, but for a new one it’s not that bad. I have been meaning to create templates for this, but have never really had the time. Anyway, that’s it. Let me know what you think…</p>
<p>Just a reminder the 2 classes can be <a href="http://bit.ly/1emxCOF">found on project’s repository</a>.</p><br /><a href='http://www.jaykimble.net/wp8-apppage-base-navigation-classes.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/wp8-apppage-base-navigation-classes.aspx</link>
      <author>jkimble@intradynamics.net (Jay Kimble)</author>
      <comments>http://www.jaykimble.net/wp8-apppage-base-navigation-classes.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/wp8-apppage-base-navigation-classes.aspx</guid>
      <pubDate>Tue, 15 Oct 2013 19:22:18 GMT</pubDate>
    </item>
    <item>
      <title>SpeechHelper class</title>
      <description><![CDATA[<p>I wrote a mini library which features a main helper class for Speech. I did this because I wanted to bring both the talking and the listening (recognition) aspects into a single class. I expose all the regular classes as well through the same object making it easy for you to simply use the helper class without having to know all the ins and outs of the speech classes. You can get the code from it’s <a href="http://bit.ly/1cPdAP7">online source code repository</a>.</p> <p>Here’s some c# code to show you how easy this is to use:</p> <style type="text/css">.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; }
</style> <pre class="brush: c-sharp; collapse: true">// First of all this class brings together all the speech
<br>// related classes and offers some shortcuts. The overall
<br>// goal is to make it so we only need to know 1 class
<br>await SpeechHelper.Instance.Say("Hello. What is your name?");
<br>
<br>var name = await SpeechHelper.Instance.UI.RecognizeWithUIAsync();
<br>
<br>// Next we make some things a little easier to do like handling 
<br>// speech recognition with a word list.
<br>var listOfWords = (
<br>       new [] {
<br>            "Blue", 
<br>            "Red", 
<br>            "Green", 
<br>            "Purple", 
<br>            "Orange",
<br>            "Yellow" }).ToList();
<br>
<br>// BTW, the prompt here ("What is your favorite color?" is an
<br>// optional parameter
<br>var favColor= await SpeechHelper.Instance.RecognizeWordInListAsync(
<br>                listOfWords, 
<br>                "What is your favorite color?", true); 
<br>// Last parameter indicates that we want to use the SpeechRecognizer 
<br>// with the default UI
<br>
<br>var age await SpeechHelper.Instance.RecognizeNumberAsync(
<br>                "How old are you?", true);
<br>
<br>// One caveat to this is that if the recognition fails you will get an 
<br>// empty string (which we aren't bother to test for here).
<br>var prompt = String.Format("Hello, {0}! I understand that" +
<br>                                             " you are {1} years old and like " + 
<br>                                             "the color {2}. Is this correct?",
<br>               name,favColor,age);
<br>               
<br>// Finally detect a boolean response (understands a lot of english variations)
<br>var correct = await SpeechHelper.Instance.AskYesNoQuestionAsync(prompt, true);
</pre>
<p>You can find the links to the repository for this over on the Libraries site (there are some additional things in this dealing with SRGS which is not complete).</p>
<p>------------------</p>
<p><a href="http://bit.ly/1cPdAP7">Again, you can get it here</a>.</p><br /><a href='http://www.jaykimble.net/speechhelper-class.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/speechhelper-class.aspx</link>
      <author>jkimble@intradynamics.net (Jay Kimble)</author>
      <comments>http://www.jaykimble.net/speechhelper-class.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/speechhelper-class.aspx</guid>
      <pubDate>Mon, 14 Oct 2013 21:39:25 GMT</pubDate>
    </item>
    <item>
      <title>New Dev Utils/Libraries page</title>
      <description><![CDATA[<p>&nbsp;</p> <p>I recently was asked to create a single page with my utility classes/libraries that I have built.</p> <p>You can find the beginnings of that right here: <a title="http://bit.ly/18f9096" href="http://bit.ly/18f9096">http://bit.ly/18f9096</a></p> <p>I am in much need of documenting some of these (hence, they hadn’t been talked about anywhere other than with people who meet me personally).</p> <p>I will try to blog about these as I have time. I will get the first one out of the way today (following this post)..</p><br /><a href='http://www.jaykimble.net/new-dev-utilslibraries-page.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/new-dev-utilslibraries-page.aspx</link>
      <author>jkimble@intradynamics.net (Jay Kimble)</author>
      <comments>http://www.jaykimble.net/new-dev-utilslibraries-page.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/new-dev-utilslibraries-page.aspx</guid>
      <pubDate>Mon, 14 Oct 2013 21:38:52 GMT</pubDate>
    </item>
    <item>
      <title>Adventures in Win8, WP8, and Game Maker Studio</title>
      <description><![CDATA[<p>My son and I have been playing with Game Maker Studio and have been building apps for Win8 Store and Windows Phone Store. This is a place holder post where I may link everything together in one handy place.</p><br /><a href='http://www.jaykimble.net/adventures-in-win8-wp8-and-game-maker-studio.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/adventures-in-win8-wp8-and-game-maker-studio.aspx</link>
      <comments>http://www.jaykimble.net/adventures-in-win8-wp8-and-game-maker-studio.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/adventures-in-win8-wp8-and-game-maker-studio.aspx</guid>
      <pubDate>Thu, 30 May 2013 16:47:49 GMT</pubDate>
    </item>
    <item>
      <title>WP8 Speech Recognizers</title>
      <description><![CDATA[<p>If you don’t know I have been deep into WP8’s Speech SDK for the last 6 months. So much so that I am starting to help others along the way. I just got a question about how to get the confidence rating on a recognized word. </p> <p>If you don’t know what that means, let me explain. Basically the speech recognition is not an exact science. There are complicated algorithms that analyze your speech to determine what words were spoken. One of the cool things with WP8’s SDK is that you can provide a list of words or phases you are looking for and this makes things a little more accurate (mainly because you are limiting the number of combinations to look for).</p> <p>WP8 has 2 objects that you can use to recognize speech: SpeechRecognizer and SpeechRecognizerUI.</p> <p>SpeechRecognizer gives you something a little more low level. It won't show the “pretty” UI that is shown while listening to the user speak; it won’t play a beep sound to indicate that speech is being recorded for recognition, nor does it give the user any feedback whatsoever. It does let you supply a list of words or phrases you are looking for as well as will do the big check for listening for any word. The SpeechRecognizerResult will give you the word (or words) it thinks the user said. It also will give you a list of alternates (via the GetAlternates() method) that might be what the user said. It also gives you a number to tell you how accurate it estimates that it was (and gives this rating for each of the alternates as well). It will also let you do your own recording and will process the speech from your recording (but it accepts a much smaller clip than what the actual MS mechanisms do). Actually doing a recognize for any word will allow for a shorter amount of data.</p> <p>SpeechRecognizerUI does a lot of work for you. It puts up the UI, plays the beep to inidicate to the user to speek, handles the case where a word isn't quite recognized, and generally let’s the user know what is going on throughout the process. It returns a SpeechRecognizerUIResult object which contains SpeechRecognizerResult (in the RecognizerResult property), but the confidence is usually high (I have yet to see any alternates come through). I think this is mainly because the UI object does the extra work of clarifying with the user when it estimates that the accuracy of the recognition isn’t quite that high.</p> <p>From my work, I have found that I tend to use SpeechRecognizerUI more often the the lower level mechanism. Mainly because the added UI/indicators creates a very good experience for the user.</p> <p>[I find it difficult to not attribute human qualities to the recognizer. It was tough not to use words like “guess” during this post.. the recognizer is really amazing how accurate it is and when it is wrong, it’s usually pretty understandable why.]</p><br /><a href='http://www.jaykimble.net/wp8-speech-recognizers.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/wp8-speech-recognizers.aspx</link>
      <comments>http://www.jaykimble.net/wp8-speech-recognizers.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/wp8-speech-recognizers.aspx</guid>
      <pubDate>Mon, 15 Apr 2013 14:51:50 GMT</pubDate>
    </item>
    <item>
      <title>Test post.. nothing to see here yet</title>
      <description><![CDATA[<p>Just putting a test post out..</p><br /><a href='http://www.jaykimble.net/test-post-nothing-to-see-here-yet.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/test-post-nothing-to-see-here-yet.aspx</link>
      <comments>http://www.jaykimble.net/test-post-nothing-to-see-here-yet.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/test-post-nothing-to-see-here-yet.aspx</guid>
      <pubDate>Fri, 18 Jan 2013 14:59:18 GMT</pubDate>
    </item>
    <item>
      <title>Logo For Windows8 in JavaScript: Lessons Learned</title>
      <description><![CDATA[<p>So <a href="http://new.efficientcoder.net/">Kevin Wolf</a> created a community challenge with a ARM Surface Tablet as the prize. He presented this to the local Florida Windows8 Development Community which I am a part of.</p> <p>Here’s the basics of the challenge:</p> <ul> <li>The Windows 8 App must be 100% JavaScript/HTML/CSS; no other client technologies allowed.</li> <li>It had to be in the Windows Store by Dec. 1st (we had approximately 2 months to do it)</li> <li>He wanted the app to be non-trivial so therefore there was criteria for what was “non-trivial”:</li> <ul> <li>App must have a market base that was not the development community (and could not be a sample app). In other words it had to have an audience, a real audience.</li> <li>App must implement some form of capture (first name, last name, etc)</li> <li>App must connect to a web service of some type and pull and push data to it (both reads and writes); social networking sites were disallowed, but any other public or private web service was acceptable</li> <li>Needed to implement either search or the share contracts</li> <li>Must use either:</li> <ul> <li>the camera in a meaningful way</li> <li>Location services AND Bing maps in a meaningful way</li></ul> <li>Must implement 1 animation</li></ul></ul> <p>That was it. When I saw the list I was thought, “Boy, he rigged the contest.” I could do that, but I’ve done this kind of insane project in the past. I considered doing it and forgot about it for a month.</p> <p><strong>A Funny Thing Happened on the way to a presentation</strong></p> <p>So&nbsp; along the way I had agreed to do a presentation for the Great American Teach in at my kids’ school. I decided that I would show them some beginning programming with the Logo programming environment (aka Turtle Graphics). I decided since I would be using my Samsung Slate to do this that I should probably go ahead and find a Windows 8 implementation of logo. I couldn’t find one. After a bit of searching around I found a nifty one in JavaScript using the HTML5 Canvas. I decided to take this single page environment and make a full Windows 8 Store app with it. It was all rather trivial. I think the initial version took me 2 evenings to get working (so a couple of hours). I did have to change things. The version I had was using jqConsole which seemed to be overkill, but it provided one nice thing: history. So I fired up TyopeScript and created a nice little history component for my jqConsole replacement (essentially a Textbox with a sprinkling of JavaScript code to sniff for the enter key). I also added a few buttons to make it convenient to retrieve past history items and a scrollable region containing that history.</p> <p>My presentation went off wonderful, and now I was thinking about finishing the app and getting it into the store (really as a convenience for others). It was at this point that I remember the challenge and realized that I had done the first couple items. Next up was the whole Share contract. Essentially what I did was make it possible to share out your history. I also implemented (I think) the opposite mechanism where you can share text back to the Logo app where each line will be executed by the Logo interpreter. </p> <p>For the animation I created a simple movement of my turtle in CSS; he starts at the bottom of the page and moves to the center where he belongs. </p> <p>Next I implemented hitting my personal App Analytics server for Error reporting (mainly). It stays off in most cases unless I am having issues with something then I turn it on for an app. Anyway, I only implemented the read component of this.</p> <p>At this point I submitted to the Windows8 Store. I failed for not having a privacy policy (you have to have one when you need Internet access). That was harder than it should have been since I needed to learn a few things about doing this in HTML5 apps (which, BTW, is easier than what it takes in XAML.. HTML5 apps have a few more controls that we should have in XAML, but I digress). I got in…</p> <p>I announced that I had won the challenge, only to read closer and realized that I needed GPS and WebService pushes. I decided to implement a non-standard GLAT/GLONG expressions in the Logo interpreter as a nicety for teaching students how to write a “how close am I too the equator (or other landmarks)” function. This didn’t take that long.</p> <p>I next implemented a simple write to my Web service and got it working (this was harder). For both of the these I wrote TypeScript. I’ve learned enough about JavaScript that if I am writing something non-trivial I want a tool to help me. There are way too many gotchas with JavaScript that it just makes sense to me (Mind you, I have maintained systems that have tens of thousands of lines of JavaScript code and even worked on a system with 100k of JavaScript! By no means am I a rookie). I got it working and got rejected on Tuesday do to something not working.. not sure what that would be…</p> <p>BUT I realized that the requirement was to write something with GPS AND Maps.. Not just GPS. If I had chosen camera (and I could have come up with something for that, but reasons also matter, because of the words “meaningful way”), I would have more or less been there. I have resubmitted but even if this version gets in before Dec. 1, I still didn’t complete the challenge…</p> <p><strong>Surprises</strong></p> <p>I ran into a couple of surprises. In some respects the set of controls that MS has enabled with WinJS/Html is a little more rich, and pretty easy to setup. The biggest item was the flyout when I built a settings panel for my GPS Enabler. The code to write this was mostly HTML and magic CSS Classes (I say magic because the MS Environment just knows what to do with them to create the control). This actually had me slightly enamored..</p> <p><strong>Takeaways </strong></p> <p>First of all if you have talked to me in the last week or so you may have gotten a different impression. I mentioned some positives to this. There are definitely some positives. BUT, I also need to factor in me. I was a trainer during the Web 2.0 craze. I knew my stuff. I once worked on/maintained/added features to a web project that had close to 100k lines of JavaScript code. I want you to ponder that for a moment…. you back? Good. Now realize that I can do non-trivial things with JavaScript and HTML (things you might not be able to do). I’m not as knowledgeable with the latest and greatest on the HTML5 track, but by no means am I an newbie with this. </p> <p>Also, the project I took was something that already worked well with IE10, and I simply sucked it into the Windows8 Templates. If that was the end of the story then I would say everyone should be doing this, but it’s not. While my project was non-trivial, the task seemed to be trivial. Creating the share contract for instance involved me tweaking the JS code to expose things I could share. I imagine this is the case with Search as well.. you will have a fair bit of tweaking to make things happen.</p> <p>Lessons Learned</p> <p>So the positives, Microsoft has thought through this and what they have delivered is a nice environment. You can do some stuff with this. They have enabled a pretty easy mechanism for you to access the various controls via CSS Styles which makes things pretty easy on that front. If you are doing something fairly trivial (port a single page over that already works in IE10, or single page that sucks in rss feeds) then have at it. You can do it with HTML5/WinJS. </p> <p>If you are doing anything more complex, I would suggest skipping HTML5, and putting on your “big boy” pants and building your app with XAML, VS2012, Blend (if you need it), and a copy of John Papa’s <a href="http://shop.oreilly.com/product/9780596523107.do">Data-Driven Services with Silverlight 2</a> (which needs to be renamed “Data-Driven Services with XAML” because it still applies today). With all that in hand you can do XAML. It’s not that hard. AND, by “complex” I mean web services in any form (where you don’t already have a fully tested/stable JavaScript library to access that service), Maps, Fancy Animations, File Apis, anything data driven… </p> <p>Another lesson learned, if you have to write JavaScript, write TypeScript instead. You still have to remember that you are using closures from things like events, but it’s certainly a lot better having the design environment tell you when something is wrong due to typing, or misspelling, etc.</p> <p>Html/WinJS has the same net effect in my mind as most of the JavaScript apps I have written in the past.. they are quirky. My Xaml apps feel much more solid. In my mind I will keep an eye on the technology, but I am going to stick with XAML for the near future… (you can’t do everything in JavaScript as some would like us to believe).</p><br /><a href='http://www.jaykimble.net/logo-for-windows8-in-javascript-lessons-learned.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/logo-for-windows8-in-javascript-lessons-learned.aspx</link>
      <comments>http://www.jaykimble.net/logo-for-windows8-in-javascript-lessons-learned.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/logo-for-windows8-in-javascript-lessons-learned.aspx</guid>
      <pubDate>Thu, 29 Nov 2012 20:15:29 GMT</pubDate>
    </item>
    <item>
      <title>Windows Store Rejection#1: Lessons Learned about Age Ratings</title>
      <description><![CDATA[<p>Just thought I would fire up a quick post (and maybe a little advice to the powers that be at Microsoft).</p> <p>I have been working on a Dropbox Client for the last several months in my spare time. I actually almost quit on the process and realized that what I had was more integrated with Windows 8 than anything else in the Windows Store, and that I really wanted to use my own app over anything else that is currently out there. Mind you I was about a week away when I decided to quit. When my work schedule broke a little I decided I NEEDED to finish this. So last Tuesday I finished it up and submitted to the Windows Store. </p> <p>When I was filling out the submission, I got to the line that asks about Age Rating.. this seems weird to me, I hadn’t really thought about it. I mean I would expect it to be rated E (for Everyone) because you bring your own content. I could see a 3 year old being able to operate it.. so I set it to 3 and eliminated any country that wanted me to back that up (at least for now). </p> <p>SIDENOTE: In other Mobile AppStores (you know the one who considers themselves the owner of the name “AppStore”), they don’t ASK you what you think your rating should be, they ask you a series of questions about your app and then they TELL you what your rating is.</p> <p>So, A whole week later, I get the notification (this morning, actually) that I got rejected. I wasn’t offended. It happens there are many things in the guidelines and it’s really easy to miss something or to have a corner of your app that is not as well tested. This was my first time through so I expected this. Of course it was for the aforementioned Age Rating. I checked SkyDrive and saw it was Age Rated for 12+.&nbsp; I assume from reading the materials it was because I have ads in an app and they don’t think anyone younger than 13 should see ads. Seems weird, but OK.. </p> <p>NOW, This is the rub. I made 2 clicks to change the Age Rating from 3+ to 12+ and hit resubmit.. No code has changed. Nothing has REALLY changed except that my age was set too low. Where am I in the process now? At the back of the line waiting another 7 days to hear if there was anything else.</p> <p align="left">[Warning Rant to proceed from here on]<br>I’m assuming that most of the tough stuff is out of the way, but I don’t really know. It does seem strange that I went through the whole process already and I have to wait 7 days. I mean I already passed presumably a number of issues. It seems like a waste of EVERYONE;’s time for me to have to wait and to have EVERYTHING thus far tested for a ZERO code change (no new binaries have been uploaded). This process needs to be streamlined some more that is for sure. Especially considering they want to have <a href="http://news.cnet.com/8301-10805_3-57527938-75/microsoft-vp-100000-windows-8-apps-by-january/">100,000 apps in the Windows Store by January</a>. If they don’t change the process some then that goal will never happen. Just my 2 cents.</p><br /><a href='http://www.jaykimble.net/windows-store-rejection1-lessons-learned-about-ages.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/windows-store-rejection1-lessons-learned-about-ages.aspx</link>
      <comments>http://www.jaykimble.net/windows-store-rejection1-lessons-learned-about-ages.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/windows-store-rejection1-lessons-learned-about-ages.aspx</guid>
      <pubDate>Wed, 10 Oct 2012 14:45:54 GMT</pubDate>
    </item>
    <item>
      <title>Why MetroOAuth? or C# Async makes life easier</title>
      <description><![CDATA[<p>Yesterday, I finally pushed some of the oAuth libraries I have been tinkering with. I have a really nice and simple library (and this simplicity seems to flow throughout the library). I decided to pull out some examples using my DropboxClient to show how much simpler a library can be. <p>Here’s how you log in to Dropbox (in c#):</p> <div id="codeSnippetWrapper" style="overflow: auto; cursor: text; font-size: 8pt; border-top: silver 1px solid; font-family: 'Courier New', courier, monospace; border-right: silver 1px solid; border-bottom: silver 1px solid; padding-bottom: 4px; direction: ltr; text-align: left; padding-top: 4px; padding-left: 4px; margin: 20px 0px 10px; border-left: silver 1px solid; line-height: 12pt; padding-right: 4px; max-height: 200px; width: 97.5%; background-color: #f4f4f4"> <div id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: 'Courier New', courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: 'Courier New', courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span style="color: #008000">// if the user has already auth'd you can save this in ISO Store or localstorage</span></pre><!--CRLF--><pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: 'Courier New', courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4">var accessKey = <span style="color: #006080">""</span>; <span style="color: #008000">// in our case we are setting it to empty (but it's not required)</span></pre><!--CRLF--><pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: 'Courier New', courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white">var client = <span style="color: #0000ff">new</span> DropboxClient(kDropBoxAppKey, kDropBoxAppSecret, accessKey);</pre><!--CRLF--><pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: 'Courier New', courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4">var authd = <span style="color: #0000ff">false</span>;</pre><!--CRLF--><pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: 'Courier New', courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span style="color: #0000ff">if</span> (client.IsAuthenticated) <span style="color: #008000">// do we already have an access key</span></pre><!--CRLF--><pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: 'Courier New', courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4">  authd = <span style="color: #0000ff">true</span>;</pre><!--CRLF--><pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: 'Courier New', courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span style="color: #0000ff">else</span></pre><!--CRLF--><pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: 'Courier New', courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4">  authd = await App.DropboxApi.Authorize(<span style="color: #006080">"http://www.tbwindev.org"</span>); <span style="color: #008000">// URI to go to once logged in</span></pre><!--CRLF--><pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: 'Courier New', courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white">&nbsp;</pre><!--CRLF--><pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: 'Courier New', courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span style="color: #0000ff">if</span>(authd)</pre><!--CRLF--><pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: 'Courier New', courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white">{</pre><!--CRLF--><pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: 'Courier New', courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4">    <span style="color: #008000">// Do something</span></pre><!--CRLF--><pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: 'Courier New', courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white">}</pre><!--CRLF--></div></div>
<p>We put everything into that example just so you can see the full set up. You don’t need the accessKey for instance and can simply leave it off that call (it’s optional). Like the comment says, after the user has Authorized your app you can grab that value from the client (stored in a property) and save it off, and then the user will not need to re-authenticate.
<p>The “if” statement where we check if the user is already authenticated is really a convenience method, but you don’t want to re-authorize the user.
<p>The only lines you really need are the creation of the DropboxClient and the line to Authorize.</p>
<p>Now what is behind that Authorize call is what makes this amazing to me. There are 2 http calls that happen with a call to the WebAuthenticationBroker to show the user a web browser window that is on the Dropbox site. All of these things happen asynchronously, but they happen in order. So, there is a call to get a temporary key which we use with the URI that we push the user to the Dropbox site’s login. After they have logged in (or closed the windows), we check to see if we got a code from the call. If so we make a call to get our official accessKey, and we can proceed from there. Again, all of this happens asynchronously, and your UI will be responsive during this time.</p>
<p>Async makes it so we don’t have to set up any kind of response action or event, etc. Each of the calls returns a Task or a Task&lt;T&gt;. We simply tell the compiler that we want to wait for the task that was passed back to us to complete before we proceed. Inside of the task that we get back there might be other tasks that get awaited. This makes it possible to have a method have a single responsibility without having to clutter it up with what happens or a link to what will happen on return.</p>
<p>&nbsp;</p>
<p>AND, all this works in Metro and WP7.x (as long as you install the Async CTP)</p>
<p>Anyway, I’ll blog some more on this soon.</p>
<p>BTW, my project is at <a href="http://metrooauth.codeplex.com">http://metrooauth.codeplex.com</a> and the current (rather cluttered) code repo is at <a href="https://bitbucket.org/DevTheo/metrodropbox">https://bitbucket.org/DevTheo/metrodropbox</a></p><br /><a href='http://www.jaykimble.net/why-metrooauth-or-c-async-makes-life-easier.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/why-metrooauth-or-c-async-makes-life-easier.aspx</link>
      <comments>http://www.jaykimble.net/why-metrooauth-or-c-async-makes-life-easier.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/why-metrooauth-or-c-async-makes-life-easier.aspx</guid>
      <pubDate>Wed, 18 Jul 2012 16:36:04 GMT</pubDate>
    </item>
    <item>
      <title>Metro Nuggets: Cloud-based File Contracts helper - UriBasedStorageFile</title>
      <description><![CDATA[<p>I have been doing a series of posts around my adventures in creating a cross-platform Dropbox library for Windows Phone and WinRT. I actually have a working API at this point, so of course the next step is to look into implementing a File Open Contract.</p> <p>One of the first things you will notice is that you have to return set of IStorageFile back to the caller. So you have to essentially hand back a mechanism that the caller can use to open your file from the cloud (without the caller necessarily needing to know anything about that). At least this is my understanding at this point. I might have to pre-download my files (something I will be testing very soon).</p> <p>Regardless, I thought it would be nice to go ahead and implement IStorageFile based on an URI. So I have created (and am letting you tinker with) this class. Here’s what happens with it. You call the constructor of my class with a URI that can be used to access the file (aka download the file), and my class builds up a read-only file that the file system thinks is a regular old file (BUT there are a bunch of things unimplemented, so you won’t be deleting files for instance). You can even control how the class acts when an unimplemented function is called (it can silently fail or generate an exception).</p> <p>Let’s see some code:</p> <div id="codeSnippetWrapper" style="cursor: text; font-size: 8pt; border-top: silver 1px solid; font-family: 'Courier New', courier, monospace; border-right: silver 1px solid; width: 97.5%; border-bottom: silver 1px solid; overflow: auto; padding-bottom: 4px; direction: ltr; text-align: left; padding-top: 4px; padding-left: 4px; margin: 20px 0px 10px; border-left: silver 1px solid; line-height: 12pt; padding-right: 4px; max-height: 200px; background-color: #f4f4f4"> <div id="codeSnippet" style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white">var cloudFile = <span style="color: #0000ff">new</span> UriBasedStorageFile(</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">            <span style="color: #0000ff">new</span> Uri(someUrl, UriKind.Absolute), </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white">            <span style="color: #006080">"Application/text"</span>, <span style="color: #008000">// optional mime type (default is "application/octet-stream")</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">            <span style="color: #006080">"test.txt"</span>, <span style="color: #008000">// optional file name (default last part of the path)</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white">            <span style="color: #0000ff">true</span>); <span style="color: #008000">// Ignore Not Implemented items</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">var file = await cloudFile.CopyAsync(Windows.Storage.KnownFolders.DocumentsLibrary);</pre><!--CRLF--></div></div>
<p>Yep, that’s 2 lines of code to copy a file from a URI to a file. Pretty cool hunh?</p>
<p><strong>Implementation details (stuff I learned)</strong></p>
<p>Implementing this interface is a little difficult. Well, not majorly so, but there are some gotchas. First of all, I am used to working with Tasks, something that you will get very familiar/comfortable with when/if you get into the Async stuff. The interface requires that you return IAsyncActions and IAsyncOperation&lt;T&gt;s. If you look at Task you will see that it implements this at some level, but casting does not work. After digging a bit I discovered an extension (which is a part of System). Essentially you can call your functions that return Task and Task&lt;T&gt; and then call AsAsyncAction() or AsAsyncOperation() on the returned Task to get it cast to the appropriate type.</p>
<p><strong>Design</strong></p>
<p>So, here’s what I did with this class. I implemented the interface and then call individual methods that&nbsp; return Task based equivalents and then use the AsAsync___ extension methods mentioned above. My actual methods are virtual and protected (which means you could derive a new class from them and override the missing functionality and get a something that is closer to fully functioning). I’ll actually be doing this with my Dropbox implementation so I can pass Dropbox-based files to the OS and things will act like these are actual files on the file system. Pretty cool, hunh?</p>
<p>By the way, none of this is done yet. If you want to help out, let me know.</p>
<p>Also, my description of building a File Open Contract may be incomplete. Like you I am learning this stuff. There might be a future post where I state that everything I knew is wrong. As far as the Open contract goes, at this point I am assuming that I will need to hand back the object and the caller will be able to open up the file. I am hoping that the caller will not need any kind of Internet access defined, but if that happens I will be rewriting these classes a little (so that this isn’t required.</p>
<p>So here’s the link to where the project lives: <a title="https://bitbucket.org/DevTheo/metrodropbox/overview" href="https://bitbucket.org/DevTheo/metrodropbox/overview">https://bitbucket.org/DevTheo/metrodropbox/overview</a><br>Here’s the link to where the file lives: <a title="https://bitbucket.org/DevTheo/metrodropbox/src/3617e9282c60/Common/IStorageFile" href="https://bitbucket.org/DevTheo/metrodropbox/src/3617e9282c60/Common/IStorageFile">https://bitbucket.org/DevTheo/metrodropbox/src/3617e9282c60/Common/IStorageFile</a></p>
<p>Oh yeah, the code from the last couple Metro Nuggets can be found here as well. (there have been some updates. For instance the Windows Phone WebAuthenticationBroker object has changed a little due to a bug I discovered).</p><br /><a href='http://www.jaykimble.net/metro-nuggets-cloud-based-file-contracts-helper-uribasedstoragefile.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/metro-nuggets-cloud-based-file-contracts-helper-uribasedstoragefile.aspx</link>
      <comments>http://www.jaykimble.net/metro-nuggets-cloud-based-file-contracts-helper-uribasedstoragefile.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/metro-nuggets-cloud-based-file-contracts-helper-uribasedstoragefile.aspx</guid>
      <pubDate>Wed, 28 Mar 2012 19:19:12 GMT</pubDate>
    </item>
    <item>
      <title>Metro Nuggets: WebAuthenticationBroker an oAuth solution</title>
      <description><![CDATA[<p>A few years ago I worked for a company that sponsors the Facebook C# SDK. I wrote a number of the initial demos and answered questions on StackOverflow for the project. I know what our users’ biggest challenge: getting an AccessToken.</p> <p>In terms of oAuth getting an AccessToken for an App is the equivalent to logging in. Essentially you are authenticating and getting permission from the user. As previously <a href="http://www.jaykimble.net/metro-nuggets-async-is-your-friend.aspx">mentioned</a>, I am building a Dropbox client for Windows8 Metro. Dropbox has a new oAuth style library which is (or at least appears to be) the recommended manner to communicate with Dropbox programmatically. So, my new Windows8 Metro/WinRT library needs to communicate in this manner. We will not go into the ins and outs of oAuth, but the first steps are pretty critical for you to understand. Here’s what they are (provided you don’t have an AccessToken, yet):</p> <ol> <li>Get a RequestToken (this is a temporary key/secret) for your application</li> <li>Redirect user to specific URI –inside of a browser window of some sort-- to logon and accept your app (you can provide an optional redirect URI which the user gets sent to after authenticating and accepting your app)</li> <li>Detect that the user has accepted your app, and get an AccessToken (a more permanent key/secret) using the request token</li></ol> <p>The next steps after this are to first save off the AccessToken and then use the AccessToken when making requests to the REST API. There’s a lot wrapped up in this, but the 1st step and the 3rd step are simply calls to the REST API (they are signed in a manner outlined by the oAuth spec, but let’s not get too heavy into that). That middle step is problematic for people. Constructing the URI is easy, but monitoring the Browser can be a problem for some reason.</p> <p><strong>Enter the WebAuthenticationBroker</strong><br>Microsoft solved this for us in Metro/WinRT. They have a gizmo called the WebAuthenticationBroker. Essentially this manages the process for step 2. The challenge is that sometimes an oAuth service will return additional data that we need in the QueryString of the call to our callback URI (yep, we need to do that). Cutting through all that can be a little work –especially when all you really want to be able to do is make a call to a service and use a third party API to facilitate that. Here’s what it looks like:</p> <p><a href="http://www.jaykimble.net/Data/Sites/1/media/wlw/webauthbroker.png"><img title="WebAuthBroker" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="WebAuthBroker" src="http://www.jaykimble.net/Data/Sites/1/media/wlw/webauthbroker_thumb.png" width="698" height="415"></a></p> <p>Essentially a chromeless browser window appears on the screen. Now I fully expect that Dropbox will be detecting the Windows8 Metro UI and will give us a slightly different UI (right now you have to scroll over to the login). A couple additional important items here. If you look closely you will see 2 links at the top of the WebAuthenticationBroker’s control. The one on the right restarts the process presumably taking the user back to the original URI. The one on the left allows the user to simply say “let’s go back to the app.” </p> <p>The code for this is awesome! I can’t stress how cool it works. Basically you do an await on the WebAuthenticationBroker. It returns you an object that indicates whether the user canceled, an error occurred, or we successfully got to the target URI. If we got to the target URI then we also get the additional data passed in with that request via another property. Here’s the pertinent snippet of code from my library:</p> <div id="codeSnippetWrapper" style="cursor: text; font-size: 8pt; border-top: silver 1px solid; font-family: 'Courier New', courier, monospace; border-right: silver 1px solid; width: 97.5%; border-bottom: silver 1px solid; overflow: auto; padding-bottom: 4px; direction: ltr; text-align: left; padding-top: 4px; padding-left: 4px; margin: 20px 0px 10px; border-left: silver 1px solid; line-height: 12pt; padding-right: 4px; max-height: 200px; background-color: #f4f4f4"> <div id="codeSnippet" style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white">String DropBoxUrl = await GetAuthorizeUri(endUrl);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">&nbsp;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white">System.Uri StartUri = <span style="color: #0000ff">new</span> Uri(DropBoxUrl);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">&nbsp;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white">System.Uri EndUri = <span style="color: #0000ff">null</span>;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span style="color: #0000ff">if</span>(!String.IsNullOrEmpty(endUrl))</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white">    EndUri = <span style="color: #0000ff">new</span> Uri(endUrl);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">&nbsp;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white">Debug.WriteLine(<span style="color: #006080">"Navigating to: "</span> + DropBoxUrl);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">&nbsp;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white">WebAuthenticationResult WebAuthenticationResult;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span style="color: #0000ff">if</span>(!String.IsNullOrEmpty(endUrl))</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white">    WebAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">                                        WebAuthenticationOptions.None,</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white">                                        StartUri, </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">                                        EndUri);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span style="color: #0000ff">else</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">    WebAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white">                                        WebAuthenticationOptions.None,</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">          </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span style="color: #0000ff">if</span> (WebAuthenticationResult.ResponseStatus == WebAuthenticationStatus.Success ||</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">    (WebAuthenticationResult.ResponseStatus == WebAuthenticationStatus.UserCancel &amp;&amp; WebAuthenticationResult.ResponseData != <span style="color: #0000ff">null</span>))</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white">{</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">    Debug.WriteLine(WebAuthenticationResult.ResponseData.ToString());</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white">    var accessToken = await GetAccessToken();</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">}</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span> (WebAuthenticationResult.ResponseStatus == WebAuthenticationStatus.ErrorHttp)</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">{</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white">    Debug.WriteLine(<span style="color: #006080">"HTTP Error returned by AuthenticateAsync() : "</span> + WebAuthenticationResult.ResponseErrorDetail.ToString());</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">}</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span style="color: #0000ff">else</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">{</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white">    Debug.WriteLine(<span style="color: #006080">"Error returned by AuthenticateAsync() : "</span> + WebAuthenticationResult.ResponseStatus.ToString());</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">}</pre><!--CRLF--></div></div>
<p>I try to get an AccessToken regardless of whether the user canceled or not because if the programmer didn’t specify an EndUri then I need to assume the user might have simply closed the WebAuthenticationBroker control via the link (back to app).</p>
<p>Anyway, this is a very cool mechanism. I don’t have to attach this code to the UI in any manner. It simply injects itself into the UI all on its own.</p>
<p><strong>Windows Phone compatibility object</strong><br>I have also mentioned that I am back-porting this library to Windows Phone. In the process I realized that I needed a mechanism like this one. In fact after looking at this one, I have to say that this is the way it SHOULD be done. I ha<a href="http://www.jaykimble.net/Data/Sites/1/media/wlw/webauthbroker-wp.png"><img title="WebAuthBroker-WP" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="WebAuthBroker-WP" align="right" src="http://www.jaykimble.net/Data/Sites/1/media/wlw/webauthbroker-wp_thumb.png" width="242" height="400"></a>d arguments with a few folks back in the day with the FB C# SDK in that I thought we should provide the mechanism. I was shot down (mainly because there were too many scenarios to handle.. that project provides Facebook to everything). Anyway, going back to that SHOULD be done. I realized that there should be a mechanism like this for Windows Phone. I have done that. Warning: it does rely on the Async CTP (truth be told this is what sold me on Async), BUT the code for Windows Phone is the same as the code above. To the right is a scrren shot of the the same code running on the Windows Phone emulator (using my compatibility object):</p>
<p>As you can see Dropbox knows the Windows Phone browser and presents a nicer dialog. You can also see that I have the same links in the project, etc. My underlying object injects it’s UI on top of the current page, so you don’t need to add anything other than the 3 files to your code to get this. There’s still work to be done. </p>
<p>I am attaching an early release of this to this post (but will probably bundle my compatibility plugins into an open source project (or at least will be exposing the source code repository publicly). I need to figure out a few more things before I can call this close to done, but feel free to play around with it (and if you spot any bugs or fix them.. let me know).</p>
<div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:60f6cafc-b193-4ab0-b225-bf513fee9357" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"><p>Here's the file: <a href="http://www.jaykimble.net/Data/Sites/1/media/wlw/webauthenticationbroker.zip" target="_blank">WebAuthenticationBroker-WP.zip</a></p></div><br /><a href='http://www.jaykimble.net/metro-nuggets-webauthenticationbroker-an-oauth-solution.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/metro-nuggets-webauthenticationbroker-an-oauth-solution.aspx</link>
      <comments>http://www.jaykimble.net/metro-nuggets-webauthenticationbroker-an-oauth-solution.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/metro-nuggets-webauthenticationbroker-an-oauth-solution.aspx</guid>
      <pubDate>Tue, 20 Mar 2012 20:09:35 GMT</pubDate>
    </item>
    <item>
      <title>Metro Nuggets: Async is your friend</title>
      <description><![CDATA[<p>I’m in the process of exploring the Metro-Style Win8 API. If you’ve done much looking you probably have discovered that the new Async is everywhere! This is not a bad thing as your code is much cleaner and easier to read. The downside though is that creating something that is compatible between say Win8 Metro and Windows Phone (the original metro) can be difficult.</p> <p>Luckily there is still a CTP of the Async stuff that works with Windows Phone (and it has a GoLive license, so you can use it). CTP sounds scary (it did to me too). If you are deciding to do install the Async CTP, you might want to go here --<a title="http://blogs.msdn.com/b/lucian/archive/2011/11/01/async-ctp-v3-installation.aspx" href="http://blogs.msdn.com/b/lucian/archive/2011/11/01/async-ctp-v3-installation.aspx">http://blogs.msdn.com/b/lucian/archive/2011/11/01/async-ctp-v3-installation.aspx</a>-- and read up.. since I am betting you –like I-- have some VS patches that will prevent you from installing it). To get it installed you need to temporarily uninstall the Silverlight 5 tools and any Visual Studio patches after say December.. if you look at the link it will get you started (there are a couple forum posts that were helpful to me).</p> <p>Now you are ready to play. I’m sure by now you have seen the syntax, but let’s make some comparisons (and we’ll use WIndows Phone code and an example on a class that I have rarely seen discussed: HttpWebRequest):</p> <p>Here’s the old way (warning there is a lot of code here): <div id="codeSnippetWrapper" style="cursor: text; font-size: 8pt; border-top: silver 1px solid; font-family: 'Courier New', courier, monospace; border-right: silver 1px solid; width: 97.5%; border-bottom: silver 1px solid; overflow: auto; padding-bottom: 4px; direction: ltr; text-align: left; padding-top: 4px; padding-left: 4px; margin: 20px 0px 10px; border-left: silver 1px solid; line-height: 12pt; padding-right: 4px; max-height: 200px; background-color: #f4f4f4"> <div id="codeSnippet" style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum1" style="color: #606060">   1:</span> <span style="color: #008000">// Pretend like Item info below just contains a couple pieces of info:</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum2" style="color: #606060">   2:</span> <span style="color: #008000">//  like Uri, Method, and possible a filename to save to --in IsoStorage</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum3" style="color: #606060">   3:</span> <span style="color: #0000ff">void</span> downloadSomething(UriInfo item) { </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum4" style="color: #606060">   4:</span>     var webReq = HttpWebRequest.CreateHttp(UriInfo);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum5" style="color: #606060">   5:</span>     webReq.Method = item.UriMethod;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum6" style="color: #606060">   6:</span>     WebRequests.Add(item, webReq);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum7" style="color: #606060">   7:</span>     <span style="color: #008000">// If we were passing post values to the routine we would need to </span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum8" style="color: #606060">   8:</span>     <span style="color: #008000">// Begin getting the request stream with a callback and then End Getting </span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum9" style="color: #606060">   9:</span>     <span style="color: #008000">// the request stream (this is bad enough.. don't want to overcomplicate things)</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum10" style="color: #606060">  10:</span>     webReq.BeginGetResponse(ResponseCallback, item);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum11" style="color: #606060">  11:</span> }</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum12" style="color: #606060">  12:</span> <span style="color: #0000ff">protected</span> <span style="color: #0000ff">void</span> ResponseCallback(IAsyncResult ar) {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum13" style="color: #606060">  13:</span>     IFileItem item= (IFileItem) ar.AsyncState;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum14" style="color: #606060">  14:</span>     var webR = WebRequests[item];</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum15" style="color: #606060">  15:</span>     var resp = (HttpWebResponse) webR.EndGetResponse(ar);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum16" style="color: #606060">  16:</span>&nbsp; </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum17" style="color: #606060">  17:</span>     <span style="color: #0000ff">if</span> (resp.StatusCode == HttpStatusCode.OK) {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum18" style="color: #606060">  18:</span>         <span style="color: #008000">// We could also do the whole Begin/End on the Response Stream </span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum19" style="color: #606060">  19:</span>         <span style="color: #008000">// (with another calllback)</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum20" style="color: #606060">  20:</span>         <span style="color: #0000ff">using</span> (var strm = resp.GetResponseStream()) {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum21" style="color: #606060">  21:</span>             var buffer = <span style="color: #0000ff">new</span> <span style="color: #0000ff">byte</span>[4096];</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum22" style="color: #606060">  22:</span>             item.BytesDownloaded = 0;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum23" style="color: #606060">  23:</span>             <span style="color: #008000">// If the file exists we need to delete it (BTW, using Jay's IsolatedStorage Facade which looks like System.IO.File, Directory, FileInfo, and DirectoryInfo -- "PS" stands for persisted storage)</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum24" style="color: #606060">  24:</span>             <span style="color: #0000ff">if</span> (PSFile.Exists(item.DestinationNameAndPath))</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum25" style="color: #606060">  25:</span>                 PSFile.Delete(item.DestinationNameAndPath);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum26" style="color: #606060">  26:</span>&nbsp; </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum27" style="color: #606060">  27:</span>             <span style="color: #008000">// We should actually check to see if the path exists for this file.. </span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum28" style="color: #606060">  28:</span>             <span style="color: #008000">// BTW, this uses my Isolated Storage Facade classes </span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum29" style="color: #606060">  29:</span>             <span style="color: #008000">// (so PSDirectory == SystemDirectory, but just against IsolatedStorage)</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum30" style="color: #606060">  30:</span>             <span style="color: #0000ff">if</span> (!String.IsNullOrEmpty(System.IO.Path.GetDirectoryName(item.DestinationNameAndPath)) &amp;&amp; !PSDirectory.Exists(System.IO.Path.GetDirectoryName(item.DestinationNameAndPath)))</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum31" style="color: #606060">  31:</span>                 PSDirectory.CreateDirectory(System.IO.Path.GetDirectoryName(item.DestinationNameAndPath));</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum32" style="color: #606060">  32:</span>&nbsp; </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum33" style="color: #606060">  33:</span>             <span style="color: #0000ff">using</span> (var fs = PSFile.Create(item.DestinationNameAndPath)) {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum34" style="color: #606060">  34:</span>                 var fileLength = item.ActualSize;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum35" style="color: #606060">  35:</span>                 <span style="color: #0000ff">do</span> {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum36" style="color: #606060">  36:</span>                     <span style="color: #0000ff">int</span> count = strm.Read(buffer, 0, 4096);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum37" style="color: #606060">  37:</span>                     <span style="color: #0000ff">if</span> (count &lt; 1)</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum38" style="color: #606060">  38:</span>                         <span style="color: #0000ff">break</span>;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum39" style="color: #606060">  39:</span>                     fs.Write(buffer, 0, count);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum40" style="color: #606060">  40:</span>                     item.BytesDownloaded += count;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum41" style="color: #606060">  41:</span>                 } <span style="color: #0000ff">while</span> (<span style="color: #0000ff">true</span>);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum42" style="color: #606060">  42:</span>             }</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum43" style="color: #606060">  43:</span>             item.BytesDownloaded = item.ActualSize;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum44" style="color: #606060">  44:</span>         }</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum45" style="color: #606060">  45:</span>     }</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum46" style="color: #606060">  46:</span>     <span style="color: #008000">//else </span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum47" style="color: #606060">  47:</span>         <span style="color: #008000">// We got an error or something. Normally I notify the end user of this (this is left up to you to do on your own)</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum48" style="color: #606060">  48:</span>&nbsp; </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum49" style="color: #606060">  49:</span> }</pre><!--CRLF--></div></div></p>
<p>New Way:</p>
<div id="codeSnippetWrapper" style="cursor: text; font-size: 8pt; border-top: silver 1px solid; font-family: 'Courier New', courier, monospace; border-right: silver 1px solid; width: 97.5%; border-bottom: silver 1px solid; overflow: auto; padding-bottom: 4px; direction: ltr; text-align: left; padding-top: 4px; padding-left: 4px; margin: 20px 0px 10px; border-left: silver 1px solid; line-height: 12pt; padding-right: 4px; max-height: 200px; background-color: #f4f4f4">
<div id="codeSnippet" style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum1" style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> async Task&lt;<span style="color: #0000ff">string</span>&gt; simpleHttpPost(<span style="color: #0000ff">string</span> url)</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum2" style="color: #606060">   2:</span> {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum3" style="color: #606060">   3:</span>     var uri = <span style="color: #0000ff">new</span> Uri(url);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum4" style="color: #606060">   4:</span>&nbsp; </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum5" style="color: #606060">   5:</span>     HttpWebRequest client = HttpWebRequest.CreateHttp(uri);</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum6" style="color: #606060">   6:</span>     client.Method = <span style="color: #006080">"POST"</span>;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum7" style="color: #606060">   7:</span>&nbsp; </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum8" style="color: #606060">   8:</span>     var response = (HttpWebResponse) (await client.GetResponseAsync());</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum9" style="color: #606060">   9:</span>     var _lastResultCode = response.StatusCode;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum10" style="color: #606060">  10:</span>&nbsp; </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum11" style="color: #606060">  11:</span>     <span style="color: #0000ff">if</span> ((<span style="color: #0000ff">int</span>)_lastResultCode &lt; 400) {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum12" style="color: #606060">  12:</span>     <span style="color: #0000ff">using</span> (var strm = (<span style="color: #0000ff">new</span> StreamReader( response.GetResponseStream())))</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum13" style="color: #606060">  13:</span>         <span style="color: #0000ff">return</span> await strm.ReadToEndAsync();</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum14" style="color: #606060">  14:</span>     }</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum15" style="color: #606060">  15:</span>&nbsp; </pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum16" style="color: #606060">  16:</span>     <span style="color: #0000ff">return</span> <span style="color: #006080">""</span>;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum17" style="color: #606060">  17:</span> }</pre><!--CRLF--></div></div>
<p>Admittedly when giving examples you try to keep the code similar for comparison sake. I decided to simply grab some code from my new project and from an old project. Please forgive me. I will do my best to highlight the big differences here.</p>
<p>The old way with HttpWebRequest was that you did a <em><strong>Begin____(callbackFunction)</strong></em> for nearly everything. The callback function must (among other things) call End______() to actually get what you were looking for (this could be the RequestStream, so you could make a post and push post variables, or it could be the response, or the ResponseStream – the ResponseStream at least has a synchronous version which I used above). Because this was going on you could use delegates and not lose context, but the execution order was jumbled.. so essentially you created a delegate for each callback (so the code came first) then you would call the Begin which would go out do the activity and then make calls into your code that was previously defined.. it is very ugly and hard to follow what is happening…</p>
<p>The new way introduces the use of the <em><strong>await</strong></em> or <strong><em>Await</em></strong> (in VB) keyword. When I first saw this I thought it was a gimmick, but the reality is that our APIs can be cleaner. You get the ability to simply suspend execution of your code while you wait for something to come back. You do have to mark your function with the async (or Async in VB) Keyword and use Task&lt;T&gt; as a result. </p>
<p>I really feel like the second example is much cleaner and easier to follow. At the very least you know what order things are happening..</p>
<p><strong>An Added Benefit</strong><br>Let’s make a not so contrived example to show you something else that is pretty cool. Let’s assume that we have an app whose first action is to run out to a service of some sort and get some data that will be databound to the UI. Meanwhile we have a few additional things that need to be done (so we don’t want to be prevented by the download)..</p>
<div id="codeSnippetWrapper" style="cursor: text; font-size: 8pt; border-top: silver 1px solid; font-family: 'Courier New', courier, monospace; border-right: silver 1px solid; width: 97.5%; border-bottom: silver 1px solid; overflow: auto; padding-bottom: 4px; direction: ltr; text-align: left; padding-top: 4px; padding-left: 4px; margin: 20px 0px 10px; border-left: silver 1px solid; line-height: 12pt; padding-right: 4px; max-height: 200px; background-color: #f4f4f4">
<div id="codeSnippet" style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum1" style="color: #606060">   1:</span> <span style="color: #0000ff">protected</span> <span style="color: #0000ff">void</span> setupMainPage() {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum2" style="color: #606060">   2:</span>     getData();</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum3" style="color: #606060">   3:</span>     <span style="color: #008000">// Next line will happen before the getData call fully completes</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum4" style="color: #606060">   4:</span>     <span style="color: #008000">// this is because we are not "await"ing the return</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum5" style="color: #606060">   5:</span>     doSomethingElse();</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum6" style="color: #606060">   6:</span> }</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum7" style="color: #606060">   7:</span> <span style="color: #0000ff">protected</span> async <span style="color: #0000ff">void</span> getData() {</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum8" style="color: #606060">   8:</span>     var result = await simpleHttpPost(<span style="color: #0000ff">new</span> Uri(<span style="color: #006080">"http://someDomain.com/someService"</span>));</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum9" style="color: #606060">   9:</span>     var dataObject = deserializeObject(result); <span style="color: #008000">// turns json string into object</span></pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum10" style="color: #606060">  10:</span>     <span style="color: #0000ff">this</span>.DataContext = dataObject;</pre><!--CRLF--><pre style="border-top-style: none; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; overflow: visible; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum11" style="color: #606060">  11:</span> }</pre><!--CRLF--></div></div>
<p>So essentially we can fire things off and when they complete they will continue running. We don’t have to await everything.</p>
<p><strong>Preview of Future posts</strong><br>At present I am building a new Dropbox client library for Windows8 and am retrofitting it for Windows Phone. To do this I had to create some compatibility objects for Windows Phone to make this happen. I actually also had to create some helper objects that do things like HTTP because they are very different and I wanted to avoid compiler directives as much as is possible. I will be writing about all of this in the coming weeks. I will eventually be speaking at a combines Tampa Bay Windows Phone UG and Tampa Bay Windows Dev UG meeting about all of this.</p><br /><a href='http://www.jaykimble.net/metro-nuggets-async-is-your-friend.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/metro-nuggets-async-is-your-friend.aspx</link>
      <comments>http://www.jaykimble.net/metro-nuggets-async-is-your-friend.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/metro-nuggets-async-is-your-friend.aspx</guid>
      <pubDate>Tue, 20 Mar 2012 18:15:04 GMT</pubDate>
    </item>
    <item>
      <title>Windows8 CP: Almost there!</title>
      <description><![CDATA[<p>So this is more of a review and less of a techy post. Yesterday as I was exploring Win8, I discovered 2 apps in the store that are important in my mobile world: EverNote and the YouVersion Bible. </p> <p>You see, I have a daily routine where I bring up YouVersion on my Acer Iconia (Android) Tablet (before this I used an iPad2.. before that I had a less techy way of doing this). I read a little scripture and then note a couple verses and then I bring up EverNote paste in the scriptures and write a few notes for myself as well as do some general journaling. It helps to keep my thoughts together before I go full force in my day.</p> <p>I was stoked because I could possibly move entirely to Windows 8. I actually started checking prices on Tablets that would run Win8, and I was thinking I could have my tablet experience with the full power of Windows.. this would be more than cool!</p> <p>Now I tried this with the developer bits, but the desktop EverNote didn’t bring up the keyboard appropriately, I gave up and went back to my iPad at the time..</p> <p>So this morning I tried it. You can guess by the post’s title that something didn’t work. I was actually able to not only bring both apps up, but pin the Bible on the left hand side. Where things failed was EverNote. It let’s you edit notes, but I could not change the notebook I was saving too. It seems to default to a Notebook I set up to do a knowledge transfer to my job (as I was leaving the company). I also couldn’t figure out how to edit after I had accidently closed the notebook. I will have to wait for an update to EverNote before I can really use this.</p> <p>Oh yeah, I will also be wanting the YouVersion guys to update their app and give me offline bibles (otherwise I have to have wifi always which in the morning isn’t too much trouble).</p> <p>Beyond this fact I am liking the evolution of the OS from the Developer Bits. I have read some stuff about how the OS isn’t necessarily intuitive in all respects, and I would concur. I have watched all the intro videos, so I know to swipe up to get app’s menu or swipe on the right hand side to get the charms or to swipe left to bring in an already running app.. and I figured out the whole swipe down to be able to throw your app off screen (shutting it off).</p><br /><a href='http://www.jaykimble.net/windows8-cp-almost-there.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/windows8-cp-almost-there.aspx</link>
      <comments>http://www.jaykimble.net/windows8-cp-almost-there.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/windows8-cp-almost-there.aspx</guid>
      <pubDate>Fri, 02 Mar 2012 13:09:16 GMT</pubDate>
    </item>
    <item>
      <title>Forced Landscape Printing in Silverlight (On a Mac)</title>
      <description><![CDATA[<p>I ran into an issue with the Silverlight5 app I am working on. One of the very important things in this app is the ability to print (in formats other than Letter format in portrait mode). My client uses a Mac and as he was testing the app on his Mac he discovered that the print dialog did not offer Landscape printing to him. After searching quite a bit on the Internet I discovered that low and behold Silverlight (both 4 and 5) don’t really have the best story for Landscape printing on a Mac. In fact if you are using Silverlight to produce printouts, you need to be aware of this fact especially when you know that your printout must be on a Landscape page.</p> <p>The solution is relatively simple (and I discovered the initial technique in this blog post – <a href="http://earok.net/sections/articles/web-dev/easy-landscape-printing-silverlight?page=3%2C8">http://earok.net/sections/articles/web-dev/easy-landscape-printing-silverlight?page=3%2C8</a>)</p> <p>This essentially gives us the ability to print Landscape, but on a PC the user could choose landscape mode. Here’s how I detect it:</p> <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #0000ff">bool</span> rotateContentForLandscape = <span style="color: #0000ff">false</span>;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #0000ff">void</span> doc_PrintPage(<span style="color: #0000ff">object</span> sender, PrintPageEventArgs e)</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">{</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">    rotateContentForLandscape = (e.PrintableArea.Height &gt;= e.PrintableArea.Width);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">    var printedPage = generatePrintContent();</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">&nbsp;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">    <span style="color: #0000ff">if</span> (rotateContentForLandscape)</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">    {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">        var transformGroup = <span style="color: #0000ff">new</span> TransformGroup();</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">        transformGroup.Children.Add(<span style="color: #0000ff">new</span> RotateTransform() { Angle = 90 });</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">        transformGroup.Children.Add(<span style="color: #0000ff">new</span> TranslateTransform() { X = e.PrintableArea.Width });</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">        printedPage.RenderTransform = transformGroup;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">    }</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">    e.PageVisual = printedPage;</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">}</pre><!--CRLF--></div></div>
<p>I use a class level variable <em><strong>rotateContentForLandscape</strong></em>, so in the process of creating content I can detect if there are any weird edge cases where I need to generate something slightly different (I might never really need this). The whole <em>TransformGroup</em> code (inside the <em>If</em>) simply rotates the content and positions it properly on the print page.</p>
<p>That’s all there is to it. Depending on your UI you might not want to detect quite like I’m doing. Your preference might be to have a checkbox in the UI to force landscape and then do the Landscape detection.</p><br /><a href='http://www.jaykimble.net/forced-landscape-printing-in-silverlight-on-a-mac.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/forced-landscape-printing-in-silverlight-on-a-mac.aspx</link>
      <comments>http://www.jaykimble.net/forced-landscape-printing-in-silverlight-on-a-mac.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/forced-landscape-printing-in-silverlight-on-a-mac.aspx</guid>
      <pubDate>Tue, 14 Feb 2012 16:25:02 GMT</pubDate>
    </item>
    <item>
      <title>The WP7/Windows Metro/RT Opportunity!</title>
      <description><![CDATA[<p>I think we’ve all seen the commercial where the kids are playing with their dad who is grocery shopping. The kids update the grocery list with all kinds of sweets. Eventually the dad realizes what is happening and he changes the list to “Do your homework!!” Microsoft is famous for showing stuff like this, and about 2 to 3 versions of VS later it gets available to the masses. In other words, it’s a feature they keep to themselves for a bit and then they give it to the developers. Oftentimes we have already moved on or have built our own solutions to the problem that we are now stuck with (until we refactor our code).</p> <p>This is why I am amazed at what has been announced surrounding SkyDrive, Windows Phone (aka WP7, WP7.5, etc), and the next version of Windows. We are actually getting the ability to make apps like this! Very, very cool! </p> <p><strong>Theme Park Pro – A Scenario</strong><br>I was recently at an Amusement Park and used my buddy’s NeurelNet’s <a href="http://www.windowsphone.com/en-US/apps/3caa74ce-d2e7-4a3b-8970-2ff2495ad77a" target="_blank">Theme Park Pro</a> App. If you are not familiar with the app, it let’s you scope out a bunch of Amusement parks (like Walt Disney World, Busch Gardens in Tampa, and Universal Studios Parks in Florida – just to name a couple). They actually offer badges as you walk around the park letting you check in at the Roller Coasters and other rides. As I was using the app that day I started thinking about a few changes I was going to suggest to the guys. </p> <p>As the went on I realized that there were a couple things bugging me. I’m getting older (but still in my early 40s), so there are few roller coasters I ‘m not really interested in riding (mainly because I am not the daredevil I once was). I started realizing that what I wish I could have done was customized my trip to show those things that I wanted to do on my trip. Of course I really didn’t want to do this on my phone.. I wanted to do this on something like my tablet or my laptop.. I wanted to be able to customize my experience in Theme Park Pro and have it reflected when I grabbed my phone. </p> <p><strong>The Opportunity!</strong><br>As I was thinking how to send this idea to my NeurelNet buddies I realized what an opportunity we all have (those of us who develop for Windows Phone –or other Mobile Platforms, really). We can make Phone Apps that absolutely rock and that combine the experiences of the PC and the Phone. I watched the demos at BUILD, but the reality is hitting me now.. I think there is a huge financial opportunity for us all again!</p><br /><a href='http://www.jaykimble.net/the-wp7windows-metrort-opportunity.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/the-wp7windows-metrort-opportunity.aspx</link>
      <comments>http://www.jaykimble.net/the-wp7windows-metrort-opportunity.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/the-wp7windows-metrort-opportunity.aspx</guid>
      <pubDate>Wed, 25 Jan 2012 16:56:27 GMT</pubDate>
    </item>
    <item>
      <title>WinRT Quick Tip #1: Get the Constructor for a Type</title>
      <description><![CDATA[<p>I ran into this on the Win8 Developer’s Preview. I am porting over some Windows Phone Code. This code has a MEF/IOC-Like mechanism that let’s me do discovery on the project. The project itself is a simple App Framework; it has a bunch of content controls, but with the way it is configured you may decide that you don’t want to deploy all these controls, SO I needed to be able to discover controls and create them dynamically (the latter is what this tip is all about).</p> <p>My original code looked like this:</p><pre class="csharpcode">        <span class="kwrd">public</span> UserControl GetAndInitControlFor(<span class="kwrd">string</span> targetType, SectionInfo data) 
        {
            UserControl result = <span class="kwrd">null</span>;
            var typ = (from item <span class="kwrd">in</span> Catalog 
                              <span class="kwrd">where</span> item.Key.Equals(targetType, 
                                                  StringComparison.InvariantCultureIgnoreCase) 
                              select item).FirstOrDefault();

            <span class="kwrd">if</span> (!typ.Equals(<span class="kwrd">null</span>))
            {
                var ctor = typ.Value.GetConstructor(<span class="kwrd">new</span> Type[0]);
                result = ctor.Invoke(<span class="kwrd">new</span> <span class="kwrd">object</span>[0]) <span class="kwrd">as</span> UserControl;
                <span class="kwrd">if</span> (result != <span class="kwrd">null</span> )
                {
                    ((ISUAFContentControl)result).SetData(data);
                }
            }
            <span class="kwrd">return</span> result;
        }
</pre>
<style type="text/css">.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; }
</style>

<p>&nbsp;</p>
<p>This particular function looks up a control by it’s content type (a string) in the Dictionary that I have already built. If it finds a match then it takes the type instantiates it via the type’s constructor (essentially doing a “new” on the class). The only problem is that WinRT’s type doesn’t have a way to get the constructor. Instead there is a different mechanism you have to use.</p>
<h2>Enter TypeInfo</h2>
<p>I did some BINGing and I found the answer. There is a mechanism called TypeInfo. It’s apart of System.Reflection, so you will have to add a “Using System.Reflectiomn;” to the top of your file. Now you can get TypeInfo for you class. Here’s the rewritten function for WinRT:</p><pre class="csharpcode">        <span class="kwrd">public</span> UserControl GetAndInitControlFor(<span class="kwrd">string</span> targetType, SectionInfo data) 
        {
            UserControl result = <span class="kwrd">null</span>;
            var typ = (from item <span class="kwrd">in</span> Catalog 
                             <span class="kwrd">where</span> item.Key.Equals(targetType, 
                                           StringComparison.OrdinalIgnoreCase)
                             select item).FirstOrDefault();

            <span class="kwrd">if</span> (!typ.Equals(<span class="kwrd">null</span>))
            {
                TypeInfo typeInfo = typ.Value.GetTypeInfo();
                var ctor = typeInfo.DeclaredConstructors
                                    .Where(c=&gt;c.GetParameters().Count() == 0)
                                    .Select(c=&gt;c).FirstOrDefault();
                result = ctor.Invoke(<span class="kwrd">new</span> <span class="kwrd">object</span>[0]) <span class="kwrd">as</span> UserControl;
                <span class="kwrd">if</span> (result != <span class="kwrd">null</span> )
                {
                    ((ISUAFContentControl)result).SetData(data);
                }
            }
            <span class="kwrd">return</span> result;
        }</pre>
<style type="text/css">.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; }
</style>

<p>It’s very similar, but about midway down you can see where I create a TypeInfo for the type, and then using that type I have to write a Linq query to pull out the paramerless constructor that I am going to use to new up an instance. </p>
<p>I didn’t like having to change things, but I do like the new mechanism a lot better. These things should have been properties all along.</p><br /><a href='http://www.jaykimble.net/winrt-quick-tip-1-get-the-constructor-for-a-type.aspx'>Jay Kimble</a>]]></description>
      <link>http://www.jaykimble.net/winrt-quick-tip-1-get-the-constructor-for-a-type.aspx</link>
      <comments>http://www.jaykimble.net/winrt-quick-tip-1-get-the-constructor-for-a-type.aspx</comments>
      <guid isPermaLink="true">http://www.jaykimble.net/winrt-quick-tip-1-get-the-constructor-for-a-type.aspx</guid>
      <pubDate>Thu, 19 Jan 2012 16:57:52 GMT</pubDate>
    </item>
  </channel>
</rss>