Introducing: PhoneCompare for Windows Phone 7

I’ve built a new Windows Phone App that lets you compare 2 Windows Phone devices with all available specs right next to each other to see which is the best. You can also just check the specifications of one of the available windows phones at this moment when you are in a heated argument with friends or colleagues again where you are not sure if that phone had a 1.4GHZ processor or a 1.5 GHZ processor.

My new app is called PhoneCompare and is available in all Windows Phone Marketplaces for 99 cents. you can also install a free trial that has 100% of the functionality but shows ads.

PhoneCompare has the following features:

  • List all available Windows Phones
  • Check specifications for a single phone to see its screen size, dimensions, weight, processor, storage, memory, battery and camera.
  • Select 2 phones to compare all these specs next to each other
  • Check the specs of your current phone
  • Browse phones by brand
  • View a list of new phones that are just released or are about to get released

My plans for the future are to also make it possible to rate phones so you can see which phones are rated the highest and I also want to store most used phones by visitors of the app. All this in version 1.1 :)

  

  

 

If you have any feedback on this app please let me know by a comment on this post, by sending me a tweet @geertvdc or by rating or using the in app mail function

Enjoy!

Geert van der Cruijsen

Share on Facebook
Kick It on DotNetKicks.com
Shout it
Post on Twitter

Windows Phone 7 Emulator Skin Switcher 1.0 Beta

In the last few weeks several people started creating their own skins for the Windows Phone 7 Emulator. Switching between different skins was a lot of work by copying files manually to the emulator directory every time you wanted to switch. From now on this is not needed anymore because you can use the Windows Phone 7 Emulator Skin Switcher application I’ve created.

wp7EmulatorSkinSwitcher

You can download the application here: Download

Update! version 1.2 is released and the project is moved to codeplex. you can find the newest version here: http://wp7emuskinswitcher.codeplex.com/

This version is the first beta release with my first set of skins. I added 2 skins from Georg Kalus: the Blue Nokia Lumia 800 and the White/Pink Nokia Lumia 710. I’ve also included the Black Nokia Lumia 800 skin from Pedro Lamas

The complete list of skins included in the application now are:

I’m planning on adding more skins in the near future but didn’t have time for it yet. If you have skins I can use please let me know by comment or on twitter

lumia710whitelumia800pinklumia710black

 

Hopefully this will make your Windows Phone 7 projects even more fun to test!

Happy Coding

Geert van der Cruijsen

Share on Facebook
Kick It on DotNetKicks.com
Shout it
Post on Twitter

Started a new Codeplex project: Windows Phone Silverlight Toolkit Behavior Extensions

Of all windows phone development that is done in the world I think almost everyone is using the Windows Phone Silverlight Toolkit you can get from Codeplex. This toolkit adds a lot of new controls and also other cool features as page transitions and a tilt effect on usercontrols so users will get more feedback when clicking in the UI.

This week I started working on a new project with a designer and he asked me how to insert the page transitions on a windows phone application page and I showed him that you’ll have to add a piece of XAML to your code and the page transitions will work. He asked me “Can’t I do this in the designer mode without touching any code?” I didn’t have any right answer for him so that’s why I’ve spend part of my weekend to build some behaviors that can be used to drag this functionality on pages in Expression Blend.

There are behaviors for every type of transition available in the silverlight toolkit. for each transitiontype there is an “in” and “out” behavior for entering and leaving the page. Besides the transition behaviors I’ve also created a behavior to turn the tilteffect on or off

  • EnableTiltEffectBehavior
  • SuppressTiltBehavior
  • TransitionRollInBehavior
  • TransitionRollOutBehavior
  • TransitionRotateInBehavior
  • TransitionRotateOutBehavior
  • TransitionSlideInBehavior
  • TransitionSlideOutBehavior
  • TransitionSwivelInBehavior
  • TransitionSwivelOutBehavior
  • TransitionTurnstileInBehavior
  • TransitionTurnstileOutBehavior

You can download the behaviors here: (important: you also need the silverlight toolkit for this to work)

