Wednesday, March 18, 2009

How to create a simple pushpin as a placemarker for DeepEarth in Silverlight?

The DeepEarth Maps in codeplex is a very brilliant work and can support a lot of map types with different providers like Yahoo, Open Street Maps, Blue Marble (except Google for now) in silverlight. I am a fan of this work.

They also have sample source code to create custom push pins. These are like the markers in the javascript version of google and yahoo maps. These are controls derived from a base class called PointBase which derives from DependencyObject at the deep base levels. Finally it overrides a function called OnApplyTemplate where it really does the work of showing the data/controls. This article does not intend to explain those concepts though.

Problem:
The sample project they have contains support for Pins which can show JPEG or other items in their styles and ability to show descriptions etc., which is great. But recently I had a requirement just to show the text of a village name for example. The existing sample controls did not fit my needs. So I had to write a simple control on my own. Hope this helps some one else as well.

Anyway here you go!!

Solution:
We need to take care of 2 things. The first is to define a style in App.xaml and the second is to write the control code.

The control name that I used is "PlaceMarkerPin". You can rename it if you like something else.

---------------------------------------------------------------------------------------------
App.xaml:

<Style x:Key="PlaceMarkerStyle" TargetType="MyControls:PlaceMarkerPin">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MyControls:PlaceMarkerPin">
<Grid>
<TextBlock x:Name="DisplayTitle" Text=" " TextAlignment="Center" Foreground="Black" FontSize="12" FontWeight="Bold" />
</Grid>

</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

---------------------------------------------------------------------------------------------

Now if you really look at it we have only one control TextBlock named as "DisplayTitle" in the above style and this is the only item displayed. You can change the Font styles, alignment etc., to your liking.

Now to the control code

---------------------------------------------------------------------------------------------
using System.Windows.Browser;
using System.Windows.Controls;
using System.Windows.Input;
using DeepEarth.Geometry;

namespace YourNameSpace
{
public class PlaceMarkerPin : PointBase
{
private string _title;

public string Title
{
get { return _title; }
set { _title = value; }
}

public PlaceMarkerPin()
{
}


#region Balloon Functions

#endregion

public override void OnApplyTemplate()
{
TextBlock tbDisplayTitle = (TextBlock)GetTemplateChild("DisplayTitle");

bool designTime = (HtmlPage.IsEnabled == false);
if (designTime == false)
{
tbDisplayTitle.Text = _title;
_IsLoaded = true;
ForceMeasure();
Layer.UpdateChildLocation(this);
}
}

void tbDisplayTitle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
CaptureMouse();
}
}
}
---------------------------------------------------------------------------------------------

The following is the codesnippet for adding it to the DeepEarth map layer. This assumes that we already have a layer created.
---------------------------------------------------------------------------------------------
Point point = new Point(loc.Longitude, loc.Latitude);
var pin = new PlaceMarkerPin() { Point = point, Style = (Application.Current.Resources["PlaceMarkerStyle"] as Style) };
pin.Title = loc.CustomLocationName;
customlayer.Add(pin);
---------------------------------------------------------------------------------------------

This also is a very short example to actually understand how the pins in DeepEarth Maps work. One can now add more controls and styles to make it better if a need arises.

No comments: