Skip to content

ProSnippets GraphicsLayers

UmaHarano edited this page Nov 12, 2025 · 1 revision
Language:              C#  
Subject:               GraphicsLayers  
Contributor:           ArcGIS Pro SDK Team <[email protected]>  
Organization:          Esri, http://www.esri.com  
Date:                  11/7/2025  
ArcGIS Pro:            3.6  
Visual Studio:         2022  

Create GraphicsLayer

if (map.MapType != MapType.Map)
    return;// not 2D

  var gl_param = new GraphicsLayerCreationParams { Name = "Graphics Layer" };
  // Note: must be called on the QueuedTask
  {
    //By default will be added to the top of the TOC
    graphicsLayer = LayerFactory.Instance.CreateLayer<ArcGIS.Desktop.Mapping.GraphicsLayer>(gl_param, map);

    //Add to the bottom of the TOC
    gl_param.MapMemberIndex = -1; //bottom
    LayerFactory.Instance.CreateLayer<ArcGIS.Desktop.Mapping.GraphicsLayer>(gl_param, map);

    //Add a graphics layer to a group layer...
    var group_layer = map.GetLayersAsFlattenedList().OfType<GroupLayer>().First();
    LayerFactory.Instance.CreateLayer<ArcGIS.Desktop.Mapping.GraphicsLayer>(gl_param, group_layer);

    //TODO...use the graphics layer
    //

    // or use the specific CreateGroupLayer method
    LayerFactory.Instance.CreateGroupLayer(map, -1, "Graphics Layer");
  }

Accessing GraphicsLayer

if (map.MapType != MapType.Map)
  {
    // not 2D - could be a scene - no graphics layers
  }

  //get the first graphics layer in the map's collection of graphics layers
  graphicsLayer = map.GetLayersAsFlattenedList().OfType<GraphicsLayer>().FirstOrDefault();
  if (graphicsLayer != null)
  {
    //TODO...use the graphics layer      
  }
  //Or, Get and set the graphic layer that acts as the target for interactive drawing tools. 
  targetGraphicsLayer = map.TargetGraphicsLayer; // get the target graphics layer
  map.TargetGraphicsLayer = graphicsLayer; // set the target graphics layer

Copy Graphic elements

// Note: must be called on the QueuedTask
  {
    var elems = sourceGraphicsLayer.FindElements(new List<string>() { "Point 1", "Line 3", "Text 1" });
    var copiedElements = targetGraphicsLayer.CopyElements(elems);
  }

Remove Graphic elements

// Note: must be called on the QueuedTask
  {
    graphicsLayer.RemoveElements(graphicsLayer.GetSelectedElements());
  }

Create Graphic Elements

Point Graphic Element using CIMGraphic

// Note: must be called on the QueuedTask
  {
    //Place symbol in the center of the map
    var extent = MapView.Active.Extent;
    var location = extent.Center;

    //specify a symbol
    var pt_symbol = SymbolFactory.Instance.ConstructPointSymbol(
                          ColorFactory.Instance.GreenRGB);

    //create a CIMGraphic 
    var graphic = new CIMPointGraphic()
    {
      Symbol = pt_symbol.MakeSymbolReference(),
      Location = location //center of map
    };
    graphicsLayer.AddElement(graphic);
  }

Line Graphic Element using CIMGraphic

// Note: must be called on the QueuedTask
  {
    //On the QueuedTask
    //Place a line symbol using the extent's lower left and upper right corner.
    var extent = MapView.Active.Extent;
    //get the lower left corner of the extent
    var pointFromCoordinates = new Coordinate2D(extent.XMin, extent.YMin);
    //get the upper right corner of the extent
    var pointToCoordinates = new Coordinate2D(extent.XMax, extent.YMax);
    List<Coordinate2D> points = new List<Coordinate2D> { pointFromCoordinates, pointToCoordinates };
    //create the polyline
    var lineSegment = PolylineBuilderEx.CreatePolyline(points);

    //specify a symbol
    var line_symbol = SymbolFactory.Instance.ConstructLineSymbol(
                          ColorFactory.Instance.GreenRGB);
    //create a CIMGraphic 
    var graphic = new CIMLineGraphic()
    {
      Symbol = line_symbol.MakeSymbolReference(),
      Line = lineSegment,
    };
    graphicsLayer.AddElement(graphic);
  }

