Select to view content in your preferred language

binding marker symbol

1697
5
10-19-2011 08:50 AM
suharthachowdhury
Emerging Contributor
Hi,

I have several ESRI markersymbols showed on a map layer. Now I want to create a "legend/TOC" like control with the marker symbols and their representative text on it. I don't have a symbol attribute served by the map service, so I really can't use the SymbolDisplay property of the toolkit . My symbols are my marker symbols. How can I achieve this? I was planning to create a user control to show my legend-like control. But how can I bind my marker symbols on it? Please share your idea and provide any code-snippet if possible.

Thanks.
Suhartha
0 Kudos
5 Replies
JenniferNery
Esri Regular Contributor
You can set GraphicsLayer.Renderer and Legend control will pick up the symbol.

For example:
<!--Under Resources-->
   <esri:SimpleRenderer x:Key="MyRenderer" Label="Red Symbol">
    <esri:SimpleRenderer.Symbol>
     <esri:SimpleMarkerSymbol Color="Red" Size="6" Style="Diamond" />
    </esri:SimpleRenderer.Symbol>
   </esri:SimpleRenderer>
<!--more code goes here-->
<esri:GraphicsLayer ID="CitiesGraphicsLayer" Renderer="{StaticResource MyRenderer}"/>
0 Kudos
suharthachowdhury
Emerging Contributor
You can set GraphicsLayer.Renderer and Legend control will pick up the symbol.

For example:
<!--Under Resources-->
   <esri:SimpleRenderer x:Key="MyRenderer" Label="Red Symbol">
    <esri:SimpleRenderer.Symbol>
     <esri:SimpleMarkerSymbol Color="Red" Size="6" Style="Diamond" />
    </esri:SimpleRenderer.Symbol>
   </esri:SimpleRenderer>
<!--more code goes here-->
<esri:GraphicsLayer ID="CitiesGraphicsLayer" Renderer="{StaticResource MyRenderer}"/>


Hi Jenni,
Thanks for your reply. But it's bit different in my case. I cannot really use any renderer for the graphics layer because I do not have a single renderer. The marker symbols are being added to the graphics layer in run-time(from code behind) for each result feature depending on some logic. So what I am doing is:
foreach(Graphic resultFeature in featureSet.Features)
{
  if(somecondition)
  {
     resultFeature.Symbol = LayoutRoot.Resources["Non_Detect"] as Symbol;
       // Non-Detect is one of my custom marker symbols defined under resources
       <!--more code goes here-->
     graphicsLayer.Graphics.Add(resultFeature);
  }
}

Now with all these marker symbols I want to create the legend-like control to explain the symbols. So it will be a list-like panel that will list all the symbols shown on the map layer with their respective explanation. My difficulty is to bind the marker symbols on this panel. Also I need to know if it is possible to do this in code-behind so that I can include only those symbols that appear on the map layer on the legend control. Hope I was able to explain the scenario...
0 Kudos
JenniferNery
Esri Regular Contributor
You can use UniqueValueRenderer and add an Attribute that will detect which symbol it needs to pick up. Instead of setting graphic.Symbol, you can set graphic.Attribute. Here's an example of how UniqueValueRenderer is used in GraphicsLayer. http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#RenderersXAML. By moving your symbols to a renderer, Legend control should be able to use the symbol and label assigned on the renderer.
0 Kudos
DominiqueBroux
Esri Frequent Contributor
An alternative to Jennifer's solution is to add legend items by code on event 'Refreshed' (Jennifer's solution is better though).

You have to instantiate a new LegendItemViewModel, initialize its label and its imagesource and add it to the LegendItems collection.

The difficulty might be to create the imagesource from the symbol.
The trick is to create a renderer with the symbols and let the renderer create the swatches.

Code example :
 
private void Legend_Refreshed(object sender, ESRI.ArcGIS.Client.Toolkit.Legend.RefreshedEventArgs e)
{
    GraphicsLayer layer = e.LayerItem.Layer as GraphicsLayer;
    if (layer != null && layer.ID == "MyGraphics")
    {
        // Create a dummy renderer with the label and symbols to see in the legend
        var renderer = new UniqueValueRenderer();
        renderer.Infos.Add(new UniqueValueInfo { Label = "RedMarker", Symbol = LayoutRoot.Resources["RedMarkerSymbol"] as Symbol });
        renderer.Infos.Add(new UniqueValueInfo { Label = "GlobePictureMarker", Symbol = LayoutRoot.Resources["GlobePictureMarkerSymbol"] as Symbol });
        renderer.Infos.Add(new UniqueValueInfo { Label = "Red Line", Symbol = LayoutRoot.Resources["RedLineSymbol"] as Symbol });
        renderer.Infos.Add(new UniqueValueInfo { Label = "Carto Line", Symbol = LayoutRoot.Resources["CartoLineSymbol"] as Symbol });
        // ....... add others symbols
 
        // Query asynchronously the legend infos for this renderer
        renderer.QueryLegendInfos(layerLegendInfo => CreateLegendItems(e.LayerItem, layerLegendInfo), null);
    }
}
private static void CreateLegendItems(LayerItemViewModel layerItem, LayerLegendInfo layerLegendInfo)
{
    // Project the legend item infos coming from the renderer (LegendItemInfo) to legend items of the legend control (LegendItemViewModel)
    var items = layerLegendInfo.LegendItemInfos.Select(legendItemInfo => new LegendItemViewModel { Label = legendItemInfo.Label, ImageSource = legendItemInfo.ImageSource });
    layerItem.LegendItems = new ObservableCollection<LegendItemViewModel>(items);
}


See result in attached screenshot.
0 Kudos
suharthachowdhury
Emerging Contributor
You can use UniqueValueRenderer and add an Attribute that will detect which symbol it needs to pick up. Instead of setting graphic.Symbol, you can set graphic.Attribute. Here's an example of how UniqueValueRenderer is used in GraphicsLayer. http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#RenderersXAML. By moving your symbols to a renderer, Legend control should be able to use the symbol and label assigned on the renderer.


Hi,

Thank you both for your help. I have resolved my problem as per Jennifer's method. It was lot simpler than I expected. Thanks a bunch.
0 Kudos