Conditional Logic During Start Up of a Windows Phone App

October 18 2010

Just managed to get myself into (and out of) a gnarly situation with Windows Phone. Here’s the scenario: I needed to execute some conditional logic to show different screens at start up in my Windows Phone app.  Basically, if the user was already logged in, bounce them to homepage; otherwise send them to the log in screen.

My first stab was to check for if they were logged in during the log-in screen and redirect them. Bad UX with that though: you can’t navigate until the NavigationService is available, which isn’t until the UI is loaded, which means the user briefly sees the login screen. Ugly.

Second stab was to add a page that simply displayed the splashscreen.jpg in which the conditional logic was executed.  So, I had a page with nothing but a splashscreen and then, in the OnNavigatedTo event, I checked to see if they were logged in.  Seemed to be working, until I discovered that the user could never navigate backward out of the app, because whenever they hit that page, the app attempted to navigated them forward. Lesson learned? Don’t add navigation logic to the OnNavigatedTo event or else backward navigation is hosed.

I then discovered Peter Torr’s excellent framework for redirecting an initial navigation.  I implemented this, which puts all this logic in the Navigating event of the application class. That solved my navigation problem, but introduced a new problem: because my application uses the Share Picker extensibility for Windows Phone, I needed access to the NavigationContext querystrings, provided by the static method that hangs off of the PhoneApplicationPage object. For the life of me, I couldn’t figure out how to access this class, since all you can get at is the PhoneApplicationFrame when in the application class.  But, then I learned that NavigationContext is just a wrapper around the URI and I could simply get the URI out of the NavigatingCancelEventArgs as e.Uri and process the querystrings myself.

Oh, one other thing to remember when messing around in the Navigating event: be sure to set e.Cancel to true or else your overridden navigation won’t ever happen.

AI->Canvas: Generating HTML5 canvas code from Adobe Illustrator

October 13 2010

Mike Swanson is the man when it comes to getting artwork out of Adobe Illustrator and into a format usable by the browser. His first go at this was the AI->XAML plug-in, a widely used plug-in by graphic designers building assets for WPF and Silverlight projects. Well, now he’s back with another plug-in, this time for the HTML5 <canvas> tag. It’s called (not surprisingly) AI->Canvas. Same idea, but even better, because he’s taken this one to the next level. Not only will he export the asset; he also has all these clever little macros that enable transformation and animation of the asset. Super sweet. There’s tons of great tutorials and documentation up at Mix Online on how to use it, so don’t be intimidated.

Oh, and a shout out to @Systim, who built all the lab pages for the AI->Canvas lab on Mix Online. View source and you’ll see all HTML5. Rad!

Windows Phone 7 XAML Design Templates

October 4 2010

Just got turned on to the Windows Phone 7 XAML Design Templates.  These are essential.  The Blend team have done the hard work to figure out all the common layout scenarios and provide templates for usage.  This makes doing layout for Windows Phone 7 apps brain dead easy. Love it.  Here’s a pic to give you a sense; video below.


Get Microsoft Silverlight

iPhone and iTouch Support For BlogEngine.NET

September 30 2010

BlogEngine.NET does a great job with mobile devices, rendering its content with a default skin whenever it detects a mobile device. Unfortunately, this behavior doesn’t work on the iPhone or iTouch. However, the fix is easy. Simply add iphone and ipod to the BlogEngine.MobileDevices key in web.config, as follows:

<add key="BlogEngine.MobileDevices" value="(iphone|ipod|nokia|sonyericsson|blackberry|samsung|sec\-|windows ce|motorola|mot\-|up.b|midp\-)"/>

Once you’ve done this, the default mobile theme will render on the iPhone and iTouch.

If you are looking for even a prettier theme   I also found the BETouch iPhone theme, which looks great. Simply add the theme to the themes directory and then change the mobile theme to BETouch in admin settings.

I’m now using it for this blog!


Windows Phone Developer Tools Hiccup, Links

September 20 2010

Installed the Windows Phone Developer Tools. Then tried to run the emulator and it failed with “Error: Connection failed because of invalid command-line arguments.” The solution? (1) Reboot. (2) Run as administrator.

Also been reading Creating High Performing Silverlight Applications for Windows Phone. Awesome content. Tons of ideas and information. Essential reading.

