Common Custom EditorTask
Common_CustomEditorTask_VBNet\CustomEditorTask_VBNet\CustomSnappingPanel.vb
' Copyright 2007 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
Imports System.Collections.Generic
Imports System.Text
Imports ESRI.ArcGIS.ADF.ArcGISServer.Editor
Imports System.Web.UI
Imports System.Web.UI.WebControls

Namespace CustomEditorTask_VBNet
  Public Class CustomSnappingPanel
    Inherits EditorPanel
    Private m_hiddenField As System.Web.UI.WebControls.HiddenField
    Friend Const DEFAULT_SNAP_TOL_MAPUNITS As Double = 50.0

    Public Sub New(ByVal task As EditorTask)
      MyBase.New("Snapping Panel", task, "customSnappingPanel")
      Me.Expanded = False
    End Sub

    ' 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

    Protected Overrides Sub OnInit(ByVal e As EventArgs)
      MyBase.OnInit(e)

      If CustomEditorTaskInstance.UseMapUnitsForSnapping 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 e As EventArgs)
      MyBase.OnPreRender(e)

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

      ' If Width not set, set it.
      If Width = Unit.Empty Then
        Width = New Unit(300, UnitType.Pixel)
      End If

      ' Check if display_editorSnapTip.js file is registered.  The JavaScript file is included as embedded resource
      ' in EditorTask.  Initialize snap radius and snap tip color.   
      If (Not Page.ClientScript.IsStartupScriptRegistered("editorSnapRad")) AndAlso Not ParentEditor.MapResource Is Nothing Then
        Dim jsSnapRadiusColor As String = String.Format("SetSnapRadius('{0}',{1});defaultSnapTipColor='{2}';", ParentEditor.Map.ClientID, ParentEditor.EditorTask.SnapTolerance, System.Drawing.ColorTranslator.ToHtml(ParentEditor.EditorTask.SnapTipColor))

        ' If snap circle is enabled, turn it on.
        If ParentEditor.EditorTask.ShowSnapCircle Then
          jsSnapRadiusColor &= String.Format(";ShowSnapCircle(""{0}"",true,null);", ParentEditor.Map.ClientID)
        End If

        Page.ClientScript.RegisterStartupScript(Me.GetType(), "editorSnapRad", jsSnapRadiusColor, True)
      End If
    End Sub

    Protected Overrides Sub CreateChildControls()
      MyBase.CreateChildControls()

      ' The HTML hidden field tracks the snap tolerance value in the browser.  It required 
      ' for EditorTask JavaScript to render the snap circle and snap tips.  It is updated 
      ' When map extent changes.
      m_hiddenField = New HiddenField()
      m_hiddenField.ID = "snapTol"
      m_hiddenField.Value = CustomEditorTaskInstance.SnapTolerance.ToString()
      Controls.Add(m_hiddenField)
    End Sub

    Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
      If ParentEditor.MapResource Is Nothing Then
        Return
      End If

      ' Hidden field
      m_hiddenField.RenderControl(writer)

      writer.RenderBeginTag(HtmlTextWriterTag.Table)
      writer.RenderBeginTag(HtmlTextWriterTag.Tr)

      ' Add text to show snap tolerance in pixels.  Merely informative, not required.  
      writer.AddAttribute(HtmlTextWriterAttribute.Class, "edSettingTD")
      writer.RenderBeginTag(HtmlTextWriterTag.Td)
      writer.Write("Tolerance")
      writer.RenderEndTag() ' td

      Dim htmlTableCellToleranceLabel As System.Web.UI.HtmlControls.HtmlTableCell = New System.Web.UI.HtmlControls.HtmlTableCell("td")
      htmlTableCellToleranceLabel.ID = "customEditorSnapToleranceLabel"
      htmlTableCellToleranceLabel.InnerText = Task.SnapTolerance.ToString() & " Pixels"
      htmlTableCellToleranceLabel.RenderControl(writer)

      writer.RenderEndTag() ' tr
      writer.RenderEndTag() ' table
    End Sub

    ' If map scale changed, recalculate the snap tolerance in pixels
    Private Sub Map_ScaleChanged(ByVal sender As Object, ByVal args As ESRI.ArcGIS.ADF.Web.UI.WebControls.ScaleEventArgs)
      If args.OldScale = Double.NaN OrElse args.OldScale = args.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)
      CustomEditorTaskInstance.SnapTolerance = ConvertSnapToleranceMapUnitsToPixels(Me.ParentEditor.Map, CustomEditorTaskInstance.SnapToleranceMapUnits)
      Dim snapTolClientID As String = m_hiddenField.ClientID

      ' Change the snap tolerance label in the snapping panel.
      Dim jsChangeToleranceLabel As String = String.Format("document.getElementById('{0}').innerHTML = '{1}'", "customEditorSnapToleranceLabel", CustomEditorTaskInstance.SnapTolerance & " Pixels")
      Me.ParentEditor.Map.CallbackResults.Add(New ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult(Nothing, Nothing, "javascript", jsChangeToleranceLabel))
      ' Change the snap tolerance maintained in Web ADF JavaScript.  Adjusts toleranced for the snap radius and snap tips.
      Dim newCallbackFunctionString As String = Me.CallbackFunctionString.Replace("'", "\'")
      Dim jsChangeToleranceInBrowser As String = String.Format("window.setTimeout('SetSnapTolerance(document.createElement(""<input value={3} />""),""{0}"",""{1}"",""{2}"")', 1);", snapTolClientID, Me.ParentEditor.Map.ClientID, newCallbackFunctionString, CustomEditorTaskInstance.SnapTolerance)
      Me.ParentEditor.Map.CallbackResults.Add(New ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult(Nothing, Nothing, "javascript", jsChangeToleranceInBrowser))
    End Sub

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