Common Callback
Common_Callback_VBNet\Default.aspx.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
Public Partial Class [Default]
  Inherits System.Web.UI.Page
  Implements System.Web.UI.ICallbackEventHandler
  #Region "Instance Variable Declarations"

  Private m_ADFCallbackFunctionString As String
  Private m_CallbackResults As String

  #End Region

  #Region "ASP.NET Page Event Handlers"

  Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
    ' Define the parameters for a browser call to the WebForm_DoCallback JavaScript function
    ' via the GetCallbackEventReference function.  The GetCallbackEventReference function returns 
    ' the syntax for initiating a callback (i.e a call to WebForm_DoCallback) with the passed-in 
    ' parameters.  Here the parameters are defined as follows:
    ' this - the Page will handle the callback request
    ' "message" - a JavaScript variable named "message" will contain argument value pairs in 
    '             the callback
    ' "processCallbackResult" - name of the JavaScript function to process the callback 
    '                           response from the Page.  This function is included with 
    '                           the Web ADF JavaScript Library.
    ' "context" - a JavaScript variable named "context" which can be used by the browser to
    '             indicate the origin of the callback
    ' "postBackError" - name of the JavaScript function to process errors returned during 
    '                   callback processing.
    ' true - define whether the callback is synchronous or asynchronous.  True is asynchronous.        
    m_ADFCallbackFunctionString = Page.ClientScript.GetCallbackEventReference(Me, "message", "processCallbackResult", "context", "postBackError", True)
  End Sub

  #End Region

  #Region "Web ADF Control Event Handlers"

  ' Event that fires when the map extent changes.  Wired to the map in the map control's HTML declaration
  Protected Sub Map1_ExtentChanged(ByVal sender As Object, ByVal extentEventArgs As ESRI.ArcGIS.ADF.Web.UI.WebControls.ExtentEventArgs)
    Try
      ' Get the new extent of the map (extent after the extent changed) and store in a Web ADF envelope
      Dim adfEnvelope As ESRI.ArcGIS.ADF.Web.Geometry.Envelope = extentEventArgs.NewExtent

      ' Create a SortedList object containing four key-value pairs, each containing one bound of the
      ' new extent and the id of the HTML div that will be updated to display that bound.  "N" is
      ' passed to double.ToString to specify a numeric format in converting the coordinate.
      Dim extentList As System.Collections.Generic.SortedList(Of String, String) = New System.Collections.Generic.SortedList(Of String, String)()
      extentList.Add("LabelN", adfEnvelope.YMax.ToString("N"))
      extentList.Add("LabelE", adfEnvelope.XMax.ToString("N"))
      extentList.Add("LabelS", adfEnvelope.YMin.ToString("N"))
      extentList.Add("LabelW", adfEnvelope.XMin.ToString("N"))

      ' Iterate through each pair in the list and create a callback result to update the extent divs
      For Each keyValuePair As System.Collections.Generic.KeyValuePair(Of String, String) In extentList
        ' Get the extent bound coordinate of the current list item
        Dim extentBound As String = keyValuePair.Value.ToString()
        ' Get the div ID that should be updated with extentBound from the current list item
        Dim extentDivId As String = keyValuePair.Key.ToString()

        ' Create a callback result that will update the div specified by extentDivId with the
        ' value specified by extentBound.  To do this, we pass the CallbackResult constructor the
        ' following parameters:
        ' "div" - the type of control/element we want updated
        ' extentDivId - the client-side ID of the control/element we want updated
        ' "innercontent" - the type of action we want to be performed.  "innercontent" specifies that
        '      we want to replace the inner HTML (what's inside the element tags) of the specified 
        '      control/element
        ' extentBound - the value to use in the specified action.  In this case, it is the value
        '      to replace the div's inner HTML with.
        Dim callbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateSetInnerContent(extentDivId, extentBound)

        ' Add the callback result to the map.  Since the map control initiated the callback when
        ' its extent changed, it is the map control's callback results that will be processed when
        ' the callback returns to the client.
        Map1.CallbackResults.Add(callbackResult)
      Next keyValuePair
    Catch exception As System.Exception
      Dim errorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ErrorHandling.GetErrorCallback(exception)
      Map1.CallbackResults.Add(errorCallbackResult)
    End Try
  End Sub

  #End Region

  #Region "ICallbackEventHandler Members"

  ' The Zoom To Point button is wired to invoke the JavaScript function ZoomToPointClient
  ' (defined in Default.aspx), which in turn invokes the JavaScript callback function.  So when
  ' the button is clicked, a callback is initiated, causing RaiseCallbackEvent and
  ' GetCallbackResult to be called.  
  '
  ' The items on the Zoom To Location menu are wired similarly, as on click they call the JavaScript 
  ' function ZoomToLocationClient (also defined in Default.aspx), which also in turn calls the 
  ' JavaScript callback.
  '
  ' We therefore add code to RaiseCallbackEvent and GetCallbackResult to parse the arguments
  ' passed in the callbacks, take action accordingly, and return a callback response to the client.
  Public Sub RaiseCallbackEvent(ByVal eventArgs As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
    Try
      ' Parse the callback string passed from the client to the server into separate
      ' arguments using the Web ADF's callback parsing utility.
      Dim nameValueCollection As System.Collections.Specialized.NameValueCollection = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(eventArgs)

      ' Check the value of the main event argument (EventArg) and take action accordingly
      If nameValueCollection("EventArg") = "ZoomToPoint" Then
        ' Call the method that will center the map at the passed-in coordinates and zoom by a factor
        ' of four.
        ZoomToPointServer(nameValueCollection("X"), nameValueCollection("Y"))
      ElseIf nameValueCollection("EventArg") = "ZoomToLocation" Then
        ' Call the method that will zoom the map to the passed-in location
        ZoomToLocationServer(nameValueCollection("Location"))
      End If
    Catch exception As System.Exception
      Dim errorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ErrorHandling.GetErrorCallback(exception)
      Map1.CallbackResults.Add(errorCallbackResult)
      m_CallbackResults = Map1.CallbackResults.ToString()
    End Try
  End Sub

  ' The last server-side method called before the callback returns to the browser, GetCallbackResult
  ' is where the server-side result of the callback is passed back to the browser as a string for
  ' processing by the client.
  Public Function GetCallbackResult() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult
    ' Return the instance variable containing the callback results
    Return m_CallbackResults
  End Function

  #End Region

  #Region "Instance Properties"

  ' Property allowing client-side access to the client callback function string.  This string
  ' contains the necessary JavaScript syntax to initiate a callback with the parameters specified
  ' in GetCallbackEventReference (in Page_Load).
  Public Property ADFCallbackFunctionString() As String
    Get
      Return m_ADFCallbackFunctionString
    End Get
    Set
      m_ADFCallbackFunctionString = Value
    End Set
  End Property

  #End Region

  #Region "Instance Methods"

  ' Method that centers the map at the passed-in coordinates and zooms by a factor of 4
  Public Sub ZoomToPointServer(ByVal xString As String, ByVal yString As String)
    Try
      ' Convert the passed-in coordinates from strings to doubles
      Dim xCenter As Double = Double.Parse(xString)
      Dim yCenter As Double = Double.Parse(yString)

      ' Create a Web ADF point from the passed-in coordinates
      Dim adfCenterPoint As ESRI.ArcGIS.ADF.Web.Geometry.Point = New ESRI.ArcGIS.ADF.Web.Geometry.Point(xCenter, yCenter)

      ' Center the map at the point
      Map1.CenterAt(adfCenterPoint)

      ' Zoom the map by a factor of 4
      Map1.Zoom(4)
    Catch exception As System.Exception
      Dim errorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ErrorHandling.GetErrorCallback(exception)
      Map1.CallbackResults.Add(errorCallbackResult)
    End Try

    ' Update the instance variable storing callback results with the callback results of the
    ' map control.  Since we've manipulated the map, its callback results must be returned
    ' to the client for our changes to show up.  And since it was not the map control that
    ' intitiated the callback, but rather a custom JavaScript function, the map control is
    ' not checked for callback results when the callback returns to the client.
    m_CallbackResults = Map1.CallbackResults.ToString()
  End Sub

  ' Method that zooms the map to the passed-in location
  Public Sub ZoomToLocationServer(ByVal location As String)
    Try
      ' Declare and initialze a variable to store whether the passed-in location is
      ' one listed on the Zoom To Location menu
      Dim validLocation As Boolean = False

      ' Get the root menu item of the Zoom To Menu
      Dim rootMenuItem As System.Web.UI.WebControls.MenuItem = Menu1.Items(0)

      ' Iterate through the items directly below the root item
      For Each menuItem As System.Web.UI.WebControls.MenuItem In rootMenuItem.ChildItems
        ' Check whether the current menu item's text matches the passed-in location
        If menuItem.Text = location Then
          ' the text matches the location, meaning the location is valid
          validLocation = True
          Exit For
        End If
      Next menuItem

      If validLocation Then
        ' Declare and initialize variables to store the bounds of the new map extent
        Dim minX As Double = 0
        Dim minY As Double = 0
        Dim maxX As Double = 0
        Dim maxY As Double = 0

        ' Check the passed-in location and initialize the extent parameters accordingly
        Select Case location
          Case "California"
            minX = -128.0
            minY = 31.0
            maxX = -111.0
            maxY = 43.0
          Case "New York"
            minX = -80.0
            minY = 40.5
            maxX = -73.0
            maxY = 45.5
          Case "Kansas"
            minX = -103.0
            minY = 35.0
            maxX = -93.0
            maxY = 42.0
          Case Else
        End Select
        ' Create a Web ADF envelope with the new extent parameters
        Dim adfNewExtentEnvelope As ESRI.ArcGIS.ADF.Web.Geometry.Envelope = New ESRI.ArcGIS.ADF.Web.Geometry.Envelope(minX, minY, maxX, maxY)

        ' Update the map control's extent with the newly created envelope
        Map1.Extent = adfNewExtentEnvelope

        ' Update the instance variable storing callback results with the callback results of the
        ' map control.  Since we've manipulated the map, its callback results must be returned
        ' to the client for our changes to show up.  And since it was not the map control that
        ' intitiated the callback, but rather a custom JavaScript function, the map control is
        ' not checked for callback results when the callback returns to the client.
        m_CallbackResults = Map1.CallbackResults.ToString()
      Else
        ' The location was not valid, so we don't need to pass any callback results to the client
        m_CallbackResults = ""
      End If
    Catch exception As System.Exception
      Dim errorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ErrorHandling.GetErrorCallback(exception)
      Map1.CallbackResults.Add(errorCallbackResult)
      m_CallbackResults = Map1.CallbackResults.ToString()
    End Try
  End Sub

  #End Region

End Class