Lastly, just starting to dive into the Microsoft Advertising SDK for Windows Phone 7. Documentation is on the web here.  Could be promising.

Screencast On Creating jQuery Animations Without Code

August 12 2010

Check out this post by my designer colleage, Tim Aidlin, on how to use Glimmer to create jQuery animations, in this case the hero graphic up at Here's the screencast itself:


Oomph artwork
You need Silverlight to view this video. It’s fast, it’s free and it’s awesome. Click here to get it.

Windows Phone 7 Development Tip: Discovering and Using Default Styles

August 10 2010

I was playing around with the Windows Phone 7 tools and noticed that there are some system styles available for text.  For example, I noticed the following XAML that referenced PhoneTextTitle1Style in one of the Visual Studio project templates:

            <TextBlock x:Name="ListTitle" Text="{Binding LineOne}" Margin="-3,-8,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>

I then wanted to figure out what all the system styles were.  How to do it? Expression Blend!  By going to the Assets tab and then clicking Styles --> System Styles, I was able to see all the styles:


I then wanted to see what they looked like, so I double clicked each one, which created a textbox. To correlate the look with the name, I replaced the default text with the name of the style, producing this:


Perhaps this graphic/tip will help someone out there!

Getting Request.Form Data Out of XDomainRequest In ASP.NET

July 12 2010

I am using the XDomainRequest object in IE8 and IE9 to do cross domain posting.  However, I hit an issue where I couldn't seem to get at the data I was posting: the Request.Form collection contained nothing yet I was clearly sending it. I then found this post:

which states: "we restricted the content type to text/plain but didn’t allow the caller to specify that the data was in application/x-www-urlencoded form. This is problematic because server-side frameworks (e.g. ASP, ASPNET, etc) will only automatically parse a request’s fields into name-value pairs if the x-www-urlencoded content type is specified.

To workaround this issue, server code that currently processes HTML Forms must be rewritten to manually parse the request body into name-value pairs when receiving requests from XDomainRequest objects. This makes adding support for the XDomainRequest object more difficult than it would be otherwise."

Okay, so how does one do that? Well, turned to be pretty simple. I just had to access the Request.InputStream directly, as follows:

           //set the header to support XDomainRequest

           Response.Headers.Add("Access-Control-Allow-Origin", "*");

           //now extract the data out of the stream

           System.IO.Stream str;

           String jsonContents;

           Int32 counter, strLen, strRead;

           // Create a Stream object.

           str = Request.InputStream;

           // Find number of bytes in stream.

           strLen = Convert.ToInt32(str.Length);

           // Create a byte array.

           byte[] byteArray = new byte[strLen];

           // Read stream into byte array.

           strRead = str.Read(byteArray, 0, strLen);

           // Convert byte array to a text string.

           jsonContents = Encoding.UTF8.GetString(byteArray);

Serializing Request.ServerVariables to JSON: JavaScriptSerializer vs. DataContractJsonSerializer

July 7 2010

I needed to serialize Request.ServerVariables to JSON.  I tried both  JavaScriptSerializer nor DataContractJsonSerializer without any luck.  But I thought both would work, as Request.ServerVariables is of type NameValueCollection and the docs on MSDN state that both serialization engines support dictionaries. The solution? Convert (manually) the NameValueCollection into a dictionary.

Here's the code:

            Dictionary<string,string> d = new Dictionary<string,string>();
            foreach (string s in Request.ServerVariables.AllKeys)
                d.Add(s, Request.ServerVariables[s]);
            DataContractJsonSerializer serverVariablesSerializer = new DataContractJsonSerializer(typeof(Dictionary<string,string>));
            MemoryStream ms = new MemoryStream();
            serverVariablesSerializer.WriteObject(ms, d);
            string json = Encoding.Default.GetString(ms.ToArray());
            JavaScriptSerializer serverVariablesSerializer2 = new JavaScriptSerializer();
            string json2 = serverVariablesSerializer2.Serialize(d);

What's interesting is that the output is different between the two serialization engines. JavaScriptSerializer is smart enough to turn the key into the key in JSON, whereas DataContractJsonSerializer creates a key called "key" with the value of the key and then a key called "value" with the value of the value. Kind of annoying. The winner? JavaScriptSerializer

Here's the output BTW:

