Common Custom tasks
Common_CustomTasks_VBNet\PostBackTask_VBNet\PostBackTask.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
<Assembly: System.Web.UI.WebResource("CustomSendRequest.js", "text/javascript")> 

' Classes encapsulating several methods of invoking and handling asynchronous functionality within a task.  Includes 
' buttons that (1) issue a partial postback, (2) invoke a custom callback, (3) execute the task via the task framework
' methods, and (4) invoke a callback that is handled in a class other than that of the parent task.
Namespace PostBackTask_VBNet
  <System.Web.UI.ToolboxData("<{0}:PostBackTask runat=""server"" Width=""200px"" Transparency=""35"" " & ControlChars.CrLf & "        BackColor=""White"" TitleBarColor=""WhiteSmoke"" TitleBarSeparatorLine=""False"" " & ControlChars.CrLf & "        TitleBarHeight=""20px"" BorderColor=""LightSteelBlue"" BorderStyle=""Outset"" BorderWidth=""1px"" " & ControlChars.CrLf & "        Font-Names=""Verdana"" Font-Size=""8pt"" ForeColor=""Black""> </{0}:PostBackTask>")> _
  Public Class PostBackTask
    Inherits ESRI.ArcGIS.ADF.Web.UI.WebControls.FloatingPanelTask
    #Region "Instance Variable Declarations"

    Private _handleCallbackButton As PostBackTask_VBNet.CustomCallbackButton
    Private _handlePartialPostBackButton As System.Web.UI.WebControls.Button
    Private _hiddenHtmlInput As System.Web.UI.HtmlControls.HtmlInputHidden
    Private _inputControlList As System.Collections.Generic.List(Of String) = New System.Collections.Generic.List(Of String)()
    Private _taskResults As ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResults
    Private _taskJobID As String

    #End Region

    #Region "ASP.NET WebControl Event Handlers - OnLoad, CreateChildControls, OnPreRender, HandlePartialPostBackButton_Click"

    #Region "Life Cycle Event Handlers - OnLoad, CreateChildControls, OnPreRender"

    Protected Overrides Overloads Sub OnLoad(ByVal e As System.EventArgs)
      MyBase.OnLoad(e)

      ' Pass the task instance to the CustomCallbackButton if the Callback framework
      ' is being used (i.e. a ScriptManager is not on the page)
      If Not _handleCallbackButton Is Nothing Then
        _handleCallbackButton.PostBackTaskInstance = Me
      End If
    End Sub

    Protected Overrides Overloads Sub CreateChildControls()
      Controls.Clear()
      MyBase.CreateChildControls()

      ' If there is no ScriptManager on the page, initialize and add custom callback button to the task.
      ' Otherwise, add a partial postback button.
      If Me.ScriptManager Is Nothing Then
'        #Region "Custom Callback Button Instantiation"

        ' Initialize a custom callback button and add it to the task's controls collection
        _handleCallbackButton = New CustomCallbackButton()
        _handleCallbackButton.ID = "CallbackButton"
        _handleCallbackButton.Text = "Handle Callback"
        _handleCallbackButton.UseSubmitBehavior = False

        Controls.Add(_handleCallbackButton)

'        #End Region
      Else
'        #Region "Partial PostBack Button Instantiation"

        ' Initialize a button that will trigger a partial postback
        _handlePartialPostBackButton = New System.Web.UI.WebControls.Button()
        _handlePartialPostBackButton.ID = "partialPostBackButton"
        _handlePartialPostBackButton.Text = "Handle Partial PostBack"
        _handlePartialPostBackButton.UseSubmitBehavior = False

        ' Wire a handler for the button's click event
        AddHandler _handlePartialPostBackButton.Click, AddressOf HandlePartialPostBackButton_Click

        ' Regiester the button as an asyncrhonous postback control so it triggers a partial postback
        ' when clicked
        ScriptManager.RegisterAsyncPostBackControl(_handlePartialPostBackButton)

        ' Add a custom attribute to the button to be handled during the partial postback
        _handlePartialPostBackButton.Attributes.Add("buttonParameter", "buttonValue")

        ' Add the button to the task's controls collection
        Controls.Add(_handlePartialPostBackButton)

