WPF and Virtual Earth

WPF Version 3.5 Service Pack 1 has a new WebBrowser control as I talked about a little here;

http://channel9.msdn.com/posts/mtaulty/WPF-35-Sp1-WebBrowser-Control/

and some of the nice things about the control are;

  1. It can load HTML from a Stream or a string – i.e. you don’t have to hit the web.
  2. You can call from the surrounding .NET code into script inside the control.
  3. You can call from script inside the control into the surrounding .NET code.

This seemed to be enough to form the basis of using the Virtual Earth control inside of WPF so I set about trying to build a control that did a very basic version of that.

The basic approach that I took is;

  1. WPF UserControl with dependency properties for Latitude, Longitude, ZoomLevel and MapStyle.
  2. Put an embedded HTML file inside the resources of my control’s assembly which contains the HTML needed to load the Virtual Earth control along with the script needed to;
    1. Make it possible to set the Latitude, Longitude, ZoomLevel and MapStyle from my UserControl.
    2. Pass appropriate notifications back from the Virtual Earth control to my control.

That’s pretty much it – I’ve not finished it yet by any means as I want to add some push-pin functionality and I’m sure there’s bugs in this thing.

Along the way I did get a little bit foxed at one point because I want to be able to use my control in scenarios such as

      <ve:VirtualEarth
        x:Name="veControl"
        Grid.Column="1"
        ZoomLevel="{Binding Path=Value, ElementName=slidey}"
        Latitude="{Binding Path=Text, ElementName=txtLat}"
        Longitude="{Binding Path=Text, ElementName=txtLon}"
        MapStyle="{Binding Path=Text, ElementName=cmbMapStyle}" />

So, everything there is databound. Seems easy but the “problem” I got into was that WPF’s databinding would start setting these properties and I would pass them through to the Virtual Earth control before it was ready to accept them and it would fail a lot.

So, I had to put a bit of a queue in between the WPF control and the Virtual Earth control where I queue up commands for the control if the control has not yet said that it is “ready”.

Here’s an example of the control in use in a simple test-harness;

image

And it’s entirely declaratively data bound there.

I’m sure that it can relatively easily be “broken” if you play with it too much but I thought I’d share it.

Here’s the solution for download – including the control and the test harness. I’ll move this forward a little bit because I want to add the ability to search by post-code and add a few push-pins but I thought it was worth sharing.