Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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?

share|improve this question

2 Answers 2

up vote 2 down vote accepted

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);
            stackBox.Children.Add(valueBlock);
        }
    }

    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.

share|improve this answer
    
Modified your code slightly to work with a KmlLayer and it does exactly what I was hoping to achieve. –  user216601 Feb 15 '13 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>
  <Snippet></Snippet>
  <Folder id="arterial_grid">
    <name>Grid</name>
    <Snippet></Snippet>

    <Placemark>
      <name><![CDATA[<span style="font-size:24px">06P32</span>]]></name>
      <styleUrl>#dg</styleUrl>
      <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>
      <MultiGeometry>
        <Polygon>
        <tessellate>1</tessellate>
        <extrude>0</extrude>
        <altitudeMode>clampToGround</altitudeMode>
        <outerBoundaryIs>
        <LinearRing>
           <coordinates> -121.901066,36.499962 -121.801064,36.499962 -121.801065,36.416626 -121.901067,36.416627 -121.901066,36.499962</coordinates>
        </LinearRing>
        </outerBoundaryIs>
        </Polygon>
      </MultiGeometry>
    </Placemark>
    <!-- ....so on and so forth -->

  </Folder>
  <Style id="dg">
    <LineStyle>
      <color>ff0066ff</color>
      <width>0.5</width>
    </LineStyle>
    <PolyStyle>
      <fill>0</fill>
      <outline>1</outline>
    </PolyStyle>
  </Style>
</Document>
</kml>
share|improve this answer
    
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. –  user216601 Feb 15 '13 at 7:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.