Introduction
OK, another post in response to a forum question. This time on SharePoint Overflow. I was looking for a way to display pushpins on a Bing Map Silverlight control using data from a SharePoint list. I've split this post into two parts mainly because there's a fair amount of code involved to just to render the Silverlight control in the web part, never mind the building the required JavaScript in managed code, so we'll leave that for another day (or night).
The answer to the question in this case is to use the HTML Bridge that enables interaction between HTML and Managed Code, specifically it allows us expose methods in managed code to JavaScript, but we'll get that part later. First up let's create the Silverlight control.
The Silverlight Control
This part is fairly straightforward so I won't go into the details here. This article will give you all you need to get started. One thing to note is that to test the Silverlight control I've made use of the web project that Visual Studio can create for you when you create a new Silverlight project so if you want to follow along with that particular section be sure to let Visual Studio create the web project for you. You can, however, skip the “Change the Map Mode using C#” step if you want. Before we move on to the code we need to add a layer to the map so that we have somewhere to put the pushpins so add the following fragment to the <m:Map>
element in the MainPage.xaml
file: –
<m:Map.Children>
<m:MapLayer x:Name="Pushpins">
</m:MapLayer>
</m:Map.Children>
Now we have somewhere to put them we'll write the code that places the pushpins on the map, so open up the MainPage.xaml.cs
file. To be able to use the HTML Bridge and Bing Map Control we need to add some references so add the following lines to the top of the file: –
using System.Windows.Browser;
using Microsoft.Maps;
using Microsoft.Maps.MapControl;
using Microsoft.Maps.MapControl.Core;
Now that we have the reference we can add a custom location class that will contain the latitude and longitude coordinates enabling us to position the pin on the map. Add the following class to the MainPage.xaml.cs
file within your namespace: –
[ScriptableType]
public class MapLocation
{
[ScriptableMember]
public string Title { get; set; }
[ScriptableMember]
public double Latitude { get; set; }
[ScriptableMember]
public double Longitude { get; set; }
}
The ScriptableType
attribute allows us to make use of the public properties, methods and events of a managed code object in JavaScript. ScriptableMember indicates that the specific property is available to JavaScript callers. Technically this isn't required in this scenario as we've decorated the entire class with the ScriptableType
attribute but it won't break it either.
Next we can add our method to add a pushpin to the map that will be called by JavaScript. Add the following lines to the MainPage class in your MainPage.xaml.cs
file: –
[ScriptableMember]
public void AddLocation(MapLocation location)
{
Pushpin pin = new Pushpin();
pin.Location = new Location(location.Latitude, location.Longitude);
pin.Name = location.Title;
pin.Tag = location.Title;
Pushpins.Children.Add(pin);
}
The ScriptableMember
attribute indicates that this method is available to us from JavaScript. To complete the MainPage class changes add the following lines to the constructor after the InitializeComponent();
call: –
HtmlPage.RegisterCreateableType("MapLocation", typeof(MapLocation));
HtmlPage.RegisterScriptableObject("Communicator", this);
This first line registers our MapLocation class for use in JavaScript with the key of “MapLocation” (why complicate things?). The second line registers the MainPage class for the same purpose. This is all we need to do to the Silverlight control but before we dive into creating the SharePoint web part lets test that we can indeed call the method from JavaScript by using the test page in the web project that Visual Studio has created for us.
The JavaScript
I've called my solution BingMapWebPart so I'm opening the BingMapWebPartTestPage.aspx file (yours might be named more succinctly). There should already be an onSilverlightError function in the head of the page. Below that we can add our JavaScript function: –
function onSilverlightLoad(sender, args) {
var bingMapsControl = sender.getHost();
var l = bingMapsControl.content.services.createObject("MapLocation");
l.Title = "API Software - Glasgow";
l.Latitude = 55.864438;
l.Longitude = -4.262776;
bingMapsControl.content.Communicator.AddLocation(l);
}
This function should add a pushpin to the map at the location of API Software's offices in Bath Street, Glasgow. Note the use of the keys we defined in the Silverlight control. To create a new MapLocation object on the client we've called the content.services.createObject method of the control, passing in the "MapLocation" key, then to call the AddLocation()
method of the MainPage class we've called the AddLocation()
method of the content.Communicator object. The last thing to do is ensure that this function is called once the Silverlight control has loaded, so add the following line to the existing list of params in the object tag for the control: –
<param name="onLoad" value="onSilverlightLoad" />
<param name="onLoad" value="onSilverlightLoad" />
So if this all works, when you press F5 you'll see a pushpin pointing to Glasgow on a map of the world. In Part 2 we'll turn this into a SharePoint web part.