Select to view content in your preferred language

Bind Symbol In MapTip?

909
6
09-03-2011 09:22 AM
RyanCoodey
Frequent Contributor
Using a FeatureLayer that has different symbols coming from the server... Is there a way to bind the graphics corresponding symbol inside the map tip?  This way when using a clusterer (that hides the symbol) it would still show in the map tip!

Example:
    <sdl:MapTip>
        <StackPanel Margin="10">
            <esriPrimitives:SymbolDisplay Symbol="{Binding Symbol}" /> <!-- Trying to get symbol displayed here -->
            <TextBlock Text="{Binding [sgnl_type_desc]}" FontWeight="Bold" FontSize="12" Foreground="Black"  />
            <TextBlock Text="{Binding [ENTY_NME]}" FontSize="10" Foreground="Black" />
        </StackPanel>
    </sdl:MapTip>


Thanks a lot for any help or ideas!
0 Kudos
6 Replies
JenniferNery
Esri Regular Contributor
If the feature service contains "drawingInfo" which defines the layer's Renderer, the graphic.Symbol property will be null.

Also in the MapTip, the DataContext here is the graphic.Attributes, which is why the Binding statements use the square brackets '[]' to access the attribute key.

To show the Symbol, DataContext need to change to Graphic so you may access its Symbol property (which could be null when FeatureLayer.Renderer is used).

You can probably use a Converter that will return a symbol based on graphic. If graphic.Symbol is not set and relies on renderer, you can get symbol from FeatureLayer.GetSymbol(graphic).
0 Kudos
RyanCoodey
Frequent Contributor
Jennifer,  Thanks a lot of the reply!

Hmm, the FeatureLayer's service does contain a "drawingInfo", It has too right, to get the symbology from the server?  The FeatureLayer's Renderer is NOT null, but each graphic.Symbol is NOT null either...

Could you please provide an example on how to set the DataContext to the Graphic (and not the Attributes collection)?  I have tried every binding I could think of but cannot get the graphic...

I also made a value converter, if it is even needed, but not sure how to get access to the FeatureLayer in it to call FeatureLayer.GetSymbol(graphic)... but I will worry about that if the above doesn't work.

Thank you much and thanks for any more help!!!
0 Kudos
JenniferNery
Esri Regular Contributor
FeatureLayer.LayerInfo.Renderer is the service-defined renderer.

I used this sample: http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#FeatureLayerMapTips

Added an AttributeToSymbolConverter class with DependencyProperty to get to the FeatureLayer.LayerInfo.Renderer

public class AttributeToSymbolConverter : FrameworkElement, IValueConverter
{
 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 {
  var dict = value as IDictionary<string, object>;
  if (dict != null && FeatureLayer != null && FeatureLayer.LayerInfo != null && FeatureLayer.LayerInfo.Renderer != null)
  {
   var graphic = new Graphic();
   foreach (var d in dict)
    graphic.Attributes[d.Key] = d.Value;
   return FeatureLayer.LayerInfo.Renderer.GetSymbol(graphic);
  }
  return null;
 }
  public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 {
  throw new NotImplementedException();
 }
  public static readonly DependencyProperty FeatureLayerProperty = DependencyProperty.Register("FeatureLayer", typeof(FeatureLayer),
  typeof(AttributeToSymbolConverter), null);

 public FeatureLayer FeatureLayer
 {
  get { return (FeatureLayer)GetValue(FeatureLayerProperty); }
  set { SetValue(FeatureLayerProperty, value); }
 }
}


<!--Grid.Resources-->
<local:AttributeToSymbolConverter x:Key="MyConverter" FeatureLayer="{Binding ElementName=MyMap, Path=Layers[CitiesFeatureLayer]}"/>
<!--FeatureLayer.MapTip.StackPanel-->
<esriPrimitives:SymbolDisplay Symbol="{Binding Converter={StaticResource MyConverter}}" />
0 Kudos
RyanCoodey
Frequent Contributor
Thanks a lot for that example, that is great... I didn't even think to pass the FeatureLayer that way.  I am still having issues with the binding though.  If I do the binding as in your example:
<esriPrimitives:SymbolDisplay Symbol="{Binding Converter={StaticResource attributeToSymbolConverter}}" />


It does not bind to the attribute collection, but to the parent UserControl that hosts the ESRI map control... kind of wierd.  I also tried this binding
<esriPrimitives:SymbolDisplay Symbol="{Binding /, Converter={StaticResource attributeToSymbolConverter}}" />


And it seems to bind to the first item in the attribute collection, but not the collection itself...

I'll keep playing with the bindings, I'm still a bit new to SL/WPF... If you have any ideas though that would be great.

Thanks a ton for all the help!
0 Kudos
JenniferNery
Esri Regular Contributor
Yeah that is strange. Element's DataContext inside FeatureLayer.MapTip should inherit its parent if it was not overwritten. The API sets this DataContext to the graphic.Attributes. Check that SymbolDisplay DataContext was not set or StackPanel/Grid that contained it did not have their DataContext set to something else.

So you are not seeing a Symbol displayed? Does your OutFields include the type ID field or field used by your renderer? If it is SimpleRenderer, OutField does not need to contain any field but ClassBreaksRenderer or UniqueValueRenderer rely on fields and their values when determining symbol. Kindly try with the SDK sample first then tweak accordingly with your own service.
0 Kudos
RyanCoodey
Frequent Contributor
Jennifer,

The DataContext on a parent control was indeed set, I changed this around and it works great!  Thanks a lot!
0 Kudos