Common Custom EditorTask
Common_CustomEditorTask_VBNet\CustomEditorTask_VBNet\CustomSnappingPanel.vb
' Copyright 2010 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 Microsoft.VisualBasic
Imports System
Namespace CustomEditorTask_VBNet
  Public Class CustomSnappingPanel
    Inherits ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorPanel
    #Region "Instance Variable Declarations"

    Friend Const DEFAULT_SNAP_TOL_MAPUNITS As Double = 50.0
    Private m_toleranceTableCell As System.Web.UI.WebControls.TableCell = Nothing

    #End Region

    #Region "Constructor"

    ' Implement a constructor to have the custom snapping panel not be expanded by default
    Public Sub New(ByVal editorTask As ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorTask)
      MyBase.New("Snapping Panel", editorTask, "customSnappingPanel")
      Me.Expanded = False
    End Sub

    #End Region

    #Region "WebControl Life Cycle Event Overrides"

    Protected Overrides Sub OnInit(ByVal eventArgs As System.EventArgs)
      MyBase.OnInit(eventArgs)

      ' Make sure the custom editor task uses map units for snapping and the editor's map is not
      ' null before wiring the scale changed event
      If Me.CustomEditorTaskInstance.UseMapUnitsForSnapping AndAlso Not Me.ParentEditor.Map Is Nothing Then
        ' Change snap tolerance when map scale changes, if using map units to define tolerance.
        AddHandler ParentEditor.Map.ScaleChanged, AddressOf Map_ScaleChanged
      End If
    End Sub

    Protected Overrides Sub OnPreRender(ByVal eventArgs As System.EventArgs)
      MyBase.OnPreRender(eventArgs)

      ' Convert snap tolerance from map units to pixels when rendered, if necessary.
      If Me.CustomEditorTaskInstance.UseMapUnitsForSnapping Then
        Me.CustomEditorTaskInstance.SnapTolerance = ConvertSnapToleranceMapUnitsToPixels(Me.ParentEditor.Map, Me.CustomEditorTaskInstance.SnapToleranceMapUnits)
      End If

      ' If Width not set, set it.
      If Width = System.Web.UI.WebControls.Unit.Empty Then
        Width = New System.Web.UI.WebControls.Unit(300, System.Web.UI.WebControls.UnitType.Pixel)
      End If
    End Sub

    Protected Overrides Sub CreateChildControls()
      MyBase.CreateChildControls()

      If Me.DesignMode Then
        Return
      End If

      ' Make sure the editor has a map resource
      If ParentEditor.MapResource Is Nothing Then
        Return
      End If

      ' Create table to store custom snapping panel's interface
      Dim table As System.Web.UI.WebControls.Table = New System.Web.UI.WebControls.Table()

      ' Create table row to hold the snap tolerance label
      Dim tableRow As System.Web.UI.WebControls.TableRow = New System.Web.UI.WebControls.TableRow()

      ' Create table cell and label to hold the static part of the tolerance label
      Dim tableCell As System.Web.UI.WebControls.TableCell = New System.Web.UI.WebControls.TableCell()
      tableCell.Text = "Tolerance"

      tableCell.Attributes.Add("class", "edSettingTD")

      ' Add the table cell to the row
      tableRow.Controls.Add(tableCell)

      ' Create a table cell to hold the dynamic part of the label.  This table cell is stored as an 
      ' instance variable so it can be easily referenced
      m_toleranceTableCell = New System.Web.UI.WebControls.TableCell()
      m_toleranceTableCell.ID = "customEditorSnapToleranceLabel"
      m_toleranceTableCell.Text = Me.Task.SnapTolerance.ToString() & " Pixels"

      ' Add the table cell to the row, the row to the table, and the table to the controls collection
      tableRow.Controls.Add(m_toleranceTableCell)
      table.Controls.Add(tableRow)
      Controls.Add(table)
    End Sub

    Protected Overrides Sub RenderContents(ByVal htmlTextWriter As System.Web.UI.HtmlTextWriter)
      ' Update snap tolerance text
      m_toleranceTableCell.Text = Me.Task.SnapTolerance.ToString() & " Pixels"
      MyBase.RenderContents(htmlTextWriter)
    End Sub

    #End Region

    #Region "Web ADF Control Event Handlers"

    ' When the map scale changes, recalculate the snap tolerance (in pixels) and update the custom snapping
    ' panel accordingly
    Private Sub Map_ScaleChanged(ByVal sender As Object, ByVal scaleEventArgs As ESRI.ArcGIS.ADF.Web.UI.WebControls.ScaleEventArgs)
      ' Make sure the old scale is valid and the old scale and new scale are distinct
      If scaleEventArgs.OldScale = System.Double.NaN OrElse scaleEventArgs.OldScale = scaleEventArgs.NewScale Then
        Return
      End If

      ' Only the map scale factor is needed (map units/pixel).
      ' Map scale is (map units/pixel * inches/map unit * pixels/inch)
      Me.CustomEditorTaskInstance.SnapTolerance = ConvertSnapToleranceMapUnitsToPixels(Me.ParentEditor.Map, Me.CustomEditorTaskInstance.SnapToleranceMapUnits)

      ' Change the snap tolerance label in the snapping panel by constructing a JavaScript callback with
      ' the code necessary to change the text of the table cell displaying the snap tolerance
      Dim jsChangeToleranceLabel As String = String.Format("document.getElementById('{0}').innerHTML = '{1}'", m_toleranceTableCell.ClientID, Me.CustomEditorTaskInstance.SnapTolerance & " Pixels")
      Dim changeToleranceLabelCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsChangeToleranceLabel)
      Me.ParentEditor.Map.CallbackResults.Add(changeToleranceLabelCallbackResult)

      ' Change the radius of the snap tolerance circle.  Use the ADF JavaScript library to get the client-side
      ' Editor object, retrieve the snap tip and set the snap radius size in pixels.    
      Dim jsChangeToleranceRadius As String = String.Format("$find('{0}').get_snapTip().set_snapRadius({1})", Me.ParentEditor.ClientID, CustomEditorTaskInstance.SnapTolerance)
      Dim changeToleranceRadiusCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsChangeToleranceRadius)
      Me.ParentEditor.Map.CallbackResults.Add(changeToleranceRadiusCallbackResult)
    End Sub

    #End Region

    #Region "Instance Properties and Methods"

    ' Provides easy access to the CustomEditorTask and custom snap properties
    Protected ReadOnly Property CustomEditorTaskInstance() As CustomEditorTask
      Get
        Return CType(Me.ParentEditor.EditorTask, CustomEditorTask)
      End Get
    End Property

    ' Convert tolerance in map units to pixels
    Friend Function ConvertSnapToleranceMapUnitsToPixels(ByVal adfMap As ESRI.ArcGIS.ADF.Web.UI.WebControls.Map, ByVal snapToleranceMapUnits As Double) As Integer
      Dim mapUnitsPerPixel As Double = (adfMap.Extent.Width / adfMap.TilingScheme.TileWidth)
      Return CInt(Fix(System.Math.Round(snapToleranceMapUnits / mapUnitsPerPixel)))
    End Function

    #End Region
  End Class
End Namespace