http://phonetoolkitbehavior.codeplex.com/

On the codeplex site you’ll find a msi release containing the dll that you can include in your project to use these behaviors and I’ve also included a sample application. I’ll also upload the sample application to the marketplace so you can easily test out the performance etc without any trouble.

For a compete tutorial check this blogpost.

This is currently the first release so every feedback is welcome. please let me know by adding a comment here or contact me on twitter

Geert van der Cruijsen

Share on Facebook
Kick It on DotNetKicks.com
Shout it
Post on Twitter

New blog template

I got a bit bored with my old blog template so I finally switched to a new one that fitted me better. This new template is better readable and clean and I like the orange color that fits with my employer Avanade. The top picture is inspired by my work and passion for Windows Phone so that’s why I’ve chosen an Image of a Metro line. Winking smile

If you like my template it’s a free template for WordPress called “Twenty Eleven 1.2” and you can just download it from the template gallery in WordPress.

Enjoy!

Share on Facebook
Kick It on DotNetKicks.com
Shout it
Post on Twitter

PinPin 1.2 update now available in the WP7 Marketplace

First note I want to make: The “Error retrieving ATM locations” bug is fixed in this release!

Here is the story on how it all went down:

Since PinPin’s launch last week I’ve been loaded with feedback from people, most of them were positive but there was also a large group of people who weren’t able to get ATM locations. At first I didn’t have any idea how this was possible since I had tested at many locations in the Netherlands and had asked several colleagues to test the app and it worked for everyone.

Luckily  lots of people were able to find the feedback form in my app and when I received a mail from Marco who had a dev unlocked phone and was receiving the errors I found my chance to find out what was causing the bug. I made a version 1.1 and submitted it to the marketplace (that wasn’t smart because that’s why it took so long to get 1.2 out) but also mailed it to Marco so he could test. 1.1 had the option to save the errors and send a mail with the Error messages and a stacktrace so I could see what was going wrong.

With the error report I received from Marco I could see it was something in the response from the webservice I’m calling to get the ATM data but still couldn’t see what the error was exactly. I again added more logging to the app and asked Marco to test again. This time I could compare my request and response from the server to his and then I found out: The Dutch regional settings were screwing things up. Ofcourse this is a major concern for an app that is only used in the Netherlands Smile

I fixed the bug but had to wait untill version 1.1 had passed certification before I could submit 1.2 Wednesday night 1.1 was approved and I immediately submitted 1.2. Today I received another mail from Microsoft that 1.2 also passed certification. From now on everyone should be able to use PinPin!

If you find any bug in version 1.2 please let me know and I’ll try to fix it asap again.

It can take a while before you’ll get the 1.2 update notification from your phone but you could also manually uninstall your current PinPin installation and reinstall from the marketplace you’ll download version 1.2.

Big thanks to Marco and everyone else who has send feedback concerning this bug. Hopefully you can enjoy PinPin now and if you do don’t try to rate and review the app, it only takes a few seconds!

 

1_thumb 2_thumb 4_thumb2

Oh and if you didn’t have PinPin yet, you can download it here:

Download PinPin for WP7

 

Geert van der Cruijsen

Share on Facebook
Kick It on DotNetKicks.com
Shout it
Post on Twitter

Introducing: PinPin for Windows Phone 7

I’m proud to announce my 2nd Windows Phone 7 application available in the marketplace. The new app is called PinPin and is an app to locate an ATM near your location. The app is really simple at this first release, just open the app and the app will retrieve ATM location information near your GPS location.

At this moment PinPin only works if you are located in the Netherlands because there is no worldwide ATM location data available. I’m still looking for this data so if someone knows where to get this please let me know.

PinPin Logo

Below are some screenshots of the application:

1 2 3
4 5 6
7 8

PinPin is available for FREE in the Windows Phone marketplace. download it by clicking the button below:

Download PinPin for WP7

Special Thanks to Christiaan Veeningen for telling me to build this app :)

