Skip To Content ArcGIS for Developers Sign In Dashboard

ArcGIS Runtime SDK for .NET

Draw and Edit Graphics

Download Samples Repository

Description

This sample demonstrates drawing and editing map graphics.

"Desktop" "Store" "Phone" Available for Desktop, Store, Phone

Sample Code

<UserControl x:Class="ArcGISRuntime.Samples.Desktop.DrawAndEditGraphics"
		xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		xmlns:esri="http://schemas.esri.com/arcgis/runtime/2013">
	
	<Grid x:Name="LayoutRoot">
		<Grid.Resources>
			<esri:SimpleMarkerSymbol x:Key="SMS" Color="Red" Style="Circle" Size="10" />
			<esri:SimpleLineSymbol x:Key="SLS" Color="Red" Width="5" />
			<esri:SimpleFillSymbol x:Key="SFS" Color="#66FF0000" Style="Solid" />
			<esri:SimpleRenderer x:Key="MarkerRenderer" Symbol="{StaticResource SMS}" />
			<esri:SimpleRenderer x:Key="PolylineRenderer" Symbol="{StaticResource SLS}" />
			<esri:SimpleRenderer x:Key="PolygonRenderer" Symbol="{StaticResource SFS}" />
		</Grid.Resources>
		<esri:MapView x:Name="MyMapView" MapViewTapped="MyMapView_MapViewTapped">
			<esri:Map>
				<esri:Map.InitialViewpoint>
					<esri:ViewpointExtent XMin="-15000000" YMin="2000000" XMax="-7000000" YMax="8000000" />
				</esri:Map.InitialViewpoint>
				<esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer"
											  ServiceUri="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer" />
			</esri:Map>
			<esri:MapView.GraphicsOverlays>
				<esri:GraphicsOverlay ID="PointGraphicsOverlay" Renderer="{StaticResource MarkerRenderer}" />
				<esri:GraphicsOverlay ID="PolylineGraphicsOverlay" Renderer="{StaticResource PolylineRenderer}" />
				<esri:GraphicsOverlay ID="PolygonGraphicsOverlay" Renderer="{StaticResource PolygonRenderer}" />
			</esri:MapView.GraphicsOverlays>
		</esri:MapView>

		<Border Background="White"  BorderThickness="1" CornerRadius="5"
				HorizontalAlignment="Right" VerticalAlignment="Top"
				Margin="10" BorderBrush="Black">
			<StackPanel Orientation="Vertical">
				<TextBlock Text="Instructions" Margin="5" FontSize="16" FontWeight="Bold"/>
				<TextBlock Margin="10" HorizontalAlignment="Center" FontSize="12" TextWrapping="Wrap">
				- Select Shape and click Draw to start drawing. <LineBreak/>
				<LineBreak/>
				- Click on shape to select and click Edit to start editing.<LineBreak/>
				<LineBreak/>
				- Click on Yellow Handles to scale.<LineBreak/>
				<LineBreak/>
				- Click on white midpoints to add a new vertex.<LineBreak/>
				<LineBreak/>
				- Click on Blue Handles to rotate
				</TextBlock>
			</StackPanel>
		</Border>

		<Border Background="White" BorderThickness="1" CornerRadius="5"
				HorizontalAlignment="Left" VerticalAlignment="Top"
				Margin="10" BorderBrush="Black">
			<Grid>
				<Grid.RowDefinitions>
					<RowDefinition Height="Auto"/>
					<RowDefinition Height="Auto"/>
					<RowDefinition Height="Auto"/>
				</Grid.RowDefinitions>
				<StackPanel Orientation="Horizontal" Grid.Row="1">
					<ComboBox x:Name="DrawShapes" 
							  Padding="10" Margin="5"/>
					<Button Content="Draw" Click="OnDrawButtonClicked" 
							Padding="10" Margin="5"/>
					<Button Content="Edit" Click="OnDrawButtonClicked" 
							Padding="10" Margin="5" />
					<Button Content="Undo" Command="{Binding Editor.Undo, ElementName=MyMapView}" 
							Padding="10" Margin="5"/>
					<Button Content="Redo" Command="{Binding Editor.Redo, ElementName=MyMapView}"
							Padding="10" Margin="5"/>
					<Button Content="Cancel" Command="{Binding Editor.Cancel, ElementName=MyMapView}"
							Padding="10" Margin="5"/>
					<Button Content="Complete" Command="{Binding Editor.Complete, ElementName=MyMapView}" 
							Padding="10" Margin="5"/>
					<Button Content="Delete Selected Vertex" Command="{Binding Editor.DeleteVertex, ElementName=MyMapView}" 
							Padding="10" Margin="5"/>
				</StackPanel>
				<StackPanel Orientation="Horizontal" Grid.Row="2" Margin="10">
					<CheckBox x:Name="AddVertex" 
							  Content="AddVertex" IsChecked="True"
							  Margin="5"/>
					<CheckBox x:Name="MoveVertex" 
							  Content="Move Vertex" IsChecked="True" 
							  Margin="5"/>
					<CheckBox x:Name="DeleteVertex" 
							  Content="Delete Vertex" IsChecked="True" 
							  Margin="5"/>
					<CheckBox x:Name="MoveGeometry" 
							  Content="Move Geometry" IsChecked="True"
							  Margin="5"/>
					<CheckBox x:Name="Scale" 
							  Content="Scale" IsChecked="True" 
							  Margin="5"/>
					<CheckBox x:Name="Rotate" 
							  Content="Rotate" IsChecked="True" 
							  Margin="5"/>
					<CheckBox x:Name="MaintainAspectRatio" 
							  Content="Maintain AspectRatio" IsChecked="True"
							  Margin="5"/>
				</StackPanel>
			</Grid>
		</Border>
	</Grid>