'        #End Region

        ' Initialize a hidden element and add it to the task's controls collection
        _hiddenHtmlInput = New System.Web.UI.HtmlControls.HtmlInputHidden()
        _hiddenHtmlInput.ID = "hiddenTag"
        _hiddenHtmlInput.Value = ""

        Controls.Add(_hiddenHtmlInput)
      End If

'      #Region "Controls for Task Input - TextBox and DropDownList"

      ' Create a textbox and add it to the task's controls collection
      Dim textBox As System.Web.UI.WebControls.TextBox = New System.Web.UI.WebControls.TextBox()
      textBox.ID = "PostBackTaskTextBox"
      Controls.Add(textBox)

      ' Add the textbox's ID to the list of input control IDs
      _inputControlList.Add(textBox.ClientID)

      ' Create a drop-down list, add items to it, and add it to the task's controls collection
      Dim dropDownList As System.Web.UI.WebControls.DropDownList = New System.Web.UI.WebControls.DropDownList()
      dropDownList.ID = "PostBackTaskDropDownList"
      dropDownList.Items.Add("item 1")
      dropDownList.Items.Add("item 2")
      dropDownList.Items.Add("item 3")
      Controls.Add(dropDownList)

      ' Add the drop-down list's ID to the list of input controls IDs
      _inputControlList.Add(dropDownList.ClientID)

'      #End Region

'      #Region "Button Invoking Asynchronous Request via Custom JavaScript"

      ' Construct a JavaScript string which, when evaluated, will result in a string of the input
      ' control IDs, each separated by "~~~"
      Dim customArgumentBuilder As System.Text.StringBuilder = New System.Text.StringBuilder("'input=' + ")
      Dim i As Integer = 0
      Do While i < _inputControlList.Count
        customArgumentBuilder.Append(String.Format("ESRI.ADF.System.escapeForCallback($get('{0}').value)", _inputControlList(i)))
        If i + 1 = _inputControlList.Count Then
          Exit Do
        End If
        customArgumentBuilder.Append(" + '~~~' + ")
        i += 1
      Loop
      Dim customArguments As String = customArgumentBuilder.ToString()

      ' Create a button which, when clicked, will initiate an asynchronous request via custom JavaScript
      Dim customAsyncRequestButton As System.Web.UI.WebControls.Button = New System.Web.UI.WebControls.Button()
      customAsyncRequestButton.Text = "Send Custom Request"

      ' Construct JavaScript to initiate an asyncrhonous request via the task's callback function string
      Dim sendAsyncRequestJavaScript As String = String.Format("sendRequest({0}, ""{1}"");return false;", customArguments, Me.CallbackFunctionString)

      ' Wire the asynchronous request initiation script to execute when the button is clicked
      customAsyncRequestButton.OnClientClick = sendAsyncRequestJavaScript

      ' Add the button to the task's controls collection
      Controls.Add(customAsyncRequestButton)

'      #End Region

'      #Region "Button Initiating Task Execution via Web ADF Task Framework"

      ' Create a button for task execution
      Dim executeTaskButton As System.Web.UI.WebControls.Button = New System.Web.UI.WebControls.Button()
      executeTaskButton.Text = "Execute Task"

      ' Construct JavaScript that calls the Web ADF's executeTask function.  This will initiate
      ' a callback that invokes the task's ExecuteTask method on the server.
      Dim executeTaskJavaScript As String = String.Format("ESRI.ADF.Tasks.executeTask({0}, ""{1}"");return false;", customArguments, CallbackFunctionString)

      ' Wire the JavaScript to execute when the button is clicked
      executeTaskButton.OnClientClick = executeTaskJavaScript

      ' Add the button to the task's controls colleciton
      Controls.Add(executeTaskButton)

