Databinding shapes with the Bing Maps control for Silverlight

The March 2009 release of the Virtual Earth control for Silverlight (now known as the bing map control) was a great release. Up until then, projects like Deep Earth were trying to provide us with a way to use deep zoom + the virtual earth tiling to allow us to build Silverlight apps. Now Microsoft have given us an official control to play with.

One of the big downsides of the official control was the lack of databinding. You still had to add / remove your pushpins & shapes manually just like you would with the AJAX version. There is code available on the Microsoft website that adds dependency properties to the Bing Maps control which expose ItemsCollection, ready for you to databind to. If you combine this with some custom datatemplates, you are able to databind directly to the map as you would expect.

Step 1. Install the Bing Maps control

The CTP of the control is available from Microsoft connect https://connect.microsoft.com/silverlightmapcontrolctp

Step 2. Download the databinding enabler

You just need to download this single .cs file and include it in your project http://code.msdn.microsoft.com/VESLBindingProps

Step 3. Add the Bing maps control to your .xaml page

Add the virtual earth namespace for the control, the ve namespace for the dependency properties, and then the grid. It should look something like this

<UserControl x:Class="SDDNTestRun.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:VirtualEarth="clr-namespace:Microsoft.VirtualEarth.MapControl;assembly=Microsoft.VirtualEarth.MapControl"
    xmlns:ve="clr-namespace:Synergist.VE"
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
    <Grid x:Name="LayoutRoot" >
        <VirtualEarth:Map x:Name="MyMap"
                CopyrightVisibility="Collapsed" LogoVisibility="Collapsed" Mode="Aerial">
        </VirtualEarth:Map>
    </Grid>
</UserControl>

Step 4. Add the data template for shapes and the map layer

This data template to databind polyshapes is fairly easy. You just need to set the polyshape style (thickness, colour, etc.) and then databind the points to the locations collection

<DataTemplate x:Key="MapShape">
    <VirtualEarth:MapPolygon Fill="Orange" Stroke="Green" StrokeThickness="2" Opacity="0.4" Locations="{Binding}" />
</DataTemplate>

And here is how you add the layer to the map

<VirtualEarth:Map x:Name="MyMap"
    CopyrightVisibility="Collapsed" LogoVisibility="Collapsed" Mode="Aerial">
    <VirtualEarth:MapLayer x:Name="ShapeLayer"
        ve:Properties.ItemsSource="{Binding}"
        ve:Properties.ItemTemplate="{StaticResource MapShape}" />
</VirtualEarth:Map>

Step 5. Add some data to the layer

This is the fun bit, figure out what the coordinates for your shape are and create a collection for it. Myself, i’m going to use the site of the Microsoft office here in Melbourne. I’m just going to do this in the page constructor in the code behind

MyMap.Center = new Location(-37.8222600730785, 144.962552763317);
MyMap.ZoomLevel = 17;

var shapeList = new ObservableCollection<LocationCollection>
{
new LocationCollection
    {
        new Location(-37.8217176782418, 144.961662269924),
        new Location(-37.8214041044085, 144.962391830776),
        new Location(-37.8222346484096, 144.963314510677),
        new Location(-37.8228194135791, 144.962638594005),
        new Location(-37.8223617716666, 144.961887575481),
        new Location(-37.8220397256568, 144.962005592678),
    }
};
ShapeLayer.DataContext = shapeList;

Step 6. Hit run and see your databinding in action!

Because we are databinding to an observable list, we can just add new items to it and watch the new shapes appear. It is also possible to add extra points to an existing shape, and see it update live on the map.

If you want to add an extra shape, add this to a click event to see the databinding happening interactively

shapeLists.Add(new LocationCollection()
{
    new Location(-37.8207645163828, 144.961630711604),
    new Location(-37.8200356576319, 144.96164144044),
    new Location(-37.8197136014726, 144.96321857934),
    new Location(-37.8206882408042, 144.962092051554)
});

Step 7. Pushpins

Pushpins are a little more involved. Here i have created a “Point of Interest” class, that has the location and extra details. Here i’m just going to use the location property to databind to. The good thing is that you can use any control as your pushpin. In the included sample my PushPin control expands out when you hover, and collapses when you move off it.

<DataTemplate x:Key="MicrosoftPushPin">
    <Controls:PushPin VirtualEarth:MapLayer.MapPosition="{Binding Loc}"
        VirtualEarth:MapLayer.MapPositionMethod="Center"  />
</DataTemplate>
public class POI
{
    public string Loc { get; set; }
    public string Description { get; set; }
}

//In the class constructor
PushPinLayer.DataContext = new ObservableCollection<POI>
{
   new POI() { Loc = "-37.8222600730785, 144.962552763317" }
};

Sample app

image

In case you just want to see it working, I’ve included the demo I built live at the Melbourne Silverlight Desiginer & Developer Network. Good luck!

http://cid-fc3a2c38819e3e29.skydrive.live.com/self.aspx/Blog/VirtualEarthBindingDemo.zip

By David Burela

6 thoughts on “Databinding shapes with the Bing Maps control for Silverlight

  1. Thanks David for this example. I’ve tried the example it works great. I have a question though and I hope I’m not too off-topic: I have a custom control (basically a blinking light) as my PushPin.xaml. This control has a set of dependency properties that when populated change some aspect of its UI, e.g. when property AlertLevel is “Red” the control will blink red, when AlertLevel is “Yellow” then the light blinks yellow but at a slower rate.
    Would you have any ideas how I can enable this databinding at the PushPin level using your example so that if the underlying PushPin data changes, the PushPin’s UI changes accordingly?
    Thanks for any ideas you can share.

  2. @HughSaalmans The speed of “traditional” vs. the databinding example should be the same. As far as I know under the covers it is still using the same add/remove functions. So the rendering speed should be exactly the same, the only time it might be different is when you modify the collection and it has to do a bit more work

  3. @AlexSerrano: The databinding for the control should be similar to how you would expect it.
    Extend the POI class so that it has the property you need e.g. AlertProp
    Then tell your control that AlertLevel=”{Binding Path=AlertProp}” and it should pick it up from the underlying object. Good question, maybe I should update the example so there is some databound text in the control popup

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s