I am trying to add simple legend to the map.

I wrote some simple test code below to see what happens but it did not work.

var map = activeView.FocusMap;

            IGraphicsContainer graphicsContainer = activeView.GraphicsContainer;
            IMapFrame mapFrame = graphicsContainer.FindFrame(map) as IMapFrame;
            UID uid = new UID();
            uid.Value = "esriCarto.Legend";
            IMapSurround mapSurround = map.CreateMapSurround(uid, null);
mapFrame.CreateSurroundFrame(uid, null);

            var legend = (ILegend)mapSurround;

            var legendItem = new VerticalLegendItemClass();
            legendItem.HeadingSymbol.Text = "served";

            var legendItema = new VerticalLegendItemClass();
            legendItema.HeadingSymbol.Text = "unserved";

            IElement element = legend as IElement;
            element.Geometry = envelope as IGeometry;
            graphicsContainer.AddElement(element, 0);


The legend I am after, must be similar to this:


Can anyone assist?

  • Does the Add Legend Snippet from the docs help?
    – Petr Krebs
    Oct 1 '13 at 14:14
  • @PetrKrebs yes, and tried this help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/… still nothing.
    – IBRA
    Oct 2 '13 at 13:06
  • @PetrKrebs it keeps crushing on this code line: IMapSurroundFrame mapSurroundFrame = mapFrame.CreateSurroundFrame((UID)uid, null);
    – IBRA
    Oct 2 '13 at 13:08
  • 1
    @IbrahimSwaiss what is the error you receive on crash?
    – Conor
    Oct 2 '13 at 14:19
  • Yes, I find it hard to understand why you wouldn't mention what exception you get at that particular line...
    – Petr Krebs
    Oct 2 '13 at 18:01

You noted in comments that your program was crashing when you cast to UID like so:

mapFrame.CreateSurroundFrame((UID)uid, null); 

Your issue might be that you are casting to a C# System UID such as this one. To rectify this, you will want to explicitly specify that you want to cast to the ArcObjects UID like in the snippet @PetrKrebs linked.

Try substituting the above code for this:

ESRI.ArcGIS.Carto.IMapSurroundFrame mapSurroundFrame = mapFrame.CreateSurroundFrame((ESRI.ArcGIS.esriSystem.UID)uid, null); // Explicit Cast

Though it requires more typing, it is always safer to explicity specify the full pathway of your references (in this case it is ESRI.ArcGIS.esriSystem.UID or System.Windows.UIElement.UID) when referencing anything in programming as it prevents ambiguities such as these.

The compiler will sometimes catch an ambiguous reference, but not always. It will usually default to the System reference if there is an ambiguous reference and no warning/error is thrown.

  • Passing a different type would not compile at all..
    – Petr Krebs
    Oct 2 '13 at 17:39

The following code (which is basically just an adapted sample from the SDK) works for me, but only if there are any layers in the map. Notice this is in line with ArcMap user interface, which does not allow you to insert the legend when no layers are in the map.

private void AddLegendForMap(IMap map, IPageLayout pageLayout, double xInPageUnits, double yInPageUnits, double widthInPageUnits)
    if (map == null) throw new ArgumentNullException("map");
    if (pageLayout == null) throw new ArgumentNullException("pageLayout");

    var layoutGraphicsContainer = (IGraphicsContainer)pageLayout;
    var mapFrame = layoutGraphicsContainer.FindFrame(map) as IMapFrame;

    if (mapFrame == null)
        throw new InvalidOperationException("Map frame for given map was not found on the page layout.");

    var legendUid = new UIDClass {Value = "esriCarto.Legend"};

    var legendMapSurroundFrame = mapFrame.CreateSurroundFrame(legendUid, null);
    var legendMapSurround = legendMapSurroundFrame.MapSurround;

    double widthInPoints = 0;
    double heightInPoints = 0;

    ((IQuerySize)legendMapSurround).QuerySize(ref widthInPoints, ref heightInPoints);
    var widthToHeightRatio = widthInPoints / heightInPoints;

    var heightInPageUnits = widthInPageUnits * widthToHeightRatio;

    var envelope = new EnvelopeClass();
    envelope.PutCoords(xInPageUnits, yInPageUnits, xInPageUnits + widthInPageUnits, yInPageUnits + heightInPageUnits);

    ((IElement)legendMapSurroundFrame).Geometry = envelope;

    layoutGraphicsContainer.AddElement((IElement)legendMapSurroundFrame, 0);

    ((IActiveView)pageLayout).PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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