The few examples and forum posts that I have found all use KML layers defined in XAML at design-time with nested MapTip templates binding to one or more Placemark attributes e.g. name or ExtendedData values (using the ExtendedDataConverter class provided in the example here).

I am looking for a way to programmatically configure map tips on a programmatically-created KML layer at runtime. I can display empty map tips if I assign a MapTip instance to every Graphic in the KmlLayer, but cannot figure out how to dynamically bind the MapTip to the Attribute data in the Graphic. I have inspected the graphic elements and confirmed that they do indeed contain the correct attribute data from the KML document.

Does anyone have an idea as to how this can be accomplished?

2 Answers 2


KmlLayer is alien to me, but I see it has a MapTip property same as FeatureLayer. Here's what we've got for FeatureLayers. These two lines are present in my main MapPage.xaml.cs in an event handler for the layer Initialized event.

FeatureLayerInfo lyrInfo = fLayer.LayerInfo;
fLayer.MapTip = CreateTipWindow(lyrInfo, fLayer.OutFields);

private PopupWindow CreateTipWindow(FeatureLayerInfo lyrInfo, List<string> outFields)
  //edited to omit details not relevent...
  Dictionary<string, string> aliases = new Dictionary<string, string>();
  foreach (Field f in lyrInfo.Fields) 
    if (f.Name != lyrInfo.DisplayField) aliases.Add(f.Name, f.Alias); 
  PopupWindow tipWindow = new PopupWindow() { ShowArrow = false, ShowCloseButton = false };
  tipWindow.Content = CreateFeatureTipContent(outFields, aliases);
  return tipWindow;

private FrameworkElement CreateFeatureTipContent(List<string> fields, Dictionary<string, string> aliases)
    StackPanel stackBox = new StackPanel() { Margin = new Thickness(4, 1, 4, 1), Orientation = Orientation.Vertical };

    foreach (string field in fields)
        if (aliases.Keys.Contains(field))
            TextBlock valueBlock = new TextBlock() { TextWrapping = TextWrapping.NoWrap };
            Binding valueBinding = new Binding() { Path = new PropertyPath(string.Format("[{0}]", field)), StringFormat = aliases[field] + ": {0}" };
            valueBinding.Converter = new DateTimeConverter(); //MC 2013-01 added this to tweak any Local DateTimes.
            valueBlock.SetBinding(TextBlock.TextProperty, valueBinding);

    return stackBox;

We are using the PopupWindow class from the ESRI.SilverlightViewer.Controls library distrubuted with this viewer (from which we've learned a great deal, BTW), but PopupWindow simply derives from ContentControl, so rolling one's own is minor, if you want.

  • Modified your code slightly to work with a KmlLayer and it does exactly what I was hoping to achieve.
    – user3043
    Feb 15, 2013 at 7:57

Here's a half answer that skips any binding. Since you're programatically creating the KML why not just loop through the graphics and put the value of the attributes in the name or description nodes of the placemark? Or am I missing something?

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document id="crsmaps">
  <name>CRS Maps</name>
  <Folder id="arterial_grid">

      <name><![CDATA[<span style="font-size:24px">06P32</span>]]></name>
      <description><![CDATA[<div style="margin:10px 10px 10px 10px;">Get Arterial Map <a href="http://a_server/maplinks/06p/06p.pdf">06P</a><br/>Get Detailed Map <a href="http://a_server/maplinks/06p/06p32.pdf">06P32</a></div>]]></description>
           <coordinates> -121.901066,36.499962 -121.801064,36.499962 -121.801065,36.416626 -121.901067,36.416627 -121.901066,36.499962</coordinates>
    <!-- ....so on and so forth -->

  <Style id="dg">
  • The content of the KML is not the issue. Attributes and extended data are already present and are being read into the Graphics correctly. I am having difficulty creating the layer's MapTip at runtime to show the features' attributes in a pop-up window.
    – user3043
    Feb 15, 2013 at 7:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.