If like or dislike the app please let me know by rating the app or by submitting a review. You can also contact me through twitter @geertvdc or leave a comment here on my blog.

This is currently the first release of PinPin. I have more plans for the app in the future, here is a roadmap of what to come:

  • Add Dutch language
  • Get Directions (Will have to wait for Mango)
  • Add more Bank logo’s
  • Add more countries
  • Review Comments I get from you!

Hopefully you’ll enjoy this new app!

Geert van der Cruijsen

Share on Facebook
Kick It on DotNetKicks.com
Shout it
Post on Twitter

Using the WP7 system color in live tiles and application icon

I’m currently building my first WP7 application for a contest that is held by Avanade Netherlands for all its employees. Who can create the best app in a small amount of time.

My app is almost finished and I was trying to set up the live tile and application icon. Of course I wanted to use the system color which the user has selected to display on the background of my live tile. How to do this? here is how, it is actually quite simple.

when you open your solution you’ll automatically get your background.png and applicationicon.png. both icons have a black/greyish background. like shown in the example below.

livetile1

to switch the background to use the system color follow the following steps:

  • Open up your background.png in any decent image editing tool like Paint.net.
  • Use the magic marker to select the background

live tile selected

  • press delete so you get a transparent background

 

live tile deleted

  • save the icon back to your visual studio solution.
  • compile
  • enjoy!

 

livetile2livetile3

 

Ofcourse the next step would be to do the same for your application icon (the icon in the application list).

I tried it and it didn’t work… after some research I found out that this is for Microsoft and official partners only.. Bummer!!

 

Guess we are going to be stuck by using greyish application icons after all.. hopefully Microsoft will fix this in the future.

 

Hopefully this post was helpful to you. In my opinion there are to few good resources to be found on WP7 development so every small thing helps.

Geert van der Cruijsen

Share on Facebook
Kick It on DotNetKicks.com
Shout it
Post on Twitter

Creating an MVC based website with reusable widgets

After the Asp.net MVC Framework was released i was pretty impressed of how it worked but one of my main problems was how to handle the data on the page that is not the main goal of the specific page.

In ASP.NET MVC every page has its specific controller and views that can handle the data for the page that is requested. for example when you’re building a web shop you’ll probably have a ProductController that handles everything that has to do with the Products in your shop. But when you are browsing a web shop product page you would also like to see other data that has nothing to do with products, for example your shopping basket, current login state etc. Should you add this logic to the ProductController? imo you shouldn’t since the Products controller only responsibility should be the products. So how should we handle this in the MVC framework?

My first idea that came to mind to solve this problem was doing an Ajax request to for example, the shopping basket controller on your view when you would like a shopping basket added to your page. This can be in some situations the best way to do it but in some cases you might not want to use Ajax since then this content can’t be indexed by search engines for example.

An example how to use Ajax widgets is found here: http://www.ajaxprojects.com/ajax/tutorialdetails.php?itemid=310

My main goal was to be able to add widgets to a page without the controller of that page knowing about these widgets. I found some solutions to this called partial requests found here: http://blog.codeville.net/2008/10/14/partial-requests-in-aspnet-mvc/

These partial requests weren’t my favorites also since i didn’t want to put this logic in the view so i developed my own CMS like solution for this problem.

My idea was that a page can have several page zones and page zones contain widgets. widgets and complete page zones should be reusable by other pages so i stored these in my CMS database. how my database is build up you can see in the image below

image