DataContractJsonSerializer: [{"Key":"ALL_HTTP","Value":"HTTP_CONNECTION:Keep-Alive\u000d\u000aHTTP_ACCEPT:*\/*\u000d\u000aHTTP_ACCEPT_ENCODING:gzip, deflate\u000d\u000aHTTP_ACCEPT_LANGUAGE:en-us\u000d\u000aHTTP_COOKIE:comment=name=b&; WT_FPC=id=\u000d\u000aHTTP_HOST:localhost:4135\u000d\u000aHTTP_USER_AGENT:Mozilla\/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident\/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; MS-RTC LM 8; .NET4.0C; .NET4.0E)\u000d\u000a"},{"Key":"ALL_RAW","Value":"Connection: Keep-Alive\u000d\u000aAccept: *\/*\u000d\u000aAccept-Encoding: gzip, deflate\u000d\u000aAccept-Language: en-us\u000d\u000aCookie: comment=name=b&; WT_FPC=id=\u000d\u000aHost: localhost:4135\u000d\u000aUser-Agent: Mozilla\/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident\/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; MS-RTC LM 8; .NET4.0C; .NET4.0E)\u000d\u000a"},{"Key":"APPL_MD_PATH","Value":""},{"Key":"APPL_PHYSICAL_PATH","Value":"C:\\stuff\\WebApplication1\\WebApplication1\\"},{"Key":"AUTH_TYPE","Value":"NTLM"},{"Key":"AUTH_USER","Value":"REDMOND\\karstenj"},{"Key":"AUTH_PASSWORD","Value":""},{"Key":"LOGON_USER","Value":"REDMOND\\karstenj"},{"Key":"REMOTE_USER","Value":"REDMOND\\karstenj"},{"Key":"CERT_COOKIE","Value":""},{"Key":"CERT_FLAGS","Value":""},{"Key":"CERT_ISSUER","Value":""},{"Key":"CERT_KEYSIZE","Value":""},{"Key":"CERT_SECRETKEYSIZE","Value":""},{"Key":"CERT_SERIALNUMBER","Value":""},{"Key":"CERT_SERVER_ISSUER","Value":""},{"Key":"CERT_SERVER_SUBJECT","Value":""},{"Key":"CERT_SUBJECT","Value":""},{"Key":"CONTENT_LENGTH","Value":"0"},{"Key":"CONTENT_TYPE","Value":""},{"Key":"GATEWAY_INTERFACE","Value":""},{"Key":"HTTPS","Value":""},{"Key":"HTTPS_KEYSIZE","Value":""},{"Key":"HTTPS_SECRETKEYSIZE","Value":""},{"Key":"HTTPS_SERVER_ISSUER","Value":""},{"Key":"HTTPS_SERVER_SUBJECT","Value":""},{"Key":"INSTANCE_ID","Value":""},{"Key":"INSTANCE_META_PATH","Value":""},{"Key":"LOCAL_ADDR","Value":""},{"Key":"PATH_INFO","Value":"\/Default.aspx"},{"Key":"PATH_TRANSLATED","Value":"C:\\stuff\\WebApplication1\\WebApplication1\\Default.aspx"},{"Key":"QUERY_STRING","Value":""},{"Key":"REMOTE_ADDR","Value":""},{"Key":"REMOTE_HOST","Value":""},{"Key":"REMOTE_PORT","Value":""},{"Key":"REQUEST_METHOD","Value":"GET"},{"Key":"SCRIPT_NAME","Value":"\/Default.aspx"},{"Key":"SERVER_NAME","Value":"localhost"},{"Key":"SERVER_PORT","Value":"4135"},{"Key":"SERVER_PORT_SECURE","Value":"0"},{"Key":"SERVER_PROTOCOL","Value":"HTTP\/1.1"},{"Key":"SERVER_SOFTWARE","Value":""},{"Key":"URL","Value":"\/Default.aspx"},{"Key":"HTTP_CONNECTION","Value":"Keep-Alive"},{"Key":"HTTP_ACCEPT","Value":"*\/*"},{"Key":"HTTP_ACCEPT_ENCODING","Value":"gzip, deflate"},{"Key":"HTTP_ACCEPT_LANGUAGE","Value":"en-us"},{"Key":"HTTP_COOKIE","Value":"comment=name=b&; WT_FPC=id="},{"Key":"HTTP_HOST","Value":"localhost:4135"},{"Key":"HTTP_USER_AGENT","Value":"Mozilla\/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident\/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; MS-RTC LM 8; .NET4.0C; .NET4.0E)"}]

