About the Editing using a custom form Sample
[C#]
EditorForm.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Collections; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.SystemUI; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.Geometry; namespace EditingUsingCustomForm { public partial class EditorForm : Form { #region private members private MainForm m_mainForm; private IMapControl3 m_mapControl; private ArrayList m_commands; private IEngineEditor m_engineEditor; private IOperationStack m_operationStack; private ICommandPool m_pool; #endregion public EditorForm() { InitializeComponent(); } private void EditorForm_Load(object sender, EventArgs e) { //********* Important ************* //Obtain a reference to the MainForm using the EditHelper class m_mainForm = EditHelper.TheMainForm; m_mapControl = m_mainForm.MapControl; //buddy the toolbars with the MapControl axBlankToolBar.SetBuddyControl(m_mapControl); axModifyToolbar.SetBuddyControl(m_mapControl); axReshapeToolbar.SetBuddyControl(m_mapControl); axUndoRedoToolbar.SetBuddyControl(m_mapControl); axCreateToolbar.SetBuddyControl(m_mapControl); //Create and share command pool m_pool = new CommandPoolClass(); 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 axCreateToolbar axCreateToolbar.AddItem("esriControls.ControlsEditingSketchTool", 0, 0, false, 0, esriCommandStyles.esriCommandStyleIconOnly); //set up the EngineEditor m_engineEditor = new EngineEditorClass(); m_engineEditor.EnableUndoRedo(true); ((IEngineEditProperties2)m_engineEditor).StickyMoveTolerance = 10000; object tbr = (object)axCreateToolbar.Object; IExtension engineEditorExt = m_engineEditor as IExtension; engineEditorExt.Startup(ref tbr); //ensures that the operationStack will function correctly //Listen to OnSketchModified engine editor event ((IEngineEditEvents_Event)m_engineEditor).OnSketchModified += new IEngineEditEvents_OnSketchModifiedEventHandler(OnSketchModified); //listen to MainForm events in case application is closed while editing EditHelper.TheMainForm.FormClosing += new FormClosingEventHandler(TheMainForm_FormClosing); #region Form Management m_commands = new ArrayList(); m_commands.Add(cmdModify); m_commands.Add(cmdReshape); m_commands.Add(cmdCreate); DisableButtons(); txtInfo.Text = ""; this.Size = new Size(242, 208); this.FormBorderStyle = FormBorderStyle.FixedSingle; SetErrorLabel(""); EditHelper.IsEditorFormOpen = true; #endregion } private void cmdCreate_Click(object sender, EventArgs e) { IEngineEditTask edittask = m_engineEditor.GetTaskByUniqueName("ControlToolsEditing_CreateNewFeatureTask"); if (edittask != null) { m_engineEditor.CurrentTask = edittask; axCreateToolbar.CurrentTool = axCreateToolbar.GetItem(0).Command as ITool; SetButtonColors(sender as Button); txtInfo.Text = ""; label1.Text = ""; this.flowLayoutPanel1.Controls.Clear(); this.flowLayoutPanel1.Controls.Add(axCreateToolbar); this.flowLayoutPanel2.Controls.Clear(); this.flowLayoutPanel2.Controls.Add(axUndoRedoToolbar); } } private void cmdModify_Click(object sender, EventArgs e) { IEngineEditTask edittask = m_engineEditor.GetTaskByUniqueName("ControlToolsEditing_ModifyFeatureTask"); if (edittask != null) { m_engineEditor.CurrentTask = edittask; axModifyToolbar.CurrentTool = axModifyToolbar.GetItem(0).Command as ITool; SetButtonColors(sender as Button); txtInfo.Text = ""; label1.Text = ""; this.flowLayoutPanel1.Controls.Clear(); this.flowLayoutPanel1.Controls.Add(axModifyToolbar); this.flowLayoutPanel2.Controls.Clear(); this.flowLayoutPanel2.Controls.Add(axUndoRedoToolbar); } } private void cmdReshape_Click(object sender, EventArgs e) { IEngineEditTask edittask = m_engineEditor.GetTaskByUniqueName("ReshapePolylineEditTask_Reshape Polyline_CSharp"); if (edittask != null) { m_engineEditor.CurrentTask = edittask; axReshapeToolbar.CurrentTool = axReshapeToolbar.GetItem(0).Command as ITool; SetButtonColors(sender as Button); txtInfo.Text = ""; label1.Text = ""; this.flowLayoutPanel1.Controls.Clear(); this.flowLayoutPanel1.Controls.Add(axReshapeToolbar); this.flowLayoutPanel2.Controls.Clear(); this.flowLayoutPanel2.Controls.Add(axUndoRedoToolbar); } } private void cmdEdit_Click(object sender, EventArgs e) { if (cmdEdit.Text == "Edit") { IFeatureLayer featlayer = FindFeatureLayer("usa_major_highways"); if (featlayer != null) { m_engineEditor.StartEditing(((IDataset)featlayer.FeatureClass).Workspace, m_mapControl.Map); IEngineEditLayers editLayer = (IEngineEditLayers)m_engineEditor; editLayer.SetTargetLayer(featlayer,0); EnableButtons(); cmdEdit.Text = "Finish"; Color color = Color.Red; cmdEdit.BackColor = color; cmdCreate_Click(cmdCreate, null); } } else { SaveEdits(); DisableButtons(); cmdEdit.Text = "Edit"; Color color = Color.White; cmdEdit.BackColor = color; SetErrorLabel(""); } } private void EditorForm_FormClosing(object sender, FormClosingEventArgs e) { CleanupOnFormClose(); } void TheMainForm_FormClosing(object sender, FormClosingEventArgs e) { CleanupOnFormClose(); } void OnSketchModified() { if (IsHighwaysEditValid) { SetErrorLabel(""); } else { m_operationStack.Undo(); SetErrorLabel("Invalid Edit"); } } #region private form and button management private void SetSelectableLayerStatus(bool enable) { IMap map = m_mapControl.Map; for (int i = 0; i < map.LayerCount - 1; i++) { IFeatureLayer layer = (IFeatureLayer)map.get_Layer(i); layer.Selectable = enable; } } private void SetErrorLabel(string message) { label1.Text = message; } private void DisableButtons() { cmdReshape.Enabled = false; cmdCreate.Enabled = false; cmdModify.Enabled = false; foreach (Button button in m_commands) { Color color = Color.White; button.BackColor = color; } } private void EnableButtons() { cmdReshape.Enabled = true; cmdCreate.Enabled = true; cmdModify.Enabled = true; } private void SetButtonColors(Button clickedButton) { Color color; foreach (Button button in m_commands) { if (clickedButton == button) { color = Color.ForestGreen; } else { color = Color.White; } button.BackColor = color; } } private void SetInfoLabel(object sender, int index) { AxToolbarControl toolbarControl = sender as AxToolbarControl; IToolbarControl2 toolbar = toolbarControl.Object as IToolbarControl2; IToolbarItem item = toolbar.GetItem(index); ICommand command = item.Command; txtInfo.Text = command.Message; } private void axModifyToolbar_OnItemClick(object sender, IToolbarControlEvents_OnItemClickEvent e) { SetInfoLabel(sender, e.index); } private void axReshapeToolbar_OnItemClick(object sender, IToolbarControlEvents_OnItemClickEvent e) { SetInfoLabel(sender, e.index); } #endregion #region private helper methods/properties private void CleanupOnFormClose() { if (m_engineEditor.EditState == esriEngineEditState.esriEngineStateEditing) { SaveEdits(); } EditHelper.IsEditorFormOpen = false; //unregister the event handlers ((IEngineEditEvents_Event)m_engineEditor).OnSketchModified -= new IEngineEditEvents_OnSketchModifiedEventHandler(OnSketchModified); EditHelper.TheMainForm.FormClosing -= new FormClosingEventHandler(TheMainForm_FormClosing); } private void SaveEdits() { bool saveEdits = false; if (m_engineEditor.HasEdits()) { string message = "Do you wish to save your edits?"; string caption = "Save Edits"; MessageBoxButtons buttons = MessageBoxButtons.YesNo; DialogResult result; result = MessageBox.Show(message, caption, buttons); if (result == DialogResult.Yes) { saveEdits = true; } } m_engineEditor.StopEditing(saveEdits); } private IFeatureLayer FindFeatureLayer(string name) { IFeatureLayer foundLayer = null; IDataset dataset = null; IMap map = m_mapControl.Map; for (int i = 0; i < map.LayerCount; i++) { IFeatureLayer layer = (IFeatureLayer)map.get_Layer(i); dataset = (IDataset)layer.FeatureClass; if (dataset.Name == name) { foundLayer = layer; break; } } return foundLayer; } private bool IsHighwaysEditValid { get { //put in all business logic here //In this example highways are not allowed to intersect the lakes layer bool success = true; //get the edit sketch IEngineEditSketch editsketch = (IEngineEditSketch)m_engineEditor; //get the protected areas layer IFeatureLayer lakesLayer = FindFeatureLayer("us_lakes"); //do a spatial filter if ((editsketch != null) && (lakesLayer != null) && (editsketch.Geometry !=null)) { IFeatureCursor cursor = FindFeatures(editsketch.Geometry, lakesLayer.FeatureClass, esriSpatialRelEnum.esriSpatialRelIntersects, m_mapControl.Map); IFeature feature = cursor.NextFeature(); //could put more sophisticated logic in here if (feature != null) success = false; } return success; } } private IFeatureCursor FindFeatures(IGeometry geometry, IFeatureClass featureClass, esriSpatialRelEnum spatialRelationship, IMap map) { //1 = esriSpatialRelIntersects //7 = esriSpatialWithin //8 = esriSpatialRelContains ISpatialFilter spatialFilter = new SpatialFilter(); spatialFilter.Geometry = geometry; spatialFilter.set_OutputSpatialReference(featureClass.ShapeFieldName, map.SpatialReference); spatialFilter.GeometryField = featureClass.ShapeFieldName; spatialFilter.SpatialRel = spatialRelationship; IFeatureCursor featureCursor = featureClass.Search(spatialFilter, false); return featureCursor; } #endregion } }
[Visual Basic .NET]
EditorForm.vb
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