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
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