A widget should be able to render itself so i made an abstract BaseWidget class that has a Render Method. A widget can also be a call to a different controller so i made a SubController class that inherits from BaseWidget. The SubController Widget has an Controller, Action and ID so it can call the controller it belongs to.

   1: public abstract class SubControllerWidget : BaseWidget

   2: {

   3:     public string Controller { get;  set; }

   4:     public string Action { get;  set; }

   5:     public object ID { get; set; }

   6: 

   7:     public SubControllerWidget(string Controller, string Action) : base()

   8:     {

   9:         this.Controller = Controller;

  10:         this.Action = Action;

  11:         this.ID = null;

  12:     }

  13: 

  14:     public SubControllerWidget(string Controller, string Action, object ID)

  15:         : base()

  16:     {

  17:         this.Controller = Controller;

  18:         this.Action = Action;

  19:         this.ID = ID;

  20:     }

  21: 

  22:     public override void Render(System.Web.Mvc.ViewContext vc)

  23:     {

  24:         vc.RouteData.Values["controller"] = Controller;

  25:         vc.RouteData.Values["action"] = Action;

  26:         vc.RouteData.Values["id"] = ID;

  27:         IHttpHandler handler = new MvcHandler(vc.RequestContext);

  28:         handler.ProcessRequest(System.Web.HttpContext.Current);

  29:     }

  30: 

  31:     public abstract void SetSettings(WidgetSettings settings);

  32: }

To build a specific widget just inherit a widget from SubControllerWidget and you are ready to go. Set the Controller, Action and ID to call and that specific controller will be called.

To add these page zones and widgets to the pages dynamically i’ve created a CMSController that overrides the OnActionExecuted method so it can insert the page zones and widgets to the model that’s been send to the View.

   1: protected override void OnActionExecuted(ActionExecutedContext filterContext)

   2: {

   3:     if (ViewData.Model == null)

   4:     {

   5:         ViewData.Model = new CMSViewModel();

   6:     }

   7:     string controller = filterContext.RequestContext.RouteData.Values["controller"] != null ? filterContext.RequestContext.RouteData.Values["controller"].ToString() : "";

   8:     string controllerAction = filterContext.RequestContext.RouteData.Values["action"] != null ? filterContext.RequestContext.RouteData.Values["action"].ToString() : "";

   9:     string controllerActionid = filterContext.RequestContext.RouteData.Values["id"] != null ? filterContext.RequestContext.RouteData.Values["id"].ToString() : "";

  10:     IList<PageZone> zones = _cmsRep.GetPageZonesForPage(controller, controllerAction, controllerActionid);

  11: 

  12:     CMSViewModel page = (CMSViewModel)ViewData.Model;

  13:     if (page.PageZones == null)

  14:     {

  15:         page.PageZones = zones;

  16:     }

  17:     else

  18:     {

  19:         foreach (PageZone zone in zones)

  20:         {

  21:             page.PageZones.Add(zone);

  22:         }

  23:     }

  24: 

  25: 

  26:     base.OnActionExecuted(filterContext);

  27: }

 

So now all widgets beloning to a page will be retrieved from the CMSRepository and are added to the CMSViewModel so now it’s the View’s turn to render all widgets.

In my master page I’ve added the following line that is responsible for rendering all widgets:

<% Html.RenderPageZones(Model); %>

For that to work I’ve created a few html extension methods to render the page zones.

   1: public static class HtmlCMSExtensions

   2: {

   3:     public static void RenderPageZones(this HtmlHelper html, CMSViewModel page)

   4:     {

   5:         if (page != null && page.PageZones != null)

   6:         {

   7:             foreach (PageZone zone in page.PageZones)

   8:             {

   9:                 html.RenderPartial("PageZone", zone);

  10:             }

  11:         }

  12:     }

  13: 

  14:     public static void RenderWidgetsInZone(this HtmlHelper html, PageZone zone)

  15:     {

  16:         if (zone != null && zone.Widgets != null)

  17:         {

  18:             foreach (IWidget widget in zone.Widgets)

  19:             {

  20:                 widget.Render(html.ViewContext);

  21:             }

  22:         }

  23:     }

  24: }

In my PageZone view i’ve added the other html extension method called RenderWidgetsInZone so all widgets are rendered by itself.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<VanDerCruijsen.MVC.CMS.Model.PageZone>" %>

<div id="<%= Html.Encode(Model.Name) %>">

name:<%
   1: = Html.Encode(Model.Name)

%>

<%
   1:  Html.RenderWidgetsInZone(Model);

%>

</div>