Polygon Graphic Element using CIMGraphic

// Note: must be called on the QueuedTask
  {
    //On the QueuedTask
    //Place a polygon symbol using the mapview extent geometry
    var extent = MapView.Active.Extent;
    //Contract the extent
    var polygonEnv = extent.Expand(-100000, -90000, false);
    //create a polygon using the envelope
    var polygon = PolygonBuilderEx.CreatePolygon(polygonEnv);

    //specify a symbol
    var poly_symbol = SymbolFactory.Instance.ConstructPolygonSymbol(
                          ColorFactory.Instance.GreenRGB);

    //create a CIMGraphic 
    var graphic = new CIMPolygonGraphic()
    {
      Symbol = poly_symbol.MakeSymbolReference(),
      Polygon = polygon,
    };
    graphicsLayer.AddElement(graphic);
  }

Multi-point Graphic Element using CIMGraphic

// Note: must be called on the QueuedTask
  {
    //Place a multipoint graphic using the mapview extent geometry
    var extent = MapView.Active.Extent;
    //Contract the extent
    var polygonEnv = extent.Expand(-100000, -90000, false);
    //create a polygon using the envelope
    var polygon = PolygonBuilderEx.CreatePolygon(polygonEnv);
    //Create MultipPoints from the polygon
    var multiPoints = MultipointBuilderEx.CreateMultipoint(polygon);
    //specify a symbol
    var point_symbol = SymbolFactory.Instance.ConstructPointSymbol(
                          ColorFactory.Instance.GreenRGB);
    //create a CIMGraphic 
    var graphic = new CIMMultipointGraphic
    {
      Symbol = point_symbol.MakeSymbolReference(),
      Multipoint = multiPoints
    };
    graphicsLayer.AddElement(graphic);
  }

Graphic Element using CIMSymbol

// Note: must be called on the QueuedTask
  {
    //Place symbol in the center of the map
    var extent = MapView.Active.Extent;
    var location = extent.Center;

    //specify a symbol
    var pt_symbol = SymbolFactory.Instance.ConstructPointSymbol(
                          ColorFactory.Instance.GreenRGB);
    graphicsLayer.AddElement(location, pt_symbol);
  }

Text Graphic Element

// Note: must be called on the QueuedTask
  {
    //Place symbol in the center of the map
    var extent = MapView.Active.Extent;
    var location = extent.Center;

    //specify a text symbol
    var text_symbol = SymbolFactory.Instance.ConstructTextSymbol
    (ColorFactory.Instance.BlackRGB, 8.5, "Corbel", "Regular");

    graphicsLayer.AddElement(location, text_symbol, "Text Example");
  }

Bulk Graphics creation

//Point Feature layer to convert into graphics
  var lyr = MapView.Active?.Map?.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault(s => s.ShapeType == esriGeometryType.esriGeometryPoint);
  if (lyr == null) return;
  // Note: must be called on the QueuedTask
  {
    //Point symbol for graphics
    var pointSymbol = SymbolFactory.Instance.ConstructPointSymbol(CIMColor.CreateRGBColor(100, 255, 40), 10, SimpleMarkerStyle.Circle);
    //Collection to hold the point graphics
    var listGraphicElements = new List<CIMGraphic>();
    //Iterate through each point feature in the feature layer
    using (RowCursor rows = lyr.Search()) //execute
    {
      int i = 0;
      while (rows.MoveNext())
      {
        using var feature = rows.Current as Feature;
        //Create a point graphic for the feature
        var crimePt = feature.GetShape() as MapPoint;
        if (crimePt != null)
        {
          var cimGraphicElement = new CIMPointGraphic
          {
            Location = crimePt, //MapPoint
            Symbol = pointSymbol.MakeSymbolReference()
          };
          //Add the point feature to the collection
          listGraphicElements.Add(cimGraphicElement);
          i++;
        }
      }
    }
    //Magic happens...Add all the features to the Graphics layer 
    graphicsLayer.AddElements(listGraphicElements);
  }

