Editing using a custom form
EditorForm.vb
' Copyright 2012 ESRI
' 
' All rights reserved under the copyright laws of the United States
' and applicable international laws, treaties, and conventions.
' 
' You may freely redistribute and use this sample code, with or
' without modification, provided you include the original copyright
' notice and use restrictions.
' 
' See the use restrictions.
' 


Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
Imports System.Collections

Imports ESRI.ArcGIS.Controls
Imports ESRI.ArcGIS.SystemUI
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.Geometry


Public Class EditorForm

#Region "private members"
    Private m_mainForm As MainForm
    Private m_mapControl As IMapControl3
    Private m_commands As ArrayList
    Private m_engineEditor As IEngineEditor
    Private m_operationStack As IOperationStack
    Private m_pool As ICommandPool
#End Region

    
    Private Sub EditorForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        '*********  Important *************
        ' Obtain a reference to the MainForm using the EditHelper class
        m_mainForm = EditHelper.TheMainForm
        m_mapControl = m_mainForm.MapControl

        axBlankToolBar.SetBuddyControl(m_mapControl)
        axModifyToolbar.SetBuddyControl(m_mapControl)
        axReshapeToolbar.SetBuddyControl(m_mapControl)
        axUndoRedoToolbar.SetBuddyControl(m_mapControl)
        axCreateToolbar.SetBuddyControl(m_mapControl)

        'create and share CommandPool
        m_pool = New CommandPool()
        axCreateToolbar.CommandPool = m_pool
        axBlankToolBar.CommandPool = m_pool
        axModifyToolbar.CommandPool = m_pool
        axReshapeToolbar.CommandPool = m_pool
        axUndoRedoToolbar.CommandPool = m_pool

        'Create and share operation stack
        m_operationStack = New ControlsOperationStackClass()
        axModifyToolbar.OperationStack = m_operationStack
        axReshapeToolbar.OperationStack = m_operationStack
        axUndoRedoToolbar.OperationStack = m_operationStack
        axCreateToolbar.OperationStack = m_operationStack

        'load items for the axModifyToolbar
        axModifyToolbar.AddItem("esriControls.ControlsEditingEditTool", 0, 0, False, 0, esriCommandStyles.esriCommandStyleIconOnly)
        axModifyToolbar.AddItem("VertexCommands_CS.CustomVertexCommands", 1, 1, False, 0, esriCommandStyles.esriCommandStyleIconOnly)
        axModifyToolbar.AddItem("VertexCommands_CS.CustomVertexCommands", 2, 2, False, 0, esriCommandStyles.esriCommandStyleIconOnly)

        'load items for the axReshapeToolbar
        axReshapeToolbar.AddItem("esriControls.ControlsEditingEditTool", 0, 0, False, 0, esriCommandStyles.esriCommandStyleIconOnly)
        axReshapeToolbar.AddItem("esriControls.ControlsEditingSketchTool", 0, 1, False, 0, esriCommandStyles.esriCommandStyleIconOnly)

        'load items for the createtoolbar 
        axCreateToolbar.AddItem("esriControls.ControlsEditingSketchTool", 0, 0, False, 0, esriCommandStyles.esriCommandStyleIconOnly)

        'set up the EngineEditor
        m_engineEditor = New EngineEditorClass()
        m_engineEditor.EnableUndoRedo(True)
        CType(m_engineEditor, IEngineEditProperties2).StickyMoveTolerance = 10000
        Dim tbr As Object = axCreateToolbar.Object
        Dim engineEditorExt As IExtension = CType(m_engineEditor, IExtension)
        engineEditorExt.Startup(tbr) 'ensures that the operationStack will function correctly

        'Listen to OnSketchModified engine editor event
        AddHandler (CType(m_engineEditor, IEngineEditEvents_Event)).OnSketchModified, AddressOf OnSketchModified
        'listen to MainForm events in case application is closed while editing
        AddHandler EditHelper.TheMainForm.FormClosing, AddressOf MainForm_FormClosing

        m_commands = New ArrayList()
        m_commands.Add(cmdModify)
        m_commands.Add(cmdReshape)
        m_commands.Add(cmdCreate)

        DisableButtons()
        txtInfo.Text = ""
        Me.Size = New Size(242, 208)
        Me.FormBorderStyle = Windows.Forms.FormBorderStyle.FixedSingle
        SetErrorLabel("")
        EditHelper.IsEditorFormOpen = True

    End Sub

    Private Sub cmdCreate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdCreate.Click

        Dim edittask As IEngineEditTask = m_engineEditor.GetTaskByUniqueName("ControlToolsEditing_CreateNewFeatureTask")

        If Not edittask Is Nothing Then
            m_engineEditor.CurrentTask = edittask
            axCreateToolbar.CurrentTool = axCreateToolbar.GetItem(0).Command

            SetButtonColours(sender)
            txtInfo.Text = ""
            label1.Text = ""
            Me.flowLayoutPanel1.Controls.Clear()
            Me.flowLayoutPanel1.Controls.Add(axCreateToolbar)
            Me.flowLayoutPanel2.Controls.Clear()
            Me.flowLayoutPanel2.Controls.Add(axUndoRedoToolbar)
        End If

    End Sub

    Private Sub cmdModify_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdModify.Click

        Dim edittask As IEngineEditTask = m_engineEditor.GetTaskByUniqueName("ControlToolsEditing_ModifyFeatureTask")

        If Not edittask Is Nothing Then
            m_engineEditor.CurrentTask = edittask
            axModifyToolbar.CurrentTool = axModifyToolbar.GetItem(0).Command

            SetButtonColours(sender)
            txtInfo.Text = ""
            label1.Text = ""
            Me.flowLayoutPanel1.Controls.Clear()
            Me.flowLayoutPanel1.Controls.Add(axModifyToolbar)
            Me.flowLayoutPanel2.Controls.Clear()
            Me.flowLayoutPanel2.Controls.Add(axUndoRedoToolbar)
        End If

    End Sub

    Private Sub cmdReshape_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdReshape.Click

        Dim edittask As IEngineEditTask = m_engineEditor.GetTaskByUniqueName("ReshapePolylineEditTask_Reshape Polyline_CSharp")

        If Not edittask Is Nothing Then
            m_engineEditor.CurrentTask = edittask
            axReshapeToolbar.CurrentTool = axReshapeToolbar.GetItem(0).Command

            SetButtonColours(sender)
            txtInfo.Text = ""
            label1.Text = ""
            Me.flowLayoutPanel1.Controls.Clear()
            Me.flowLayoutPanel1.Controls.Add(axReshapeToolbar)
            Me.flowLayoutPanel2.Controls.Clear()
            Me.flowLayoutPanel2.Controls.Add(axUndoRedoToolbar)
        End If

    End Sub

    Private Sub cmdEdit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdEdit.Click
        If cmdEdit.Text = "Edit" Then
            Dim featlayer As IFeatureLayer = FindFeatureLayer("usa_major_highways")

            If Not featlayer Is Nothing Then
                m_engineEditor.StartEditing((CType(featlayer.FeatureClass, IDataset)).Workspace, m_mapControl.Map)
                Dim editLayer As IEngineEditLayers = CType(m_engineEditor, IEngineEditLayers)
                editLayer.SetTargetLayer(featlayer, 0)
                EnableButtons()

                cmdEdit.Text = "Finish"
                Dim color As Color = color.Red
                cmdEdit.BackColor = color
                cmdCreate_Click(cmdCreate, Nothing)
            End If
        Else
            SaveEdits()
            DisableButtons()
            cmdEdit.Text = "Edit"
            Dim color As Color = color.White
            cmdEdit.BackColor = color
            SetErrorLabel("")
        End If

    End Sub

    Private Sub EditorForm_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        CleanupOnFormClose()
    End Sub

    Private Sub MainForm_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        CleanupOnFormClose()
    End Sub

    Private Sub OnSketchModified()
        If (IsHighwaysEditValid) Then
            SetErrorLabel("")
        Else
            m_operationStack.Undo()
            SetErrorLabel("Invalid Edit")
        End If

    End Sub