This is the way I use to create widgets on my ASP.NET MVC pages. If you have any recommendations or better ways how to do it please let me know.

When I have the time I’m going to build an admin controller to be able to add widgets and pagezones via the webinterface since now the only option is to add them in the database by hand.

My sources aren’t really cleaned up so if you want a working source/solution please send me mail or leave a comment.

Geert van der Cruijsen

Share on Facebook
Kick It on DotNetKicks.com
Shout it
Post on Twitter

Last.Fm Radio Stream Player Gadget 0.5 Released!

Update 08-06-2010: the last.fm gadget does not work anymore. Last.fm changed their client server protocols and therefore the gadget is not working anymore. I’m not using Last.fm anymore so i’m not planning on updating the gadget in the future

 

 

Last week my mailbox was flooded by mails of people who were telling me my Windows Vista Sidebar gadget to play Last.fm radio was broken.

I tested it myself and concluded that this was indeed the case. Last.fm changed their website last week and my guess is that they also changed their streaming service.

After a full night of debugging I found out what was the problem and I fixed it in a new version which can be now downloaded from the download area.

If you are interested in what was changed read on. The change was fairly simple, the protocol uses 2 handshakes to connect to the service. The first handshake is to connect to the scrobbling service. The second handshake is used to connect to the streaming service. Before last week requesting the mp3 stream was done by sending the sessionid of the first handshake. Now… it seems you have to send the sessionid you get with the second handshake. It took some time to figure this out but now everything seems to work fine again.

Protocol example:

Handshake 1 request:

http://ws.audioscrobbler.com/radio/handshake.php?version=1.4.2.58376&platform=win32&platformversion=Windows%20Vista&username=geertvdcruijsen&passwordmd5=
4d9309866b98863c3c3336e50392831b&language=en&player=winamp

Handshake 1 response from last.fm:

session=bbe5e763d1e1deb988595cecf1c21e9d stream_url=http://87.117.229.85:80/last.mp3?Session=bbe5e763d1e1deb988595cecf1c21e9d subscriber=0 framehack=0base_url=ws.audioscrobbler.com base_path=/radio info_message= fingerprint_upload_url=http://ws.audioscrobbler.com/fingerprint/upload.php permit_bootstrap=0

Handshake 2 request:

http://post.audioscrobbler.com/?hs=true&p=1.2&c=tst&v=1.3.1.1&u=geertvdcruijsen
&t=1217017120&a=2a060e72c7aae132e8fad06b741be806

Handshake 2 response from last.fm:

OK 7e5b82460d2a45e382b81c437ae6a87a http://post.audioscrobbler.com:80/np_1.2 http://87.117.229.205:80/protocol_1.2

Tune to the right radio channel:

http://ws.audioscrobbler.com/radio/adjust.php?session=bbe5e763d1e1deb988595cecf1c21e9d&url=lastfm://artist/muse

Response to channel change request from last.fm:

response=OK url=lastfm://artist/muse stationname= Muse’s Similar Artists discovery=true

Request metadata of stream:

http://ws.audioscrobbler.com/radio/xspf.php?sk=bbe5e763d1e1deb988595cecf1c21e9d
&discovery=0&desktop=1.3.1.1&time=1217017120321

I was happy to receive the mails of complaints because this is proof people are actually using my gadget :) Hopefully all problems are fixed now so happy listening!

Geert van der Cruijsen

Share on Facebook
Kick It on DotNetKicks.com
Shout it
Post on Twitter

Display Picture Metadata in your Silverlight 2.0 Deepzoom Application

