Common Partial Postback
Common_PartialPostback_VBNet\AJAXDemo.aspx.vb
' Copyright 2011 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 AJAXDemo
  Inherits System.Web.UI.Page
  #Region "Instance Variable Declarations"

  ' Variables defining what resource, layer, and field name to use for the drop-down list and listbox
  Private m_queryResourceItemName As String = "MapResourceItem0"
  Private m_queryLayerName As String = "States"
  Private m_queryFieldName As String = "STATE_NAME"

  #End Region

  #Region "ASP.NET Page Life Cycle Event Handlers"

  Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs)
    Dim scriptKeyCustom As String = "customDataItemScript"
    ' Check whether a script block with the name stored in scriptKeyCustom has already
    ' been registered on the client, and whether the page is in an asynchronous postback.
    ' If neither of these is true, create and register the script block.  Note that replacing
    ' ScriptManager1.IsInAsyncPostBack with Page.IsPostback will work initially, but if a
    ' full page postback occurs, the script may be lost.
    If (Not Me.Page.ClientScript.IsClientScriptBlockRegistered(Me.GetType(), scriptKeyCustom)) AndAlso (Not ScriptManager1.IsInAsyncPostBack) Then
      ' Construct the JavaScript block that will be responsible for processing data items.
      ' 
      ' onLoadFunction specifies AsyncResponseHandler as a handler for the pageLoading AJAX
      ' client-side event.  This event fires during asynchronous postbacks after the response 
      ' has been received from the server, but before any content on the page is updated.  
      ' 
      ' AsyncResponseHandler retrieves the data items thate were registered server-side during 
      ' the asynchronous postback by accessing the dataItems property on the second argument 
      ' passed to the handler.  It then gets the particular data item corresponding to the 
      ' page by passing the page's client ID to the dataItems array as an array index.  This 
      ' data item, assumed to be formatted as a Web ADF callback result, is then passed to 
      ' ESRI.ADF.System.processCallbackResult - the client-side Web ADF function responsible 
      ' for parsing callback results and updating Web ADF controls accordingly.
      '
      ' Below the function declarations, onLoadFunction is added as a handler for the AJAX 
      ' client-side event init, which is raised one time when the page is first rendered. 
      ' This is therefore the appropriate place for onLoadFunction to be called, since the 
      ' asynchronous pageLoading handler in this case can remain unchanged for the life
      ' of the application.
      '
      ' The functions are enclosed in an extra pair of curly braces to allow the subsequent
      ' call to String.Format.  String.Format is designed to replace the contents of curly
      ' braces with the parameters passed to the function call.  These extra braces "escape" 
      ' the braces that must enclose a JavaScript function's logic, essentially telling 
      ' String.Format to not replace the contents of these particular braces.
      Dim scriptBlock As String = "" & ControlChars.CrLf & "                " & ControlChars.CrLf & "                function onLoadFunction(){{" & ControlChars.CrLf & "                  Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(AsyncResponseHandler);" & ControlChars.CrLf & "                }}" & ControlChars.CrLf & ControlChars.CrLf & "                function AsyncResponseHandler(sender, args) {{" & ControlChars.CrLf & "                  var dataItems = args.get_dataItems();" & ControlChars.CrLf & "                  if (dataItems['{0}'] != null)" & ControlChars.CrLf & "                    ESRI.ADF.System.processCallbackResult(dataItems['{0}']);" & ControlChars.CrLf & "                }}" & ControlChars.CrLf & ControlChars.CrLf & "                Sys.Application.add_init(onLoadFunction);"

      ' Insert the client ID of the page into the script block.  
      scriptBlock = String.Format(scriptBlock, Page.ClientID)

      ' Register the script on the client.  This will make the script block available client-side
      ' and execute statements that are not function or object declarations, in this case adding
      ' onLoadFunction as a handler for the init event.
      Me.Page.ClientScript.RegisterStartupScript(Me.GetType(), scriptKeyCustom, scriptBlock, True)
    End If
  End Sub

  #End Region

  #Region "ASP.NET WebControl Event Handlers"

  Protected Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, ByVal eventArgs As System.EventArgs)
    ZoomToFeatureByValue(DropDownList1.SelectedValue)
  End Sub

  Protected Sub ListBox1_SelectedIndexChanged(ByVal sender As Object, ByVal eventArgs As System.EventArgs)
    ZoomToFeatureByValue(ListBox1.SelectedValue)
  End Sub

  #End Region

  #Region "Web ADF Control Event Handlers"

  Protected Sub Map1_ExtentChanged(ByVal sender As Object, ByVal args As ESRI.ArcGIS.ADF.Web.UI.WebControls.ExtentEventArgs)
    ' New extent is the explicit envelope the Map extent will be set to.  Note that the aspect ratio of the map 
    ' extent has been adjusted to account for pixel image size / extent size discrepancies. 
    Dim adfEnvelope As ESRI.ArcGIS.ADF.Web.Geometry.Envelope = args.NewExtent

    ' Get the map resource to query
    Dim gisResource As ESRI.ArcGIS.ADF.Web.DataSources.IGISResource = Map1.GetFunctionality(m_queryResourceItemName).Resource

    ' Create a Common Data Source API query functionality from the resource
    Dim commonQueryFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality = CType(gisResource.CreateFunctionality (GetType(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), Nothing), ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)

    ' Get arrays containing the layer IDs and names of the resource's queryable layers
    Dim layerIDs As String() = Nothing
    Dim layerNames As String() = Nothing
    commonQueryFunctionality.GetQueryableLayers(Nothing, layerIDs, layerNames)

    ' Create a Web ADF spatial filter with the new map extent as the filter geometry
    Dim adfSpatialFilter As ESRI.ArcGIS.ADF.Web.SpatialFilter = New ESRI.ArcGIS.ADF.Web.SpatialFilter()
    adfSpatialFilter.ReturnADFGeometries = False
    adfSpatialFilter.Geometry = adfEnvelope

    ' Loop through the layer names array until the query layer name is found.  When found, use the layer
    ' ID at the current index to execute a query on the resource
    Dim queryResultsDataTable As System.Data.DataTable = Nothing
    Dim i As Integer = 0
    Do While i < layerNames.Length
      If layerNames(i) = m_queryLayerName Then
        queryResultsDataTable = commonQueryFunctionality.Query(commonQueryFunctionality.Name, layerIDs(i), adfSpatialFilter)
        Exit Do
      End If
      i += 1
    Loop

    ' Populate an ArrayList with the value of the query field for each row in the query results 
    Dim arrayList As System.Collections.ArrayList = New System.Collections.ArrayList()
    For Each dataRow As System.Data.DataRow In queryResultsDataTable.Rows
      Dim dataRowValue As String = dataRow(m_queryFieldName).ToString()
      arrayList.Add(dataRowValue)
    Next dataRow
    arrayList.Sort()

        ListBox1.Items.Clear()
    For Each item As String In arrayList
      ' If the ScriptManager is not in an asynchronous postback, then the page is in initial load.  
      ' We therefore add the current item to DropDownList1 since it has not yet been populated.
      ' Otherwise, we skip this step and clear ListBox1 since that control will be re-populated with
      ' the query results (i.e. features that intersect the new extent)
      If (Not ScriptManager1.IsInAsyncPostBack) Then
        DropDownList1.Items.Add(item)
            End If

      ' Add the current item to the listbox
      ListBox1.Items.Add(item)
    Next item
  End Sub

  #End Region

  #Region "Instance Methods"

  Private Sub ZoomToFeatureByValue(ByVal value As String)
    ' Get the resource to be queried and use it to create a Web ADF Common Data Source API
    ' query functionality
    Dim gisResource As ESRI.ArcGIS.ADF.Web.DataSources.IGISResource = Map1.GetFunctionality(m_queryResourceItemName).Resource
    Dim commonQueryFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality = CType(gisResource.CreateFunctionality (GetType(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), Nothing), ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)

    ' Get arrays containing the names and IDs of the resource's queryable layers
    Dim layerIDs As String() = Nothing
    Dim layerNames As String() = Nothing
    commonQueryFunctionality.GetQueryableLayers(Nothing, layerIDs, layerNames)

    ' Create a Web ADF query filter with a where clause that will select features according
    ' to the class-level field name variable and the passed-in value.  Note that the code here
    ' assumes the field has a string data type.
    Dim adfQueryFilter As ESRI.ArcGIS.ADF.Web.QueryFilter = New ESRI.ArcGIS.ADF.Web.QueryFilter()
    adfQueryFilter.ReturnADFGeometries = True
    adfQueryFilter.WhereClause = String.Format("{0} = '{1}'", m_queryFieldName, value)

    ' Loop through the layer names array until the query layer name is found.  When found, use 
    ' the layer ID at the current index to execute a query on the resource.
    Dim queryResultsDataTable As System.Data.DataTable = Nothing
    Dim i As Integer = 0
    Do While i < layerNames.Length
      If layerNames(i) = m_queryLayerName Then
        queryResultsDataTable = commonQueryFunctionality.Query(commonQueryFunctionality.Name, layerIDs(i), adfQueryFilter)
        Exit Do
      End If
      i += 1
    Loop

    If Not queryResultsDataTable Is Nothing Then
      ' Get the results as a Web ADF GraphicsLayer
      Dim adfGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer = TryCast(queryResultsDataTable, ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer)

      ' Get the envelope of the geometry of the first row in the data table and use it to set 
      ' the map extent.  Note that this code assumes we always want to zoom to the first row 
      ' in the table.
      Dim adfGeometry As ESRI.ArcGIS.ADF.Web.Geometry.Geometry = adfGraphicsLayer.GeometryFromRow(adfGraphicsLayer.Rows(0))
            Dim adfEnvelope As ESRI.ArcGIS.ADF.Web.Geometry.Envelope = ESRI.ArcGIS.ADF.Web.Geometry.Geometry.GetMinimumEnclosingEnvelope(adfGeometry).Expand(20)
      Map1.Extent = adfEnvelope

      ' Register the Map's callback results as a data item so they are processed on the client
      ScriptManager1.RegisterDataItem(Page, Map1.CallbackResults.ToString(), False)
    End If
  End Sub

  #End Region
End Class