</UserControl>
using Esri.ArcGISRuntime.Controls;
using Esri.ArcGISRuntime.Layers;
using Esri.ArcGISRuntime.Symbology;
using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace ArcGISRuntime.Samples.Desktop
{
	/// <summary>
	/// This sample demonstrates drawing and editing map graphics.
	/// </summary>
	/// <title>Draw and Edit Graphics</title>
	/// <category>Editing</category>
	public partial class DrawAndEditGraphics : UserControl
	{
		Graphic _editGraphic = null;

		public DrawAndEditGraphics()
		{
			InitializeComponent();

			DrawShapes.ItemsSource = new DrawShape[]
			{
				DrawShape.Freehand,
				DrawShape.Point,
				DrawShape.Polygon,
				DrawShape.Polyline,
				DrawShape.Arrow,
				DrawShape.Circle,
				DrawShape.Ellipse,
				DrawShape.LineSegment,
				DrawShape.Rectangle
			};
			DrawShapes.SelectedIndex = 0;
		}

		private async void OnDrawButtonClicked(object sender, RoutedEventArgs e)
		{
			string message = null;
			var resultGeometry = _editGraphic == null ? null : _editGraphic.Geometry;

			var editCnfg = MyMapView.Editor.EditorConfiguration;
			editCnfg.AllowAddVertex = AddVertex.IsChecked.HasValue && AddVertex.IsChecked.Value;
			editCnfg.AllowDeleteVertex = DeleteVertex.IsChecked.HasValue && DeleteVertex.IsChecked.Value;
			editCnfg.AllowMoveGeometry = MoveGeometry.IsChecked.HasValue && MoveGeometry.IsChecked.Value;
			editCnfg.AllowMoveVertex = MoveVertex.IsChecked.HasValue && MoveVertex.IsChecked.Value;
			editCnfg.AllowRotateGeometry = Rotate.IsChecked.HasValue && Rotate.IsChecked.Value;
			editCnfg.AllowScaleGeometry = Scale.IsChecked.HasValue && Scale.IsChecked.Value;
			editCnfg.MaintainAspectRatio = MaintainAspectRatio.IsChecked.HasValue && MaintainAspectRatio.IsChecked.Value;
			editCnfg.VertexSymbol =
					new SimpleMarkerSymbol() { Style = SimpleMarkerStyle.Diamond, Color = Colors.Yellow, Size = 15 };

			try
			{
				var drawShape = (DrawShape)DrawShapes.SelectedItem;

				GraphicsOverlay graphicsOverlay;
				graphicsOverlay = drawShape == DrawShape.Point ? MyMapView.GraphicsOverlays["PointGraphicsOverlay"] as GraphicsOverlay :
						   ((drawShape == DrawShape.Polyline || drawShape == DrawShape.Freehand || drawShape == DrawShape.LineSegment) ?
				  MyMapView.GraphicsOverlays["PolylineGraphicsOverlay"] as GraphicsOverlay : MyMapView.GraphicsOverlays["PolygonGraphicsOverlay"] as GraphicsOverlay);

				var progress = new Progress<GeometryEditStatus>();
				progress.ProgressChanged += (a, b) =>
				{
					//if (b.GeometryEditAction == GeometryEditAction..CompletedEdit)
					//    if (_editGraphic != null)
					//        _editGraphic.IsSelected = false;

				};

				var content = (sender as Button).Content.ToString();
				switch (content)
				{
					case "Draw":
						{
							var r = await MyMapView.Editor.RequestShapeAsync(drawShape, null, progress);
							graphicsOverlay.Graphics.Add(new Graphic() { Geometry = r });
							break;
						}
					case "Edit":
						{
							if (_editGraphic == null)
								return;
							var g = _editGraphic;
							g.IsVisible = false;
							var r = await MyMapView.Editor.EditGeometryAsync(g.Geometry, null, progress);
							resultGeometry = r ?? resultGeometry;
							_editGraphic.Geometry = resultGeometry;
							_editGraphic.IsSelected = false;
							break;
						}
				}

			}
			catch (TaskCanceledException)
			{
				// Ignore TaskCanceledException - usually happens if the editor gets cancelled or restarted
			}
			catch (Exception ex)
			{

				message = ex.Message;				
			}
			finally
			{
				if (_editGraphic != null)
				{
					_editGraphic.IsVisible = true;
					_editGraphic = null;
				}
			}
			if (message != null)
				MessageBox.Show(message);
		}

		private async void MyMapView_MapViewTapped(object sender, MapViewInputEventArgs e)
		{
			if (MyMapView.Editor.IsActive)
				return;

			var drawShape = (DrawShape)DrawShapes.SelectedItem;
			GraphicsOverlay graphicsOverlay;
			graphicsOverlay = drawShape == DrawShape.Point ? MyMapView.GraphicsOverlays["PointGraphicsOverlay"] as GraphicsOverlay :
					   ((drawShape == DrawShape.Polyline || drawShape == DrawShape.Freehand || drawShape == DrawShape.LineSegment) ?
			  MyMapView.GraphicsOverlays["PolylineGraphicsOverlay"] as GraphicsOverlay : MyMapView.GraphicsOverlays["PolygonGraphicsOverlay"] as GraphicsOverlay);


			var graphic = await graphicsOverlay.HitTestAsync(MyMapView, e.Position);

			if (graphic != null)
			{
				//Clear previous selection
				foreach (GraphicsOverlay gOLay in MyMapView.GraphicsOverlays)
				{
					gOLay.ClearSelection();
				}

				//Cancel editing if started
				if (MyMapView.Editor.Cancel.CanExecute(null))
					MyMapView.Editor.Cancel.Execute(null);

				_editGraphic = graphic;
				_editGraphic.IsSelected = true;
			}
		}
	}
}
Feedback on this topic?