As i promised 2 days ago here’s my post about how to display metadata of sub images in your Silverlight Deepzoom Application. I already typed this post yesterday but because of a stupid mistake i lost my post and now I have to type it again :( (but I think I’ll make it a bit shorter)

To start building your Silverlight 2.0 deepzoom application download Deepzoom Composer from Microsoft here. This tool works quite easy. just add some images in the “import” mode then drag them on your screen in the “compose” mode and then export your deepzoom Project.

If you want to be able to identify the different sub images in your Multiscaleimage object check the “Create Collection” checkbox.

deepzoomComposerCollection

After exporting this will be the result:

deepzoomexport

Now to load up this collection of pictures into your own project take a look at this weblog, there is a really good explanation on which steps to take and after you did all those steps i’ll explain how to show metada of the different subimages in the deepzoom application.

So if you are at this point you should have your own working deepzoom application and you want to add picture metadata to your project. If not go back to this weblog or try one of these.

The only way of identifying the different sub images in the big multiscaleimage is by the Z-Order of the different images. So how do you know which image has what Z-Order you ask? thats where the generated SparseImageSceneGraph.xml comes in which was generated by the Deepzoom Composer.

<SceneNode

  <FileName> P1000558.JPG</FileName

  <x>0,235460826165879</x>

  <y>0,00108692916410255</y

  <Width>0,218281177677285</Width>

  <Height>0,144923888547009</Height

  <ZOrder>2</ZOrder>

  <Description>Uitzicht van hotelkamer</Description>

</SceneNode>

 

As you can see i added my own Description element to every SceneNode in the generated xml so we can use it in our project. We’ll use this xml file to query the ZOrder of the subimage and get the description as a result with the use of Linq.

To do this we’ll first have to open the xml file in our code behind page from the page.xaml.cs.

deepZoomObject.Loaded += delegate(object sender, RoutedEventArgs e)

{

    _xmlImageMetadata = XDocument.Load(“SparseImageSceneGraph.xml”);

};

 

After that we’ll add code to display the metadata when the mouse moves over a sub image in the multiscaleimage.

deepZoomObject.MouseMove += delegate(object sender, MouseEventArgs e)

{

    if (mouseButtonPressed) 

    {

        mouseIsDragging = true

    }

    else 

    {

        ImageName.Text = GetMetadata(e.GetPosition(deepZoomObject)); 

    }

    lastMousePos = e.GetPosition(deepZoomObject);

};

 

Then we add the function GetMetadata which queries the xml file and gets the description from it.

private string GetMetadata(Point point)

{

    Point p = deepZoomObject.ElementToLogicalPoint(point); 

    int subImageIndex = SubImageHitTest(p);

    if (subImageIndex >= 0) 

    {

        var q = from c in _xmlImageMetadata.Elements(“SceneGraph”).Elements(“SceneNode”

        where ((string)c.Element(“ZOrder”)) == (subImageIndex + 1).ToString()

        select (string)c.Element(“Description”); 

        if (q != null)

       

            return q.Single();

       

        else

            return “”

    }

    else 

        return “”;

}

 

This function uses the function SubImageHitTest which I copied from this weblog:

int SubImageHitTest(Point p)

{

    for (int i = 0; i < deepZoomObject.SubImages.Count; i++) 

    {

        Rect subImageRect = GetSubImageRect(i); 

        if (subImageRect.Contains(p))           

            return i; 

    } return -1;

}

 

Rect GetSubImageRect(int indexSubImage)

{

    if (indexSubImage < 0 || indexSubImage >= deepZoomObject.SubImages.Count)        

        return Rect.Empty;

    MultiScaleSubImage subImage = deepZoomObject.SubImages[indexSubImage]; 

    double scaleBy = 1 / subImage.ViewportWidth;

    return new Rect(-subImage.ViewportOrigin.X * scaleBy, -subImage.ViewportOrigin.Y * scaleBy, 1 * scaleBy, (1 / subImage.AspectRatio) * scaleBy);

}

 

if you build and start your application now you should be able to see your added metadata when you mouseover a sub image in the MultiscaleImage.

My working example can be found here: http://www.vdcruijsen.net/projects/SilverlightDeepzoom/test.html

sourcecode can be downloaded here:

(you’ll have to add your own deepzoom object since i removed that from the zip file)

 

Happy Coding!

 

Geert van der Cruijsen

kick it on DotNetKicks.com

Share on Facebook
Kick It on DotNetKicks.com
Shout it
Post on Twitter