Graphic Elements Selection

Select Graphic Elements

var elements = graphicsLayer.GetElementsAsFlattenedList()
                      .Where(e => e.Name.StartsWith("Text"));
  // Note: must be called on the QueuedTask
  {
    graphicsLayer.SelectElements(elements);
    //or select one element
    graphicsLayer.SelectElement(elements.FirstOrDefault());
  }

Find Graphic elements

// Note: must be called on the QueuedTask
  {
    //Find elements by name
    var elems = graphicsLayer.FindElements(new List<string>() { "Point 1", "Line 3", "Text 1" });
    //Find elements by type
    //Find all point graphics in the Graphics Layer
    var pointGraphics = graphicsLayer.GetElementsAsFlattenedList().Where(elem => elem.GetGraphic() is CIMPointGraphic);
    //Find all line graphics in the Graphics Layer
    var lineGraphics = graphicsLayer.GetElementsAsFlattenedList().Where(elem => elem.GetGraphic() is CIMLineGraphic);
    //Find all polygon graphics in the Graphics Layer
    var polygonGraphics = graphicsLayer.GetElementsAsFlattenedList().Where(elem => elem.GetGraphic() is CIMPolygonGraphic);
    //Find all text graphics in the Graphics Layer
    var textGraphics = graphicsLayer.GetElementsAsFlattenedList().Where(elem => elem.GetGraphic() is CIMTextGraphic);
    //Find all picture graphics in the Graphics Layer
    var pictureGraphic = graphicsLayer.GetElementsAsFlattenedList().Where(elem => elem.GetGraphic() is CIMPictureGraphic);
  }

Spatial selection of elements in all Graphics Layers

//Map Tool is used to perform Spatial selection.
//Graphic selection uses the selection geometry 
//to intersect the geometries of those elements (graphic or group) 
//that will be selected and then highlights them. 
{
  var selPoly = geometry as Polygon;
  // Note: must be called on the QueuedTask
  {
    //note: the selected elements may belong to more than one layer...
    var elems = MapView.Active.SelectElements(selPoly, SelectionCombinationMethod.New);
  }
}

Spatial selection of elements in one graphics layer

// Note: must be called on the QueuedTask
  {
    //Create an extent to use for the spatial selection
    var extent = MapView.Active.Extent;
    var selectionExtent = extent.Expand(0.5, 0.5, true);
    //Select elements in specified graphics layer using the selection extent.
    var selectedElements = MapView.Active.SelectElements(graphicsLayer, selectionExtent, SelectionCombinationMethod.Add);
  }

Select Text Graphic Elements

var all_text = graphicsLayer.GetElementsAsFlattenedList()
                .Where(e => e.GetGraphic() is CIMTextGraphic);

Un-Select Graphic elements

//unselect the first element in the currently selected elements
  var elem = graphicsLayer.GetSelectedElements().FirstOrDefault();
  // Note: must be called on the QueuedTask
  {
    if (elem != null)
      //Unselect one element
      graphicsLayer.UnSelectElement(elem);

    //unselect all elements
    graphicsLayer.UnSelectElements();
    //equivalent to
    graphicsLayer.ClearSelection();
  }

Graphic Element Events

Subscribe to ElementSelectionChangedEvent

ArcGIS.Desktop.Layouts.Events.ElementEvent.Subscribe((args) =>
  {
    //check if the container is a graphics layer - could be a Layout (or even map view)
    if (args.Container is ArcGIS.Desktop.Mapping.GraphicsLayer graphicsLayer)
    {
      //get the total selection count for the container
      var count = args.Elements.Count();
      //Check count - could have been an unselect or clearselect
      if (count > 0)
      {
        //this is a selection or add to selection
        var elems = graphicsLayer.GetSelectedElements();
        //TODO process the selection...
      }
      else
      {
        //This is an unselect or clear selection
        //TODO process the unselect or clear select
      }
    }
  });

Grouping and Ordering Graphic Elements

Group Graphic Elements

// Note: must be called on the QueuedTask
  {
    var elemsToGroup = graphicsLayer.GetSelectedElements();
    //group  elements
    groupElement = graphicsLayer.GroupElements(elemsToGroup);
  }

Un-Group Graphic Elements

// Note: must be called on the QueuedTask
  {
    var selectedElements = graphicsLayer.GetSelectedElements().ToList(); ;
    if (selectedElements?.Any() == false)//must be at least 1.
      return;
    var elementsToUnGroup = new List<GroupElement>();
    //All selected elements should be grouped.
    if (selectedElements.Count() == selectedElements.OfType<GroupElement>().Count())
    {
      //Convert to a GroupElement list.
      elementsToUnGroup = selectedElements.ConvertAll(x => (GroupElement)x);
    }
    if (elementsToUnGroup.Count() == 0)
      return;
    //UnGroup
    graphicsLayer.UnGroupElements(elementsToUnGroup);
  }

Parent of GroupElement

//check the parent
  var parent = groupElement.Elements.First().GetParent();//will be the group element
                                                         //top-most parent
  var top_most = groupElement.Elements.First().GetParent(true);//will be the GraphicsLayer

Ordering: Send backward and Bring forward

// Note: must be called on the QueuedTask
  {
    //get the current selection set
    var sel_elems = graphicsLayer.GetSelectedElements();
    //can they be brought forward? This will also check that all elements have the same parent
    if (graphicsLayer.CanBringForward(sel_elems))
    {
      //bring forward
      graphicsLayer.BringForward(sel_elems);
      //bring to front (of parent)
      //graphicsLayer.BringToFront(sel_elems);
    }
    else if (graphicsLayer.CanSendBackward(sel_elems))
    {
      //send back
      graphicsLayer.SendBackward(sel_elems);
      //send to the back (of parent)
      //graphicsLayer.SendToBack(sel_elems);
    }
  }

Get Z-Order

// Note: must be called on the QueuedTask
  {
    var selElementsZOrder = graphicsLayer.GetSelectedElements();
    //list out the z order
    foreach (var elem in selElementsZOrder)
      System.Diagnostics.Debug.WriteLine($"{elem.Name}: z-order {elem.ZOrder}");
  }

Modifying Graphic Elements

Move Graphic Elements

// Note: must be called on the QueuedTask
  {
    //Each selected element will move to a set distance to the upper right.
    var selElements = graphicsLayer.GetSelectedElements();
    if (selElements.Count == 0) return;
    //Move the element up
    foreach (var selElement in selElements)
    {
      //Get the element's bounds
      var elementPoly = PolygonBuilderEx.CreatePolygon(selElement.GetBounds());
      //get the coordinates of the element bounding envelope.
      var pointsList = elementPoly.Copy2DCoordinatesToList();
      //Move the element's Anchor point to the upper right.
      selElement.SetAnchorPoint(pointsList[1]);
    }
  }

Modify symbology of a Graphic Element

// Note: must be called on the QueuedTask
  {
    //within a queued Task
    //get the first line element in the layer
    var ge = graphicsLayer.FindElement("Line 10") as GraphicElement;
    var graphic = ge.GetGraphic();
    if (graphic is CIMLineGraphic lineGraphic)
    {
      //change its symbol
      lineGraphic.Symbol =
       SymbolFactory.Instance.ConstructLineSymbol(
         SymbolFactory.Instance.ConstructStroke(
     ColorFactory.Instance.BlueRGB, 2, SimpleLineStyle.DashDot)).MakeSymbolReference();
      //apply the change
      ge.SetGraphic(lineGraphic);
    }
  }
Clone this wiki locally