#Region "private form and button management"


    Private Sub SetSelectableLayerStatus(ByVal enable As Boolean)
        Dim map As IMap = m_mapControl.Map
        'get the workspace to edit
        Dim i As Integer
        For i = 0 To map.LayerCount - 1 - 1 Step i + 1
            Dim layer As IFeatureLayer = CType(map.get_Layer(i), IFeatureLayer)
            layer.Selectable = enable

        Next
    End Sub


    Private Sub SetErrorLabel(ByVal message As String)
        label1.Text = message
    End Sub

    Private Sub DisableButtons()
        cmdReshape.Enabled = False
        cmdCreate.Enabled = False
        cmdModify.Enabled = False

        Dim button As Button
        For Each button In m_commands
            Dim color As Color = Color.White
            button.BackColor = color
        Next
    End Sub

    Private Sub EnableButtons()
        cmdReshape.Enabled = True
        cmdCreate.Enabled = True
        cmdModify.Enabled = True
    End Sub

    Private Sub SetButtonColours(ByVal clickedButton As Button)

        Dim color As Color

        Dim button As Button
        For Each button In m_commands
            If clickedButton Is button Then
                color = color.ForestGreen
            Else
                color = color.White
            End If

            button.BackColor = color

        Next
    End Sub

    Private Sub SetInfoLabel(ByVal sender As Object, ByVal index As Integer)
        Dim toolbarControl As AxToolbarControl = sender
        Dim toolbar As IToolbarControl2 = CType(toolbarControl.Object, IToolbarControl2)
        Dim item As IToolbarItem = toolbar.GetItem(index)
        Dim command As ICommand = item.Command
        txtInfo.Text = command.Message
    End Sub

    Private Sub axModifyToolbar_OnItemClick(ByVal sender As Object, ByVal e As IToolbarControlEvents_OnItemClickEvent)

        SetInfoLabel(sender, e.index)
    End Sub

    Private Sub axReshapeToolbar_OnItemClick(ByVal sender As Object, ByVal e As IToolbarControlEvents_OnItemClickEvent)
        SetInfoLabel(sender, e.index)
    End Sub

