WPF and Virtual Earth revisited

I've been pretty quite on the blogging front lately.  Every once in a while, I get the opportunity to work on something a little meatier than writing demo code.  Almost all of my time over the last month or so has been spent working on a couple such opportunities.  During this time, I worked on a more creative/reusable approach to hosting Virtual Earth in a WPF application.  If you have looked at any of my previous samples showing how to host Virtual Earth in a WPF app, you'll recall I was using the WinForms WebBrowser control to host an html page that in turn hosts Virtual Earth.  Additionally, I used the WebBrowser control's ability to enable communication between managed code and JavaScript.  One of the frustrations with this approach is that when using WinForms interop, all WinForms controls take the highest z-order in your app which means you cannot render WPF elements on top of the map.  The other thing that has always bothered me about my sample is although it showed how to implement the general approach, it did not wrap all the functionality into a reusable WPF Virtual Earth control.  Good news!  I have an updated sample.

I created the beginnings of a WPF Virtual Earth control.  That's right, one you can just reference, add to your XAML, and start programming against without having to know the dirty underbelly of how it is implemented.




You simply use your .NET language of choice to program against the control's API like you would with any other WPF control.  No need for JavaScript.

The control is a WPF wrapper around the Virtual Earth Map Control 6.1.  In the interest of time, I mirrored the the Virtual Earth Map Control 6.1 API.  However, there are a few deviations.  The control really should, but doesn't, follow .NET coding and naming conventions.  For the most part, it mirrors the JavaScript API.  The control is far from perfect and it is currently only a subset of the JavaScript API.  I implemented the subset of API I needed for the work I was doing.  Having said that, I think I have created a decent foundation that could be built upon to have a full WPF wrapper around the Virtual Earth Map Control 6.1.

I decided to use the new WPF WebBrowser control that is in the .NET Framework 3.5 SP1.  The WPF WebBrowser control is similar to the WinForms WebBrowser.  The WPF WebBrowser control has the same z-order as it's WinForms counterpart, but it eliminates the need for WinForms interop. 

The WPF map control allows you to create WPF UserControls and have them appear on top of the map:


In the picture above, the InfoBox, which is the term Virtual Earth uses for the UI that pops up when you hover over a pushpin, is a UserControl that uses WPF databinding to show Title and Description.  I am clearly not taking advantage of the power of WPF in this example, but you get the point:).  You achieve this through the following code:


You set the InfoBox property of the map to an instance of your UserControl.  The map control does all the heavy lifting of positioning/showing/hiding your UserControl.  The map control also allows you to add as many UserControls as you'd like through map.AddControl.  However, you are responsible for positioning the controls yourself.  In the picture below, I have replaced the default Virtual Earth Dashboard control with a UserControl containing WPF buttons:


If the WPF WebBrowser control still has the z-order issue, then how am I rendering WPF content on top of the map?  I am using what I have been calling "layered window trickery" for lack of a better term.  The map control loads a transparent window with a higher z-order than the window the control is in.  The map control places the transparent window itself "covering" the area of the map control.  Since the top window is transparent, interaction with the map below behaves as if there isn't a window over the map control.  When a call is made to map.AddControl() or to set the map.InfoBox property, I actually add the UserControl to the top window.  As you can imagine there is a bit of repositioning logic for the top window & WPF UI over top of the map.  I plan on recording a Channel 9 Screencast walking through the code.  If you can't wait, then you can just download the sample here and dig through it yourself.  The control uses new features in the .NET Framework 3.5 SP1.  Make sure you install Visual Studio 2008 SP1 Beta before trying to open it.  Details here.


Comments (9)

  1. ASP.NET Using routing with ASP.NET web forms apps [Via: luisabreu ] WPF myHealth [Via: rudi ] "Serialize"…

  2. Jesper Halvorsen says:

    I’m sure that the app works great in the US, but since its for Virtual Earth it should properly also work for the rest of us 🙂

    The issue is with the parsing of doubles being returned from/passed to js – changing them to for example double.Parse(resultArray[0], System.Globalization.CultureInfo.InvariantCulture) will prevent from push pins being added at latitude 389544.

    But this is a minor issue – and it is a great sample

  3. aL_ says:

    love to see more development on this (or something similar)

    a quick fix for the globalization issue is to add the following line as early as possible in your program

    Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo( "en-US" );

    you’ll need to resolve some usings for that to work but you get the general idea 🙂

  4. Keoz says:

    You did my day actually there is no other better aproach to a wraper that mimics the Silverlight VE control thanks

  5. Chris says:

    How would you add a custom push pin?

  6. Joe says:

    It would be much more convenient to see this done through the web services, but have not seen thing about doing so.

  7. PL says:

    VEMap.Clear method is error.

    An invalid VARIANT was detected during a conversion from an unmanaged VARIANT to a managed object. Passing invalid VARIANTs to the CLR can cause unexpected exceptions, corruption or data loss.

    Is anybody getting this error. Did anything changed in Virtual Earth Map Control 6.2 API recently

  8. Preeti Loomba says:

    I am facing the issue when I am trying to show pushpins as soon as the control is loaded rather than show pushpins or polyline on a button click event.

    I tried even in the sample app by calling btnAddPushpins_Click in the end of Window1 contructor rather than on Add Pushpins button

    and I got the VisualStudio Just-In-Time Debugger error for an Unhandled Win 32 exception(‘Launch for User’) occured in WpfVirtualEarthControlTest.exe

    Any help would be highly appreciated

  9. Rich says:

    How do you add a search zip code textbox

Skip to main content