'      #End Region
    End Sub

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

      ' Register the CustomSendRequest JavaScript file if it has not already been
      Dim embedTaskScriptKey As String = "embeddedPostBackTaskScript"
      If (Not Page.ClientScript.IsClientScriptBlockRegistered(embedTaskScriptKey)) Then
                Dim scriptLocation As String = Page.ClientScript.GetWebResourceUrl(GetType(PostBackTask), "CustomSendRequest.js")
        Page.ClientScript.RegisterClientScriptInclude(embedTaskScriptKey, scriptLocation)
      End If

      ' Check whether the Callback or Partial PostBack framework is being used by checking whether
      ' a ScriptManager has been included on the page.  Then wire client-side logic accordingly.
      If Me.ScriptManager Is Nothing Then
'        #Region "Custom Callback Button Click Handling"

        ' Get the JavaScript syntax for invoking a callback to the callback button
        Dim callbackInvocationString As String = Page.ClientScript.GetCallbackEventReference(_handleCallbackButton, "argument", "processCallbackResult", "context")

        ' Construct JavaScript to create an argument string containing the browser's dimensions
        ' and execute a callback to pass the argument to the server.
        Dim callbackJavaScript As String = "" & ControlChars.CrLf & "                        var argument = 'callbackArgument=' + document.body.clientWidth + '~~~' " & ControlChars.CrLf & "                            + document.body.clientHeight;" & ControlChars.CrLf & "                        var context = null;" & ControlChars.CrLf & "                        {0};" & ControlChars.CrLf & "                        return;" & ControlChars.CrLf & "                    "
        ' Substitute the callback invocation into the callback packaging JavaScript
        callbackJavaScript = String.Format(callbackJavaScript, callbackInvocationString)

        ' Wire the script to the callback button's click event
        _handleCallbackButton.OnClientClick = callbackJavaScript

'        #End Region
      Else
'        #Region "Partial PostBack Button Click Handling"

        ' Get the JavaScript syntax to invoke a postback to the partial postback button
        Dim postbackInvocationString As String = Page.ClientScript.GetPostBackEventReference(_handlePartialPostBackButton, String.Empty)

        ' Construct JavaScript to place an argument string in a hidden input element and invoke
        ' a postback
        Dim postbackJavaScript As String = "" & ControlChars.CrLf & "                        $get('{0}').value = 'postbackArgument=' + document.body.clientWidth + '~~~' " & ControlChars.CrLf & "                            + document.body.clientHeight;" & ControlChars.CrLf & "                        {1};" & ControlChars.CrLf & "                        return;" & ControlChars.CrLf & "                    "
        ' Substitute the hidden input's client ID and the postback invocation syntax into the 
        ' argument packaging JavaScript
        postbackJavaScript = String.Format(postbackJavaScript, _hiddenHtmlInput.ClientID, postbackInvocationString)

        ' Wire the script to the postback button's click event
        _handlePartialPostBackButton.OnClientClick = postbackJavaScript

'        #End Region

'        #Region "Partial PostBack Response Handling"

        ' Create the JavaScript necessary to pass the result of a partial postback to the Web ADF
        ' JavaScript library's processCallbackResult function
        Dim scriptKeyCustom As String = "customDataItemScript"
        If (Not Me.Page.ClientScript.IsStartupScriptRegistered(Me.GetType(), scriptKeyCustom)) Then
          Dim processDataItemJavaScript 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);"
          processDataItemJavaScript = String.Format(processDataItemJavaScript, Me.Page.ClientID)

          ' Register the script as a startup script so the result handling code is wired during
          ' applicaton initialization
          Me.Page.ClientScript.RegisterStartupScript(Me.GetType(), scriptKeyCustom, processDataItemJavaScript, True)

        End If

