Edit Tools - Geometry Online

This sample demonstrates using the ESRI.ArcGIS.Client.EditGeometry class for explicit control over the editing experience of an existing graphic. A set of methods initiate actions to start, stop, cancel, undo, and redo edits on a graphic's geometry. Symbols to represent vertices and handles (used to rotate, scale, and move geometry) can be explicitly defined. The GeometryEdit event can be used to track each action that occurs. Snapping to other graphic geometry is supported. If the graphics are associated with an editable feature layer hosted by a feature service, edits will be pushed back to the server upon completion.

To use the sample, click on the polygon or line feature and begin editing. EditGeometry only supports polygon or line geometry. Some code logic to edit the geometry of an existing point feature is included, but it does not leverage EditGeometry and is merely meant to provide an example of simple editing of point geometry can be accomplished.

Download Sample Application
XAML C# VB.NET
<UserControl x:Class="ArcGISWPFSDK.EditToolsGeometry"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:esri="http://schemas.esri.com/arcgis/client/2009">

    <Grid x:Name="LayoutRoot" Background="White">

        <Grid.Resources>
            <ControlTemplate x:Key="EditVertexSymbol">
                <Ellipse x:Name="root" Width="7" Height="7" Cursor="Hand" Stroke="Black" StrokeThickness="0" Fill="Yellow">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Unselected" />
                            <VisualState x:Name="Selected">
                                <Storyboard>
                                    <DoubleAnimation BeginTime="00:00:00" Storyboard.TargetName="root" Storyboard.TargetProperty="StrokeThickness" To="1" Duration="0" />
                                    <ColorAnimation BeginTime="00:00:00" Storyboard.TargetName="root" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" To="Transparent" Duration="0" />
                                    <ObjectAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="root" Storyboard.TargetProperty="(FrameworkElement.Cursor)">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Cursor>None</Cursor>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Ellipse>
            </ControlTemplate>
            <LinearGradientBrush x:Key="PanelGradient" EndPoint="0.5,1" StartPoint="0.5,0">
                <LinearGradientBrush.RelativeTransform>
                    <TransformGroup>
                        <ScaleTransform CenterY="0.5" CenterX="0.5"/>
                        <SkewTransform CenterY="0.5" CenterX="0.5"/>
                        <RotateTransform Angle="176" CenterY="0.5" CenterX="0.5"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </LinearGradientBrush.RelativeTransform>
                <GradientStop Color="#FF145787"/>
                <GradientStop Color="#FF3D7FAC" Offset="0.184"/>
                <GradientStop Color="#FF88C5EF" Offset="0.984"/>
            </LinearGradientBrush>

            <esri:MarkerSymbol x:Key="EditMarkerSymbol" OffsetX="9" OffsetY="9">
                <esri:MarkerSymbol.ControlTemplate>
                    <ControlTemplate>
                        <Ellipse x:Name="root" Width="18" Height="18" Cursor="Hand" Stroke="Black" StrokeThickness="0" Fill="Blue">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="SelectionStates">
                                    <VisualState x:Name="Unselected" />
                                    <VisualState x:Name="Selected">
                                        <Storyboard>
                                            <DoubleAnimation BeginTime="00:00:00" Storyboard.TargetName="root" Storyboard.TargetProperty="StrokeThickness" To="1" Duration="0" />
                                            <ColorAnimation BeginTime="00:00:00" Storyboard.TargetName="root" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" To="Transparent" Duration="0" />
                                            <ObjectAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="root" Storyboard.TargetProperty="(FrameworkElement.Cursor)">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Cursor>None</Cursor>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>

                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                        </Ellipse>
                    </ControlTemplate>
                </esri:MarkerSymbol.ControlTemplate>
            </esri:MarkerSymbol>

            <ControlTemplate x:Key="ScalePointSymbol">
                <Ellipse x:Name="root" Width="10" Height="10" Cursor="Hand" Stroke="Black" StrokeThickness="0.5" Fill="Red">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Unselected" />
                            <VisualState x:Name="Selected">
                                <Storyboard>
                                    <DoubleAnimation BeginTime="00:00:00" Storyboard.TargetName="root" Storyboard.TargetProperty="StrokeThickness" To="1" Duration="0" />
                                    <ColorAnimation BeginTime="00:00:00" Storyboard.TargetName="root" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" To="Yellow" Duration="0" />
                                    <ObjectAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="root" Storyboard.TargetProperty="(FrameworkElement.Cursor)">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Cursor>None</Cursor>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>

                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Ellipse>
            </ControlTemplate>

            <ControlTemplate x:Key="RotatePointSymbol">
                <Grid  Width="10" Height="20"  x:Name="root" Cursor="Hand" >
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Ellipse x:Name="rect" Stroke="Black" StrokeThickness="0.5" Fill="Green"/>
                    <Rectangle Width="1" Grid.Row="1" Fill="Black" HorizontalAlignment="Center" />
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Unselected" />
                            <VisualState x:Name="Selected">
                                <Storyboard>
                                    <DoubleAnimation BeginTime="00:00:00" Storyboard.TargetName="rect" Storyboard.TargetProperty="StrokeThickness" To="1" Duration="0" />
                                    <ColorAnimation BeginTime="00:00:00" Storyboard.TargetName="rect" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" To="Yellow" Duration="0" />
                                    <ObjectAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="root" Storyboard.TargetProperty="(FrameworkElement.Cursor)">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Cursor>None</Cursor>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>

                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Grid>
            </ControlTemplate>

            <ControlTemplate x:Key="EditLineSymbol">
                <Path x:Name="Element"
                    Stroke="{Binding Symbol.Color}"
                    StrokeStartLineCap="Round"
                    StrokeThickness="{Binding Symbol.Width}"
                    StrokeLineJoin="Round"
                    StrokeEndLineCap="Round"
                    StrokeDashArray="3 2" 
                    Fill="{x:Null}" />
            </ControlTemplate>

            <esri:MarkerSymbol x:Key="MyVertexSymbol" ControlTemplate="{StaticResource EditVertexSymbol}" OffsetX="3.5" OffsetY="3.5"/>
            <esri:MarkerSymbol x:Key="MyScaleSymbol" ControlTemplate="{StaticResource ScalePointSymbol}" OffsetX="5" OffsetY="5"/>
            <esri:MarkerSymbol x:Key="MyRotateSymbol" ControlTemplate="{StaticResource RotatePointSymbol}" OffsetX="5" OffsetY="20"/>
            <esri:LineSymbol x:Key="MyScaleBox" ControlTemplate="{StaticResource EditLineSymbol}" Color="Black" Width="5"/>
            <esri:EditGeometry x:Key="MyEditGeometry"                                
                               IsEnabled="True" 
                               GeometryEdit="EditGeometry_GeometryEdit" 
                               VertexSymbol="{StaticResource MyVertexSymbol}"                               
                               ScalePointSymbol="{StaticResource MyScaleSymbol}"
                               ScaleBoxSymbol="{StaticResource MyScaleBox}"
                               RotatePointSymbol="{StaticResource MyRotateSymbol}"/>

        </Grid.Resources>

        <esri:Map x:Name="MyMap" Extent="-16574645.619,-5541958.774,13341035.686,10559275.713" Loaded="MyMap_Loaded"
                  esri:Editor.SnapDistance="30"
                  MouseClick="MyMap_MouseClick" 
                  MouseMove="MyMap_MouseMove"
                  MouseLeftButtonUp="MyMap_MouseLeftButtonUp">
            <esri:ArcGISTiledMapServiceLayer Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer"/>
            <esri:GraphicsLayer ID="MyGraphicsLayer" 
                                Initialized="GraphicsLayer_Initialized" 
                                MouseLeftButtonDown="GraphicsLayer_MouseLeftButtonDown">
                <esri:GraphicsLayer.Graphics>
                    <esri:Graphic>
                        <esri:Polygon>
                            <esri:Polygon.Rings>
                                <esri:PointCollection>
                                    <esri:MapPoint X="-50.039" Y="-10.303" />
                                    <esri:MapPoint X="-62.539" Y="3.0137" />
                                    <esri:MapPoint X="-83.281" Y="-3.923" />
                                    <esri:MapPoint X="-102.773" Y="-25.174" />
                                    <esri:MapPoint X="-73.594" Y="-33.180" />
                                    <esri:MapPoint X="-51.797" Y="-26.032" />
                                    <esri:MapPoint X="-50.039" Y="-10.303" />
                                </esri:PointCollection>
                            </esri:Polygon.Rings>
                        </esri:Polygon>
                        <esri:Graphic.Symbol>
                            <esri:SimpleFillSymbol Fill="#660000FF" BorderBrush="Blue" BorderThickness="1" />
                        </esri:Graphic.Symbol>
                    </esri:Graphic>
                    <esri:Graphic>
                        <esri:Polyline >
                            <esri:Polyline.Paths>
                                <esri:PointCollection>
                                    <esri:MapPoint X="0" Y="51.399" />
                                    <esri:MapPoint X="2.637" Y="48.865" />
                                    <esri:MapPoint X="12.568" Y="41.706" />
                                    <esri:MapPoint X="13.447" Y="52.483" />
                                    <esri:MapPoint X="21.357" Y="52.160" />
                                    <esri:MapPoint X="30.322" Y="59.845" />
                                </esri:PointCollection>
                            </esri:Polyline.Paths>
                        </esri:Polyline>
                        <esri:Graphic.Symbol>
                            <esri:SimpleLineSymbol Color="Blue" Width="3" Style="Dash" />
                        </esri:Graphic.Symbol>
                    </esri:Graphic>
                    <esri:Graphic Symbol="{StaticResource EditMarkerSymbol}">
                        <esri:MapPoint X="-96.8" Y="32.7833" />
                    </esri:Graphic>
                </esri:GraphicsLayer.Graphics>
            </esri:GraphicsLayer>
        </esri:Map>

        <Border Background="{StaticResource PanelGradient}" BorderThickness="1" CornerRadius="5"
                HorizontalAlignment="Right"  VerticalAlignment="Top"
                Padding="5" BorderBrush="Black" Margin="0,5,5,0"
                DataContext="{StaticResource MyEditGeometry}">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>

                <StackPanel x:Name="EditGeometryTools" Orientation="Vertical" Grid.Row="0">
                    <StackPanel Orientation="Horizontal" Margin="2">
                        <Button x:Name="StopEdit" Content="Stop" Click="StopEdit_Click" Margin="2"/>
                        <Button x:Name="CancelEdit" Content="Cancel" Click="CancelEdit_Click" Margin="2"/>
                        <Button x:Name="UndoLastEdit" Content="Undo" Click="UndoLastEdit_Click" Margin="2"/>
                        <Button x:Name="RedoLastEdit" Content="Redo" Click="RedoLastEdit_Click" Margin="2"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" Margin="2">
                        <CheckBox Content="Enable Editing" IsChecked="{Binding IsEnabled, Mode=TwoWay}" Margin="2" Foreground="White"/>
                        <CheckBox Content="Edit Vertices" IsChecked="{Binding EditVerticesEnabled, Mode=TwoWay}" Margin="2" Foreground="White"/>
                        <CheckBox Content="Move" IsChecked="{Binding MoveEnabled, Mode=TwoWay}" Margin="2" Foreground="White"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" Margin="2">
                        <CheckBox Content="Scale" IsChecked="{Binding ScaleEnabled, Mode=TwoWay}" Margin="2" Foreground="White"/>
                        <CheckBox Content="Rotate" IsChecked="{Binding RotateEnabled, Mode=TwoWay}" Margin="2" Foreground="White"/>
                        <CheckBox Content="Maintain Aspect Ratio" IsChecked="{Binding MaintainAspectRatio, Mode=TwoWay}" Margin="2" Foreground="White"/>
                    </StackPanel>
                </StackPanel>
                <TextBlock Text="Edit Actions" Margin="2" Grid.Row="1" Foreground="White"/>
                <TextBox x:Name="ActionTextBox" Grid.Row="2" FontSize="12" Height="150"  
                         VerticalScrollBarVisibility="Visible" />
            </Grid>
        </Border>

    </Grid>
</UserControl>

Sample code usage restrictions
5/16/2014