JavaScriptSerializer: {"ALL_HTTP":"HTTP_CONNECTION:Keep-Alive\r\nHTTP_ACCEPT:*/*\r\nHTTP_ACCEPT_ENCODING:gzip, deflate\r\nHTTP_ACCEPT_LANGUAGE:en-us\r\nHTTP_COOKIE:comment=name=b&; WT_FPC=id=\r\nHTTP_HOST:localhost:4135\r\nHTTP_USER_AGENT:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; MS-RTC LM 8; .NET4.0C; .NET4.0E)\r\n","ALL_RAW":"Connection: Keep-Alive\r\nAccept: */*\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: en-us\r\nCookie: comment=name=b&; WT_FPC=id=\r\nHost: localhost:4135\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; MS-RTC LM 8; .NET4.0C; .NET4.0E)\r\n","APPL_MD_PATH":"","APPL_PHYSICAL_PATH":"C:\\stuff\\WebApplication1\\WebApplication1\\","AUTH_TYPE":"NTLM","AUTH_USER":"REDMOND\\karstenj","AUTH_PASSWORD":"","LOGON_USER":"REDMOND\\karstenj","REMOTE_USER":"REDMOND\\karstenj","CERT_COOKIE":"","CERT_FLAGS":"","CERT_ISSUER":"","CERT_KEYSIZE":"","CERT_SECRETKEYSIZE":"","CERT_SERIALNUMBER":"","CERT_SERVER_ISSUER":"","CERT_SERVER_SUBJECT":"","CERT_SUBJECT":"","CONTENT_LENGTH":"0","CONTENT_TYPE":"","GATEWAY_INTERFACE":"","HTTPS":"","HTTPS_KEYSIZE":"","HTTPS_SECRETKEYSIZE":"","HTTPS_SERVER_ISSUER":"","HTTPS_SERVER_SUBJECT":"","INSTANCE_ID":"","INSTANCE_META_PATH":"","LOCAL_ADDR":"","PATH_INFO":"/Default.aspx","PATH_TRANSLATED":"C:\\stuff\\WebApplication1\\WebApplication1\\Default.aspx","QUERY_STRING":"","REMOTE_ADDR":"","REMOTE_HOST":"","REMOTE_PORT":"","REQUEST_METHOD":"GET","SCRIPT_NAME":"/Default.aspx","SERVER_NAME":"localhost","SERVER_PORT":"4135","SERVER_PORT_SECURE":"0","SERVER_PROTOCOL":"HTTP/1.1","SERVER_SOFTWARE":"","URL":"/Default.aspx","HTTP_CONNECTION":"Keep-Alive","HTTP_ACCEPT":"*/*","HTTP_ACCEPT_ENCODING":"gzip, deflate","HTTP_ACCEPT_LANGUAGE":"en-us","HTTP_COOKIE":"comment=name=b&; WT_FPC=id=","HTTP_HOST":"localhost:4135","HTTP_USER_AGENT":"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; MS-RTC LM 8; .NET4.0C; .NET4.0E)"}

Using Stringify With the New window.msPerformance in Internet Explorer 9

July 6 2010

I've been playing with the new window.msPerformance that's part of IE9 as explained in this blog post: Of course, the main thing you want to do is capture this data. The blog post mentions that you can use the stringify method to serialize the object to JSON and then send the diagnostics back to the server.  Well, I tried this with no luck. Here's what my code looked like:

   <script type="text/javascript" >
        function test() {
            if (window.msPerformance != null) {

                var json = JSON.stringify(window.msPerformance.timing);

Even though the performance object was populated, the serialization to JSON failed.

I did some digging around and learned that the native JSON method in IE9 doesn't successfully stringify native objects, like anything hanging off window or document.  However, I was able to work around this by using Crockford's JSON class from here:  The one thing I had to do was to change the prototype to JSON2 so that the browser's native JSON prototype wasn't called. Then it worked!

Visual Studio Achievements
Karsten Januszewski (207 Points)