'        #End Region
      End If
    End Sub

    #End Region

    #Region "UI Event Handlers - HandlePartialPostBackButton_Click"

    ' Fires when the Handle Partial PostBack button is clicked
    Private Sub HandlePartialPostBackButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
      ' Get the contents of the hidden input element from the page's request parameters.  Since
      ' the asynchronous request is a partial postback and the input element is a server control,
      ' we know that this is included in the page request.
      Dim hiddenValueArguments As String = Page.Request.Params(_hiddenHtmlInput.UniqueID)

      ' Use the Web ADF's callback parsing utility to split the contents of the hidden element into
      ' a name-value collection.  Note that the parsing utility can be used on any string with the
      ' format <Param Name 1>=<Value 1>&<Param Name 2>=<Value 2>&...
      Dim postbackArgsCollection As System.Collections.Specialized.NameValueCollection = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(hiddenValueArguments)

      ' Get the postback argument from the collection
      Dim postbackArguments As String = postbackArgsCollection("postbackArgument")

      If (Not String.IsNullOrEmpty(postbackArguments)) Then
        ' Split the argument string into the input parameters contained within it.  Note the 
        ' JavaScript formatting this string was registered in OnPreRender.
        Dim inputArray As String() = postbackArguments.Split(New String() { "~~~" }, System.StringSplitOptions.None)

        ' Format a simple task result with the input arguments and display the result in the task
        ' results container
        Dim simpleTaskResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.SimpleTaskResult = New ESRI.ArcGIS.ADF.Web.UI.WebControls.SimpleTaskResult("Browser Dimensions", "Width: " & inputArray(0) & "," & "Height: " & inputArray(1))
        TaskResultsInstance.DisplayResults(Nothing, Nothing, Nothing, simpleTaskResult)
      End If

      ' Zoom the map
      If Not TaskResultsInstance.MapInstance Is Nothing Then
        TaskResultsInstance.MapInstance.Zoom(2)
      End If

      ' Copy the map's callback results to the task results container's callback results collection
      TaskResultsInstance.CallbackResults.CopyFrom(TaskResultsInstance.MapInstance.CallbackResults)

      ' Register the task results container's callback results as a data item.  This will pass the
      ' callback results to the client-side AsyncResponseHandler function that was registered in
      ' OnPreRender.  This function, in turn, will pass the callback results to the Web ADF's 
      ' processCallbackResults function.
      Me.ScriptManager.RegisterDataItem(Page, TaskResultsInstance.CallbackResults.ToString(), False)
    End Sub

    #End Region

    #End Region

    #Region "ICallbackEventHandler Member Overrides - GetCallbackResult"

    ' Fires when the callback framework is being used and an asynchronous request is issued to the task
    Public Overrides Overloads Function GetCallbackResult() As String
      ' Use the Web ADF's callback parsing utility to split the argument passed in the callback into
      ' a collection of name-value pairs
      Dim callbackArgsCollection As System.Collections.Specialized.NameValueCollection = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(Me.CallbackEventArgument)

      ' Get the value of the EventArg parameter
      Dim eventArgument As String = callbackArgsCollection("EventArg")

      ' Get the task input
      Dim inputString As String = callbackArgsCollection("input")

      ' Clear the server-side property storing task input
      Me.Input = Nothing
      If (Not String.IsNullOrEmpty(inputString)) Then
        ' Parse the input string into an array of input arguments
        Dim inputArray As String() = inputString.Split(New String() { "~~~" }, System.StringSplitOptions.None)
        ' Set the task's server-side input property to reference the input array
        Me.Input = inputArray
      End If

      ' If the event argument is "executeTask," the ExecuteTask method will fire automatically.  
      ' Otherwise, we must explicitly invoke any server side methods we want to execute during the
      ' callback.
      If eventArgument = "executeTask" Then
        ' Get the job ID of the task.  This will be used to set up the task result node containing
        ' the results
        _taskJobID = callbackArgsCollection("taskJobID")

        ' Since we are using the task framework, we can simply return the base method's result
        Return MyBase.GetCallbackResult()
      ElseIf eventArgument = "customRequest" Then
        ' Invoke the method we want to execute during the callback.
        CustomMethod()
      End If

      ' Since we have invoked server-side logic outside the scope of the task framework, we explicitly
      ' return the callback results that have been created during execution of that logic.
      Return Me.CallbackResults.ToString()
    End Function

    #End Region

    #Region "FloatingPanelTask Overrides - ExecuteTask, GetGISResourceItemDependencies"

    ' Fires when a callback is initiated by invoking the Web ADF's executeTask function from the client
    Public Overrides Overloads Sub ExecuteTask()
      ' Make sure that task input exists
      If Me.Input Is Nothing Then
        Return
      End If

      ' Cast the task input to a string array
      Dim inputArray As String() = TryCast(Me.Input, String())

      ' Clear out the property storing the task results
      Me.Results = Nothing

      ' Create a Task Result Node, set its text to the first input paramter, and initialize 
      ' it via the SetupTaskResultNode method.
      Dim taskResultNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResultNode = New ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResultNode()
      taskResultNode.Text = inputArray(0)
      TaskResultsInstance.SetupTaskResultNode(Me, _taskJobID, Input, taskResultNode)

      ' Create a TreeViewPlus Node, set its text to the second input parameter, and add it 
      ' to the node collection of the Task Result Node
      Dim treeViewPlusNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode = New ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode()
      treeViewPlusNode.Text = inputArray(1)
      taskResultNode.Nodes.Add(treeViewPlusNode)

      ' Zoom the map
      If Not TaskResultsInstance.MapInstance Is Nothing Then
        TaskResultsInstance.MapInstance.Zoom(2)
      End If

      ' Set the Task Result Node as the result of the task
      Me.Results = taskResultNode
    End Sub

    ' Used by Manager to see if task requires a particular resource item in a resource manager.  
    ' Since this task has no dependencies, the implementation here returns an empty list.
    Public Overrides Overloads Function GetGISResourceItemDependencies() As System.Collections.Generic.List(Of ESRI.ArcGIS.ADF.Web.UI.WebControls.GISResourceItemDependency)
      Return New System.Collections.Generic.List(Of ESRI.ArcGIS.ADF.Web.UI.WebControls.GISResourceItemDependency)()
    End Function

    #End Region

    #Region "Instance Members - CustomMethod, TaskResultsInstance"

    #Region "Instance Methods - Custom Method "

    ' Fires when the Send Custom Request button is clicked
    Public Sub CustomMethod()
      ' Make sure task input exists
      If Me.Input Is Nothing Then
        Return
      End If

      ' Cast the task's input to a string array
      Dim inputArray As String() = TryCast(Me.Input, String())

      ' Create a task result node, set its text as the first item in the input array, and initialze 
      ' a context menu for it
      Dim taskResultNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResultNode = New ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResultNode()
      taskResultNode.Text = inputArray(0)
      TaskResultsInstance.SetupContextMenu(TaskResultsInstance.RemoveOnlyContextMenu, taskResultNode)

      ' Initialize a tree view plus node, set its text to the second item in the input array, and
      ' add it to the nodes collection of the task result node
      Dim treeViewPlusNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode = New ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode()
      treeViewPlusNode.Text = inputArray(1)
      taskResultNode.Nodes.Add(treeViewPlusNode)

      ' Add the task result node to the nodes collection of the task's task results container
      TaskResultsInstance.Nodes.Add(taskResultNode)

      ' Refresh the task results container to apply the addition of the task results node
      TaskResultsInstance.Refresh()

      ' Copy the callback results of the task results container to the task's callback results 
      ' collection.  GetCallbackResults returns the task's callback results collection to the
      ' client, so we need to do this so the task results container's callback results are 
      ' processed on the client.
      Me.CallbackResults.CopyFrom(TaskResultsInstance.CallbackResults)
    End Sub

    #End Region

    #Region "Instance Properties - TaskResultsInstance"

    ' Convenient access to the first TaskResults control in the Task's TaskResultsContainers collection
    Friend ReadOnly Property TaskResultsInstance() As ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResults
      Get
        ' Retrieve the TaskResults control if it has not already been
        If (_taskResults Is Nothing) AndAlso (Not Me.TaskResultsContainers(0) Is Nothing) Then
                    _taskResults = TryCast(ESRI.ArcGIS.ADF.Web.UI.WebControls.Utility.FindControl(Me.TaskResultsContainers(0).Name, Me.Page), ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResults)
        End If

        Return _taskResults
      End Get
    End Property

    #End Region

    #End Region
  End Class

  ' Class encapsulating an ASP.NET button that handles a callback.  Implemented here to show how a task can 
  ' include child controls that process their own callbacks, rather than sending those callback to the parent
  ' task.
  Public Class CustomCallbackButton
    Inherits System.Web.UI.WebControls.Button
    Implements System.Web.UI.ICallbackEventHandler
    #Region "Instance Variable Declarations"

    Private _callbackArg As String
    Private _postbackTask As PostBackTask_VBNet.PostBackTask

    #End Region

    #Region "ICallbackEventHandler Members - RaiseCallbackEvent, GetCallbackResult"

    ' The first method to execute on the server when a callback is invoked from the client.  The string
    ' containing the callback's parameters is passed to this method.
    Public Sub RaiseCallbackEvent(ByVal eventArgument As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
      ' Store the callback argument string in an instance variable for reference in GetCallbackResult
      _callbackArg = eventArgument
    End Sub

    ' Fires when a callback string referencing a CustomCallbackButton instance is invoked from the client.  
    ' In the PostBackTask implementation above, the JavaScript needed to do that is wired to a 
    ' CustomCallbackButton instance in the OnPreRender method.
    Public Function GetCallbackResult() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult
      ' Use the Web ADF's callback parsing utility to split the callback argument string into a 
      ' collection of name-value pairs.
      Dim callbackArgsCollection As System.Collections.Specialized.NameValueCollection = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(_callbackArg)

      ' Get the callback argument from the collection
      Dim callbackArguments As String = callbackArgsCollection("callbackArgument")

      If (Not String.IsNullOrEmpty(callbackArguments)) Then
        ' Split the callback argument into a string array
        Dim inputArray As String() = callbackArguments.Split(New String() { "~~~" }, System.StringSplitOptions.None)

        ' Create a simple task result containing the input arguments in the array
        Dim simpleTaskResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.SimpleTaskResult = New ESRI.ArcGIS.ADF.Web.UI.WebControls.SimpleTaskResult("Browser Dimensions", "Width: " & inputArray(0) & "," & "Height: " & inputArray(1))

        ' Display the task result in the task results container buddied to the callback button's parent
        ' PostBackTask.
        Me.PostBackTaskInstance.TaskResultsInstance.DisplayResults(Nothing, Nothing, Nothing, simpleTaskResult)
      End If

      ' Zoom the map buddied to the callback button's parent PostBackTask
      If Not Me.PostBackTaskInstance.TaskResultsInstance.MapInstance Is Nothing Then
        Me.PostBackTaskInstance.TaskResultsInstance.MapInstance.Zoom(2)
      End If

      ' Copy the map's callback results to the task results container's results collection
      Me.PostBackTaskInstance.TaskResultsInstance.CallbackResults.CopyFrom(Me.PostBackTaskInstance.TaskResultsInstance.MapInstance.CallbackResults)


      Return PostBackTaskInstance.TaskResultsInstance.CallbackResults.ToString()
    End Function

    #End Region

    #Region "Instance Properties - PostBackTaskInstance"

    ' Provides access to the parent task
    Friend Property PostBackTaskInstance() As PostBackTask
      Get
        Return _postbackTask
      End Get
      Set
        _postbackTask = Value
      End Set
    End Property

    #End Region
  End Class
End Namespace