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 (27)

  1. Ned says:

    Trying to run the sample I get error in VEMap.xaml.cs when it tries to invoke line 477:

     var result = this.webBrowser.InvokeScript("GetCenter")

    Is the sample supposed to be self-contained or do I need to have some VE Map stuff installed?

  2. keydet says:

    Looks like you found a bug!  I think this is due to a issue with the JavaScript map control not being fully loaded in the browser.  Does it work if you go to maps.live.com and run it again?

    I actually thought I cleaned up the code that caused map.GetCenter() to be called during initial load.  Not that the control shouldn’t support this scenario.  It should.  However, I had a couple bugs with a related scenario and just didn’t have the time to investigate.  I’ve updated the code to remove the call to map.GetCenter() on the initial load and uploaded the new bits to SkyDrive.  You can either download the updated code or just comment out line 30 in Window1.xaml.cs.  As an alternative, you could dig into what’s causing the error and suggest an enhancement:).  I am actually considering turning this prototype into a CodePlex project so that others can build on the foundation, improve the code, and implement the rest of the API.

  3. Ned says:

    Thanks, that fixed it. I don’t have time now to look into the code. I was planning on using it this fall in a C# class that I teach. I will be using WPF and had planned on doing something with VE and along came your blog post. Perfect timing!

    It will get me past the "startup" phase.

  4. Marc Schweigert wrote a great blog post and provided some code samples for an application he wrote combining

  5. Nuke says:

    We created a similar solution, also using a "layered window trickery"  (and we thought we invented it :-)). You can see a movie here:


    This was 6 months ago. Since then we moved to Silverlight 2 as our platform. We hit a wall displaying transparency over the 3D though..

    If your curious, we’ll be releasing a beta preview this July.

  6. keydet says:

    Very cool app in the video!  Looking forward to seeing it in July!


  7. You’ve been kicked (a good thing) – Trackback from DotNetKicks.com

  8. Marc Schweigert shows you how to use Virtual Earth in a WPF application by using a prototype WPF Virtual

  9. For the WPF /VE fans in the house, Marc Schweigert has a post and demo showing how to use the new web

  10. Good job !

    I also made this kind of things, some weeks ago, directly by overlapping WPF and Virtual Earth (with multitouch control ).

    It’s viewable on youtube, here :


  11. keydet says:

    Very cool!


  12. For the WPF /VE fans in the house, Marc Schweigert has a post and demo showing how to use the new web browser control in .NET 3.5 SP1 to host Virtual Earth. Web meets desktop. Marc's post is here ….

  13. While the MapPoint Web Service SDK is highly cool and nice and lightweight, I gotten lots of requests

  14. For the WPF /VE fans in the house, Marc Schweigert has a post and demo showing how to use the new web

  15. Gold Coast says:

    First, let me apologize since I promised to make this recording available almost two months ago. 

  16. First, let me apologize since I promised to make this recording available almost two months ago. 

  17. Keith Woods says:

    Nice work, I used your control (largley unchanged) in combination with some code I wrote a year ago to parse a NMEA log and write the track to screen, hopefully post the code soon 🙂


  18. Chi says:

    Nice Control. Only one thing I could not find is Adding VEShapeLayer. Is it possible to add this method for supporting large number of pushpins?

  19. Alex Preston says:

    Is it possible to rotate and morph your ve control using WPF?

  20. Marc says:

    Sorry for the slow response.

    Chi – It’s definitely possible, but the control is a prototype / "as is" sample.  I’m thinking about turning this sample into a much more stable and feature rich control via http://codeplex.  Stay tuned for news.

    Alex – This is not possible because the control ultimately wraps a non WPF control so we run into the same issues disscussed at http://msdn.microsoft.com/en-us/library/ms753178.aspx.  


  21. Gustavo says:

    Thank you very much for your work.  I found some bugs in the code that I want to share just in case anybody is faced with the same problems:

    1. Setters in VELatLong are wrong (they should be "xxxx = value" instead of "value = xxxx")

    2. Events in Map must be checked before launched ("if (MapLoaded != null) MapLoaded(this, args)" instead of just "MapLoaded(this, args)")

    Thank you again for this valuable control.

  22. Marc says:

    Thanks Gustavo.  I must admit I put this thing together in haste.  I had been sitting on the basic prototype for some time, but wasn’t finding the time to polish it.  I finally decided to just post it.  Thanks for finding the bugs.  I’m hoping to find some time to finish / polish the control and post it up to CodePlex.


  23. Dan says:

    Great, I’ll be checking codeplex eagerly! Just a note: besides the already signaled bugs, in a polished version you should pay attention to localization issues: European languages typically use , instead of . in decimals, so I changed the coordinates-split character into ; rather than ,. and added an explicit CultureInfo.InvariantCulture parameter to ALL the C# functions doing ToString() or Parse().

  24. Vocal Steve says:

    great.  i add a SuppressScriptErrors function as a complement.

  25. Help says:

    i cant download this sample,could u plz mail the soucre code to me:yongjunbingyu@gmail.com

  26. devkeydet says:

    This is an OLD sample.  There is a WPF control for Bing Maps now: