How to add features to a graphics layer
Once you've created a graphics layer (as described in How to add a graphics layer), you need to add graphics to it to display data. In most cases, you'll create graphics using geometries that have been created by actions such as executing a query or drawing a shape on the map. To add a graphic, you need to do the following:
- Retrieve the GraphicsLayer where the graphic will be added (from the Map.Layers collection)
- Ensure there is a renderer for the GraphicsLayer (or set the symbol directly on the graphic)
- Create or retrieve a graphic.
- Set the graphic's geometry (if it's not already set).
- Add the graphic to the GraphicsLayer.
Adding graphic features
While it's possible to add graphics to a map using Extensible Application Markup Language (XAML), you'll usually use .NET code (that is, code-behind). The following steps show how to add graphic features:
- Create an ArcGIS Runtime SDK for WPF application with a Map and a GraphicsLayer. Alternatively you can create a GraphicsLayer in code. Your ContentPanel XAML should look as follows:
<Grid x:Name="ContentPanel" Grid.Row="1"> <esri:Map x:Name="MyMap" Extent="-120, 20, -100, 40"> <esri:Map.Layers> <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer" Url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"> </esri:ArcGISTiledMapServiceLayer> <esri:GraphicsLayer ID="MyGraphicsLayer"/> </esri:Map.Layers> </esri:Map> </Grid>
Caution:Don't forget to add a reference to System.Runtime.Serialization in your project.
- In your code get a reference to the GraphicsLayer form the Map.Layers collection.
GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer;
- In many cases, you'll get a reference to a graphic or a list of graphics by handling the events of objects such as tasks. In other instances, such as with draw surfaces, you'll create a graphic from a geometry. The code that follows assumes that you already have a reference to a list of graphics and stored them in a variable called resultsOfQuery which is a common scenario when using the API and means that you can use the optimized AddRange method to add the collection of Graphics to the GraphicsLayer. If using this approach you should ensure the GraphicsLayer has a renderer (the recommended approach as opposed to individual symbol instances).
GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer; graphicsLayer.Renderer = new SimpleRenderer() { Symbol = new SimpleMarkerSymbol() { Color = new SolidColorBrush(Colors.Red), Size = 12, Style = SimpleMarkerSymbol.SimpleMarkerStyle.Square, } }; graphicsLayer.Graphics.AddRange(resultsOfQuery);
- In other cases, you might want to iterate the collection of graphics to assign individual Graphic properties before adding them to the GraphicsLayer, such as adding or modifying attributes or perhaps setting the selected state. In this scenario you should iterate the Graphics collection then still call the AddRange method to add those Graphics to the layer.
- The objects that you want to display in the GraphicsLayer might come from elsewhere and may not be in a form you can add directly to the layer. You can iterate your collection of objects, creating a new Graphic instance and set the relevant properties on each Graphic before adding again to a generic collection of graphics before adding them to the layer:
GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer; List<Graphic> graphicsList = new List<Graphic>(); foreach (var item in myCollectionOfObjects) { Graphic graphic = new Graphic(); graphic.Geometry = new MapPoint(item.Longitude, item.Latitude); graphicsList.Add(graphic); } graphicsLayer.Graphics.AddRange(graphicsList);
- If you do need to apply symbols individually to Graphics you can do so by setting the Symbol property. The following code assumes that a symbol with the key MySymbol has been declared as a resource in the XAML. For information about creating symbols, see Symbols and renderers. This code also adds the graphic directly to the GraphicsLayer, which is only recommended when you are dealing with a small number of objects.
GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer; foreach (Graphic graphic in resultsOfQuery) { graphic.Symbol = MyMap.Resources["MySymbol"] as Symbol; graphicsLayer.Graphics.Add(graphic); }
Caution:If you have a renderer set on your GraphicsLayer, and the GraphicsLayer.RendererTakesPrecedence property is set to true (which is the default), the symbols set on individual graphics will be overwritten by the renderer. Set RendererTakesPrecendence to false to use the symbols set on individual graphics and only apply the renderer to the graphics without a symbol set. However, you should always try to assign a Renderer to the entire GraphicsLayer rather than assign symbols individually to each Graphic because this ensures reuse of symbol instances across the Graphics. You should also take care not to create Symbols within loops since that will create many symbol instances and will lead to poor performance.