#End Region

#Region "private helper methods/properties"

    Private Sub CleanupOnFormClose()

        If (m_engineEditor.EditState = esriEngineEditState.esriEngineStateEditing) Then

            SaveEdits()
        End If

        EditHelper.IsEditorFormOpen = False

        'unregister the event handler
        RemoveHandler (CType(m_engineEditor, IEngineEditEvents_Event)).OnSketchModified, AddressOf OnSketchModified

    End Sub

    Private Sub SaveEdits()

        Dim saveEdits As Boolean = False

        If (m_engineEditor.HasEdits()) Then

            Dim message As String = "Do you wish to save edits?"
            Dim caption As String = "Save Edits"
            Dim buttons As MessageBoxButtons = MessageBoxButtons.YesNo
            Dim result As DialogResult

            result = MessageBox.Show(message, caption, buttons)

            If (result = DialogResult.Yes) Then
                saveEdits = True

            End If

            m_engineEditor.StopEditing(saveEdits)
        End If
    End Sub


    Private Function FindFeatureLayer(ByVal name As String) As IFeatureLayer

        Dim foundLayer As IFeatureLayer = Nothing
        Dim dataset As IDataset = Nothing
        Dim map As IMap = m_mapControl.Map

        Dim i As Integer
        For i = 0 To map.LayerCount - 1 Step i + 1
            Dim layer As IFeatureLayer = CType(map.Layer(i), IFeatureLayer)
            dataset = CType(layer.FeatureClass, IDataset)
            If (dataset.Name = name) Then

                foundLayer = layer
                Exit For
            End If

        Next

        Return foundLayer
    End Function


    Private ReadOnly Property IsHighwaysEditValid() As Boolean
        Get
            'put in all business logic here
            'In this example highways are not allowed to intersect the lakes layer
            Dim success As Boolean = True

            'get the edit sketch
            Dim editsketch As IEngineEditSketch = CType(m_engineEditor, IEngineEditSketch)

            'get the protected areas layer
            Dim lakesLayer As IFeatureLayer = FindFeatureLayer("us_lakes")

            'do a spatial filter 
            If Not editsketch Is Nothing And Not lakesLayer Is Nothing And Not editsketch.Geometry Is Nothing Then

                Dim cursor As IFeatureCursor = FindFeatures(editsketch.Geometry, lakesLayer.FeatureClass, esriSpatialRelEnum.esriSpatialRelIntersects, m_mapControl.Map)
                Dim feat As IFeature = cursor.NextFeature()

                'could put more sophisticated logic in here
                If Not feat Is Nothing Then
                    success = False
                End If

            End If
            Return success
        End Get
    End Property

    Private Function FindFeatures(ByVal geomeTry As IGeometry, ByVal featureClass As IFeatureClass, ByVal spatialRelationship As esriSpatialRelEnum, ByVal map As IMap) As IFeatureCursor

        Try
            '1 = esriSpatialRelIntersects
            '7 = esriSpatialWithin
            '8 = esriSpatialRelContains

            Dim spatialFilter As ISpatialFilter = New SpatialFilter()
            spatialFilter.Geometry = geomeTry
            spatialFilter.GeometryField = featureClass.ShapeFieldName
            spatialFilter.SpatialRel = spatialRelationship

            Dim featureCursor As IFeatureCursor = featureClass.Search(spatialFilter, False)
            Return featureCursor
        Catch ex As Exception
            System.Diagnostics.Debug.WriteLine(ex.Message)
            Return Nothing
        End Try
    End Function

#End Region

End Class