Common_CustomTasks_VBNet\FindNearTask_VBNet\FindNearTask.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. ' ' Embedded images Imports Microsoft.VisualBasic Imports System <Assembly: System.Web.UI.WebResource("point.bmp", "image/bmp")> <Assembly: System.Web.UI.WebResource("pointD.bmp", "image/bmp")> <Assembly: System.Web.UI.WebResource("pointU.bmp", "image/bmp")> <Assembly: System.Web.UI.WebResource("point.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("point_selected.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("point_hover.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("polyline.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("polyline_selected.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("polyline_hover.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("polygon.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("polygon_selected.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("polygon_hover.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("clearInput.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("clearInput_selected.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("clearInput_hover.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("selectFeature.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("selectFeature_selected.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("selectFeature_hover.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("selectTaskResult.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("selectTaskResult_selected.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("selectTaskResult_hover.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("preview.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("contextMenuRemove.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("contextMenuZoomTo.gif", "image/gif")> <Assembly: System.Web.UI.WebResource("contextMenuViewTable.gif", "image/gif")> ' Embedded JavaScript <Assembly: System.Web.UI.WebResource("FindNearTask.js", "text/javascript")> Namespace FindNearTask_VBNet ' Task that allows searching for features within a specified distance of user-drawn graphics, selected ' features, or task results <System.ComponentModel.DefaultProperty("TabularResultOptions"), System.Drawing.ToolboxBitmap(GetType(FindNearTask_VBNet.FindNearTask)), System.Web.UI.ToolboxData("<{0}:FindNearTask runat=""server"" Width=""400px"" BackColor=""White"" " & ControlChars.CrLf & " BorderColor=""#999999"" BorderStyle=""Solid"" BorderWidth=""1px"" Font-Names=""Verdana"" " & ControlChars.CrLf & " Font-Size=""8pt"" ForeColor=""Black"" TitleBarColor=""#2F5675"" TitleBarHeight=""24px"" " & ControlChars.CrLf & " TitleBarSeparatorLine=""True"" Transparency=""0"" Font-Bold=""True"" TitleBarForeColor=""White"" " & ControlChars.CrLf & " Visible=""False"" DockingContainerElementID=""LeftPanelCellDiv"" ShowDockedContextMenu=""True"" " & ControlChars.CrLf & " GeometryServiceUrl=""http://tasks.arcgisonline.com/arcgis/services/Geometry/GeometryServer""" & ControlChars.CrLf & " ShowDockButton=""True"" Docked=""False"" > </{0}:FindNearTask>")> _ Public Class FindNearTask Inherits ESRI.ArcGIS.ADF.Web.UI.WebControls.FloatingPanelTask #Region "Instance Varables" ' UI Controls Private _taskToolbar As ESRI.ArcGIS.ADF.Web.UI.WebControls.Toolbar Private _selectionLayerDropDownList As System.Web.UI.WebControls.DropDownList Private _selectionLayerLabel As System.Web.UI.WebControls.Label Private _searchDistanceTextBox As System.Web.UI.WebControls.TextBox Private _unitsDropDownList As System.Web.UI.WebControls.DropDownList Private _searchLayerDropDownList As System.Web.UI.WebControls.DropDownList Private _activityIndicatorDiv As System.Web.UI.HtmlControls.HtmlGenericControl Private _findButton As System.Web.UI.HtmlControls.HtmlInputButton Private _graphicsLayerContextMenu As ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenu ' Tracking variables shared internally Private _taskFrameworkJobID As String = Nothing Private _newTaskResultsPanel As Boolean = False Private _originalDataSetName As String = Nothing ' Internal references to buddied Map and TaskResults controls Private _map As ESRI.ArcGIS.ADF.Web.UI.WebControls.Map = Nothing Private _taskResults As ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResults = Nothing #End Region #Region "Properties" #Region "Internal Properties" ' The task's input parameters. See InputParameters.cs for the parameters' class definition. Friend Property TaskInput() As FindNearTask_VBNet.InputParameters Get ' Attempt to retrieve the input parameters from state Dim inputParameters As InputParameters = TryCast(StateManager.GetProperty("FindNearTaskInputParameters"), InputParameters) If inputParameters Is Nothing Then ' Since no parameters were stored in state, create a new InputParameters object inputParameters = New InputParameters() ' Initialize the TaskInput property so the InputParameters object is stored in state Me.TaskInput = inputParameters End If ' Return the parameters Return inputParameters End Get Set(ByVal value As FindNearTask_VBNet.InputParameters) ' Store the passed-in parameters in state StateManager.SetProperty("FindNearTaskInputParameters", value) End Set End Property ' Graphics resource used to store user input and buffer graphics layers. The geometries of the features ' in this resource are used as input for the task. Friend ReadOnly Property TaskInputGraphicsResource() As FindNearTask_VBNet.GraphicsResource Get ' Attempt to retrieve the task's graphics resource from state Dim taskGraphicsResource As FindNearTask_VBNet.GraphicsResource = TryCast(Me.StateManager.GetProperty("TaskInputGraphicsResource"), FindNearTask_VBNet.GraphicsResource) If taskGraphicsResource Is Nothing Then ' Since the task's graphics resource is not yet in state, create it and store it Dim resourceName As String = String.Format("{0} Input Graphics Resource", Me.ClientID) taskGraphicsResource = New FindNearTask_VBNet.GraphicsResource(resourceName, Me.MapInstance) Me.StateManager.SetProperty("TaskInputGraphicsResource", taskGraphicsResource) End If ' Return the resource Return taskGraphicsResource End Get End Property #End Region #Region "Private Properties" ' Whether to define the search area by selecting a task result Private Property SearchAreaByTaskResult() As Boolean Get ' Check whether the property is stored in state. If not, return false. If so, return ' the value from state. If StateManager.GetProperty("SearchAreaByTaskResult") Is Nothing Then Return False Else Return CBool(StateManager.GetProperty("SearchAreaByTaskResult")) End If End Get Set(ByVal value As Boolean) ' Store the passed-in value in state StateManager.SetProperty("SearchAreaByTaskResult", value) End Set End Property ' Returns the buddied Map Private ReadOnly Property MapInstance() As ESRI.ArcGIS.ADF.Web.UI.WebControls.Map Get Return Me.TaskResultsInstance.MapInstance End Get End Property ' Returns the first buddied TaskResults container that has a buddied Map Private ReadOnly Property TaskResultsInstance() As ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResults Get ' Check whether the internal task results variable is null If _taskResults Is Nothing Then ' Iterate through the the task's buddied TaskResults containers. Exit the loop when the first one wtih ' a buddied Map control is found. For i As Integer = 0 To Me.TaskResultsContainers.Count - 1 _taskResults = TryCast(ESRI.ArcGIS.ADF.Web.UI.WebControls.Utility.FindControl(Me.TaskResultsContainers(i).Name, Me.Page), ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResults) If _taskResults IsNot Nothing AndAlso _taskResults.MapInstance IsNot Nothing Then Exit For End If Next i End If ' Return the internal variable storing the reference to the TaskResults Return _taskResults End Get End Property ' Counts the number of times the task has executed. Used to apply a unique ID to new TaskResultsPanels displaying resutls. Private Property SearchCount() As Integer Get If Me.StateManager.GetProperty("OperationCount") Is Nothing Then Return 1 Else Return CInt(Fix(Me.StateManager.GetProperty("OperationCount"))) End If End Get Set(ByVal value As Integer) Me.StateManager.SetProperty("OperationCount", value) End Set End Property #End Region #Region "Public Properties" ''' <summary> ''' How tabular results will be displayed ''' </summary> <System.Web.UI.PersistenceMode(System.Web.UI.PersistenceMode.Attribute), System.ComponentModel.Browsable(True), System.ComponentModel.NotifyParentProperty(True), System.ComponentModel.DefaultValue(TabularResultOptions.TableInFloatingPanel), System.ComponentModel.Description("How tabular results will be displayed"), System.ComponentModel.Category("Task")> _ Public Property TabularResultOptions() As TabularResultOptions Get ' Attempt retrieving the tabular result options from state. If not found, return the default ' option. Otherwise, return the value from state. Dim obj As Object = StateManager.GetProperty("TabularResultOptions") Return If((obj Is Nothing), TabularResultOptions.TableInFloatingPanel, CType(obj, TabularResultOptions)) End Get ' Store the passed-in value in state Set(ByVal value As TabularResultOptions) StateManager.SetProperty("TabularResultOptions", value) End Set End Property ''' <summary> ''' The URL of an ArcGIS Server Geometry Service. Required for calculating the search area. ''' </summary> <System.Web.UI.PersistenceMode(System.Web.UI.PersistenceMode.Attribute), System.ComponentModel.Browsable(True), System.ComponentModel.NotifyParentProperty(True), System.ComponentModel.DefaultValue("http://tasks.arcgisonline.com/arcgis/services/Geometry/GeometryServer"), System.ComponentModel.Description("URL for an ArcGIS Server geometry service"), System.ComponentModel.Category("Task")> _ Public Property GeometryServiceUrl() As String Get ' Attempt retrieving the geometry service URL from state. If not found, return the default ' URL. Otherwise, return the value from state. Dim obj As Object = StateManager.GetProperty("GeometryServiceUrl") Return If((obj Is Nothing), "http://tasks.arcgisonline.com/arcgis/services/Geometry/GeometryServer", CStr(obj)) End Get ' Store the passed-in value in state Set(ByVal value As String) StateManager.SetProperty("GeometryServiceUrl", value) End Set End Property #End Region #End Region #Region "ASP.NET WebControl Life Cycle Event Handlers" Protected Overrides Sub CreateChildControls() MyBase.CreateChildControls() ' Do not create child controls if the control is being rendered at design-time If Me.DesignMode Then Return End If ' Table to format the task interface and add it to the task's controls Dim taskInterfaceTable As New System.Web.UI.WebControls.Table() Controls.Add(taskInterfaceTable) ' Row for the distance label, distance textbox, and units label Dim tableRow As New System.Web.UI.WebControls.TableRow() taskInterfaceTable.Rows.Add(tableRow) ' Cell for the search area tools label Dim tableCell As New System.Web.UI.WebControls.TableCell() tableCell.ColumnSpan = 2 tableCell.Style(System.Web.UI.HtmlTextWriterStyle.WhiteSpace) = "nowrap" tableRow.Cells.Add(tableCell) ' Create the search area tools label and add it to the container cell Dim label As New System.Web.UI.WebControls.Label() label.Text = "Search Area Definition Tools" tableCell.Controls.Add(label) ' Create the toolbar containing the task's tools and add it to the interface table CreateTaskToolbar() tableCell.Controls.Add(_taskToolbar) ' Table row and cell for the selection layer controls tableRow = New System.Web.UI.WebControls.TableRow() taskInterfaceTable.Rows.Add(tableRow) tableCell = New System.Web.UI.WebControls.TableCell() tableCell.ColumnSpan = 2 tableCell.Style(System.Web.UI.HtmlTextWriterStyle.WhiteSpace) = "nowrap" tableRow.Cells.Add(tableCell) ' Create selection layer label and drop-down list and add them to the table CreateSelectionLayerControls() tableCell.Controls.Add(_selectionLayerLabel) tableCell.Controls.Add(_selectionLayerDropDownList) ' Table row and cell for the Add New Search Areas to Previous checkbox tableRow = New System.Web.UI.WebControls.TableRow() taskInterfaceTable.Rows.Add(tableRow) tableCell = New System.Web.UI.WebControls.TableCell() tableCell.ColumnSpan = 2 tableCell.Style(System.Web.UI.HtmlTextWriterStyle.WhiteSpace) = "nowrap" tableRow.Cells.Add(tableCell) ' Create a checkbox to give user the option of overwriting or adding to task input geometries and add ' it to the UI table tableCell.Controls.Add(CreateAddToInputCheckbox()) ' Row for the search distance controls tableRow = New System.Web.UI.WebControls.TableRow() tableRow.Style(System.Web.UI.HtmlTextWriterStyle.WhiteSpace) = "nowrap" taskInterfaceTable.Rows.Add(tableRow) ' Cell for the search distance label and textbox tableCell = New System.Web.UI.WebControls.TableCell() tableCell.Style(System.Web.UI.HtmlTextWriterStyle.WhiteSpace) = "nowrap" tableRow.Cells.Add(tableCell) ' Create the search distance label and add it to the cell tableCell.Controls.Add(CreateSearchDistanceLabel()) ' Add the search distance textbox to the table CreateSearchDistanceControls() tableCell.Controls.Add(_searchDistanceTextBox) ' Cell for the units drop-down list tableCell = New System.Web.UI.WebControls.TableCell() tableCell.Style(System.Web.UI.HtmlTextWriterStyle.WhiteSpace) = "nowrap" tableRow.Cells.Add(tableCell) ' Add the units drop-down list to the table tableCell.Controls.Add(_unitsDropDownList) ' Table row and cell for the search layer label and drop-down list tableRow = New System.Web.UI.WebControls.TableRow() taskInterfaceTable.Rows.Add(tableRow) tableCell = New System.Web.UI.WebControls.TableCell() tableCell.ColumnSpan = 2 tableCell.Style(System.Web.UI.HtmlTextWriterStyle.WhiteSpace) = "nowrap" tableRow.Cells.Add(tableCell) ' Create search layer label and add it to the table tableCell.Controls.Add(CreateSearchLayerLabel()) ' Create selection layer drop-down list and add it to the table CreateSearchLayerDropDownList() tableCell.Controls.Add(_searchLayerDropDownList) ' Row and cell for the Find button tableRow = New System.Web.UI.WebControls.TableRow() taskInterfaceTable.Rows.Add(tableRow) tableCell = New System.Web.UI.WebControls.TableCell() tableCell.ColumnSpan = 2 tableCell.Style(System.Web.UI.HtmlTextWriterStyle.WhiteSpace) = "nowrap" tableRow.Cells.Add(tableCell) ' Create the Find button to the container table cell CreateFindButton() tableCell.Controls.Add(_findButton) ' Create and add the activity indicator div to the table CreateActivityIndicatorDiv() tableCell.Controls.Add(_activityIndicatorDiv) ' If tabular results are to appear in a floating panel, call the function to create the task results ' context menu containing an item to show the panel If TabularResultOptions = TabularResultOptions.TableInFloatingPanel Then Me.CreateTaskResultsPanelContextMenu() End If ' Add handlers for the task results container's node events. The NodeAdded and NodeRemoved hanlders ' manage creating and destroying TaskResultsPanels for the associated task results, while the NodeClicked ' handler incorporates adding the clicked task result's search geometry if the tool to specify ' input by task result is selected AddHandler TaskResultsInstance.NodeAdded, AddressOf TaskResults_NodeAdded AddHandler TaskResultsInstance.NodeRemoved, AddressOf TaskResults_NodeRemoved AddHandler TaskResultsInstance.NodeClicked, AddressOf TaskResults_NodeClicked End Sub Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter) MyBase.Render(writer) If DesignMode Then Return End If ' Register the JavaScript file containing the functions used by the task If (Not Me.Page.ClientScript.IsStartupScriptRegistered("FindNearTaskScript")) Then Me.Page.ClientScript.RegisterStartupScript(GetType(FindNearTask_VBNet.FindNearTask), "FindNearTaskScript", FindNearTask_VBNet.ResourceUtility.GetJavascript(Me, "FindNearTask.js", GetType(FindNearTask_VBNet.FindNearTask))) End If ' Registered the TaskResultsPanel's scripts FindNearTask_VBNet.TaskResultsPanel.RegisterScripts(Me) ' Find all the toolbars on the page and construct a string containing their IDs Dim toolbarList As System.Collections.Generic.List(Of ESRI.ArcGIS.ADF.Web.UI.WebControls.Toolbar) = ESRI.ArcGIS.ADF.Web.UI.WebControls.Utility.FindControls(Of ESRI.ArcGIS.ADF.Web.UI.WebControls.Toolbar)(Me.Page.Controls) Dim toolbarIDs As String = "" For Each toolbar As ESRI.ArcGIS.ADF.Web.UI.WebControls.Toolbar In toolbarList toolbarIDs &= toolbar.ClientID & "," Next toolbar If toolbarIDs.Length > 0 Then toolbarIDs = toolbarIDs.Substring(0, toolbarIDs.Length - 1) End If ' Construct JavaScript to pass server-side task initialization data to the client Dim initializationScriptKey As String = "FindNearTaskInitializationScript" If (Not Page.ClientScript.IsStartupScriptRegistered(initializationScriptKey)) Then Dim initializationScript As String = "" & ControlChars.CrLf & " function findNearTaskInit() {{" & ControlChars.CrLf & " _callbackFunctionString = ""{0}"";" & ControlChars.CrLf & " " & ControlChars.CrLf & " var toolbarIDs = '{1}';" & ControlChars.CrLf & " toolbarIDs = toolbarIDs.split(',');" & ControlChars.CrLf & " for (var i = 0; i < toolbarIDs.length; i++)" & ControlChars.CrLf & " {{" & ControlChars.CrLf & " var toolbar = $find(toolbarIDs[i]);" & ControlChars.CrLf & " if (toolbar)" & ControlChars.CrLf & " toolbar.add_onToolSelected(toolSelected);" & ControlChars.CrLf & " }}" & ControlChars.CrLf & ControlChars.CrLf & " _selectionLayerLabel = $get('{2}'); " & ControlChars.CrLf & " _selectionLayerDropDownList = $get('{3}');" & ControlChars.CrLf & " _searchDistanceTextBox = $get('{4}');" & ControlChars.CrLf & ControlChars.CrLf & " _unitsDropDownList = $get('{5}');" & ControlChars.CrLf & " _buddyMapID = '{6}';" & ControlChars.CrLf & " _findButton = $get('{7}');" & ControlChars.CrLf & " _activityIndicatorDiv = $get('{8}');" & ControlChars.CrLf & " _buddyTaskResultsID = '{9}';" & ControlChars.CrLf & ControlChars.CrLf & " initAsyncRequestHandler();" & ControlChars.CrLf & " }}" & ControlChars.CrLf & ControlChars.CrLf & " Sys.Application.add_init(findNearTaskInit);" initializationScript = String.Format(initializationScript, Me.CallbackFunctionString, toolbarIDs, _selectionLayerLabel.ClientID, _selectionLayerDropDownList.ClientID, _searchDistanceTextBox.ClientID, _unitsDropDownList.ClientID, Me.MapInstance.ClientID, _findButton.ClientID, _activityIndicatorDiv.ClientID, Me.TaskResultsInstance.ClientID) ' Register the script on the page Page.ClientScript.RegisterStartupScript(Me.GetType(), initializationScriptKey, initializationScript, True) End If Me.TaskResultsInstance.ShowRowCount = False End Sub #End Region #Region "Web ADF Control Event Handlers" ' Fires when a node is removed from the TaskResults control buddied to the task. If the removed node corresponds ' to a TaskResultsPanel, then that panel is detroyed here. Private Sub TaskResults_NodeRemoved(ByVal sender As Object, ByVal args As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNodeRemovedEventArgs) ' Check whether results are being shown in a TaskResultsPanel If Me.TabularResultOptions = TabularResultOptions.TableInFloatingPanel Then ' Call method to retrieve a GraphicsLayerNode that is the child of the current node. Note this method ' will also check whether the current node is a GraphicsLayerNode Dim graphicsLayerNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.GraphicsLayerNode = Me.FindChildGraphicsLayerNode(args.Node) ' Check whether a GraphicsLayerNode was found If graphicsLayerNode IsNot Nothing Then ' Construct JavaScript to find the TaskResultsPanel corresponding to the GraphicsLayerNode and ' destroy it. Dim taskResultsPanelClientID As String = String.Format("{0}_{1}_TaskResultsPanel", Me.ClientID, graphicsLayerNode.NodeID) Dim disposeResultsPanelJavaScript As String = "" & ControlChars.CrLf & " var taskResultsPanel = $find('{0}');" & ControlChars.CrLf & " if (taskResultsPanel)" & ControlChars.CrLf & " {{" & ControlChars.CrLf & " taskResultsPanel.hide(false);" & ControlChars.CrLf & " taskResultsPanel.dispose();" & ControlChars.CrLf & " }}" & ControlChars.CrLf & " var element = $get('{0}');" & ControlChars.CrLf & " if (element)" & ControlChars.CrLf & " element.parentNode.removeChild(element);" disposeResultsPanelJavaScript = String.Format(disposeResultsPanelJavaScript, taskResultsPanelClientID) ' Encapsulate the JavaScript in a callback result and add it to the task's collection of CallbackResults Dim disposeResultsPanelCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(disposeResultsPanelJavaScript) Me.CallbackResults.Add(disposeResultsPanelCallbackResult) End If End If ' Retrieve any FeatureNodes that are children of the removed node. Note this call will also check whether ' the current node is a FeatureNode. Dim featureNodes As New System.Collections.Generic.List(Of ESRI.ArcGIS.ADF.Web.UI.WebControls.FeatureNode)() Me.FindChildFeatureNodes(args.Node, featureNodes) ' Check whether any FeatureNodes were found If featureNodes.Count > 0 Then ' For each FeatureNode, construct JavaScript to reset the corresponding entry in the client-side array ' storing FeatureNode IDs to null Dim removeNodeIDsJavaScript As String = "" For Each featureNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.FeatureNode In featureNodes removeNodeIDsJavaScript &= String.Format("_featureNodeIDs['{0}'] = null;", featureNode.NodeID) Next featureNode ' Wrap the JavaScript in a CallbackResult and add it to the task's collection Dim removeNodeIDsCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(removeNodeIDsJavaScript) Me.CallbackResults.Add(removeNodeIDsCallbackResult) End If ' Add any CallbackResults created by the task to the calling controls results so they are processed on the client Me.CopyCallbackResultsToCaller(Me.CallbackResults) End Sub ' Fires when a node is added to the TaskResults control buddied to the Task. Private Sub TaskResults_NodeAdded(ByVal sender As Object, ByVal args As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNodeEventArgs) ' Check whether the internal flag indicating that a new TaskResultsPanel needs to be created is true and ' results are to be shown in a TaskResultsPanel If Me._newTaskResultsPanel AndAlso (Me.TabularResultOptions = TabularResultOptions.TableInFloatingPanel) Then ' Get the GraphicsLayerNode that is an ancestor or descendant of the current node Dim graphicsLayerNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.GraphicsLayerNode = Me.GetRelatedGraphicsLayerNode(args.Node) ' Make sure a GraphicsLayerNode was found and that the name of the dataset containing the GraphicsLayer it ' references does not match the dataset name that was assigned in ExecuteTask. We do this because the Web ' ADF replaces the original node with one that has IDs that are used internally by other ADF components. ' The DataSetName in particular holds the name of the resource that contains the results GraphicsLayer. If graphicsLayerNode IsNot Nothing AndAlso graphicsLayerNode.Layer.DataSet.DataSetName <> Me._originalDataSetName Then ' Create the TaskResultsPanel that will be used to display results Dim taskResultsPanelID As String = String.Format("{0}_TaskResultsPanel", graphicsLayerNode.NodeID) Dim taskResultsPanelTitle As String = String.Format("{0} Results - {1}", Me.Title, graphicsLayerNode.Layer.TableName) Dim taskResultsPanel As FindNearTask_VBNet.TaskResultsPanel = Me.CreateTaskResultsPanel(taskResultsPanelID, taskResultsPanelTitle) ' When a Web ADF FloatingPanel is rendered during an asynchronous request, the ADF automatically creates ' a callback result that includes a call to the private client-side function _checkDock. In cases where the ' FloatingPanel does not have a docking container, this interferes with the FloatingPanel's initialization. ' So we remove that callback result here. Dim checkDockJavaScript As String = String.Format("$find('{0}')._checkDock();", taskResultsPanel.ClientID) Dim callbackResultToRemove As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = Nothing For Each callbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult In taskResultsPanel.CallbackResults If TryCast(callbackResult.Parameters(0), String) = checkDockJavaScript Then callbackResultToRemove = callbackResult Exit For End If Next callbackResult If callbackResultToRemove IsNot Nothing Then taskResultsPanel.CallbackResults.Remove(callbackResultToRemove) End If ' Get the name of the resource containing the results GraphicsLayer and call SetLayer to associate the ' TaskResultsPanel with the GraphicsLayer Dim resourceName As String = graphicsLayerNode.Layer.DataSet.DataSetName taskResultsPanel.SetLayer(TryCast(graphicsLayerNode.Layer, ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer), resourceName, Me.TaskResultsInstance.Map) ' Call ShowFloatingPanel to display the results panel taskResultsPanel.ShowFloatingPanel() ' Copy the results panel's callback results to the task's results collection so changes made to the ' panel requiring client-side handling are processed Me.CallbackResults.CopyFrom(taskResultsPanel.CallbackResults) ' Reset the flag indicating whether a new TaskResultsPanel needs to be created Me._newTaskResultsPanel = False End If End If ' Find any FeatureNodes that are descendants of the added node Dim featureNodes As New System.Collections.Generic.List(Of ESRI.ArcGIS.ADF.Web.UI.WebControls.FeatureNode)() Me.FindChildFeatureNodes(args.Node, featureNodes) ' Check whether any FeatureNodes were found If featureNodes.Count > 0 Then ' Create JavaScript to add each FeatureNode's ID to a client-side array. This allows the tool to ' specify search area by clicking on a task result to determine if a clicked node is a FeatureNode ' and show a progress indicator accordingly. Dim defineNodeIDsJavaScript As String = "" For Each featureNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.FeatureNode In featureNodes defineNodeIDsJavaScript &= String.Format("_featureNodeIDs['{0}'] = true;", featureNode.NodeID) Next featureNode ' Put the JavaScript in a CallbackResult and add it to the task's collection Dim defineNodeIDsCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(defineNodeIDsJavaScript) Me.CallbackResults.Add(defineNodeIDsCallbackResult) End If ' Check whether the control that initiated the asynchronous request is the task. If not, copy the task's ' callback results to the control that did. If Me.GetCallingControl(Me.Page).UniqueID <> Me.UniqueID Then Me.CopyCallbackResultsToCaller(Me.CallbackResults) End If End Sub ' Fires when a node on the buddied TaskResults control is clicked. Updates the search area geometry with that of ' the feature corresponding to the clicked node if the node is a FeatureNode and the tool to specify search area by ' task result is active, Private Sub TaskResults_NodeClicked(ByVal sender As Object, ByVal args As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNodeEventArgs) ' Check whether the passed-in node is a feature node and the define search area by task result tool is active If Me.SearchAreaByTaskResult AndAlso (TypeOf args.Node Is ESRI.ArcGIS.ADF.Web.UI.WebControls.FeatureNode) Then ' Get a reference to the clicked node as a FeatureNode Dim clickedFeatureNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.FeatureNode = TryCast(args.Node, ESRI.ArcGIS.ADF.Web.UI.WebControls.FeatureNode) ' Loop through the data of the FeatureNode until the feature geometry is found For Each value As Object In clickedFeatureNode.DataRow.ItemArray If TypeOf value Is ESRI.ArcGIS.ADF.Web.Geometry.Geometry Then ' Put the feature geometry in a geometry array Dim inputGeometries(0) As ESRI.ArcGIS.ADF.Web.Geometry.Geometry inputGeometries(0) = TryCast(value, ESRI.ArcGIS.ADF.Web.Geometry.Geometry) ' Update the task's input geometries with the feature geometry Me.TaskInput.SetUserInputGeometries(inputGeometries) ' Update the task's user input and buffer graphics layer Me.UpdateInputGraphicsLayers() ' Create a callback result to call the client-side function that hides the activity indicator Dim hideActivityIndicatorJavaScript As String = "hideUpdateAreaIndicator();" Dim hideIndicatorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(hideActivityIndicatorJavaScript) Me.CallbackResults.Add(hideIndicatorCallbackResult) ' Check whether the task initiated the request. If not, copy the callback results to the initiating ' control so the updates to the GraphicsLayer are processed on the client. If Me.GetCallingControl(Me.Page).UniqueID <> Me.UniqueID Then Me.CopyCallbackResultsToCaller(Me.CallbackResults) End If Exit For End If Next value End If End Sub ' Fires when the custom GraphicLayer context menu is closed. Private Sub GraphicsLayerContextMenu_Dismissed(ByVal sender As Object, ByVal args As ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuDismissedEventArgs) Me.TaskResultsInstance.ContextMenuDismissed(_graphicsLayerContextMenu, args) End Sub ' Fires when an item on the custom GraphicsLayer context menu is clicked Private Sub GraphicsLayerContextMenu_ItemClicked(ByVal sender As Object, ByVal args As ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItemEventArgs) ' Get the node on which the context menu was displayed Dim graphicsLayerNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.GraphicsLayerNode = TryCast(TaskResultsInstance.Nodes.FindByNodeID(args.Context), ESRI.ArcGIS.ADF.Web.UI.WebControls.GraphicsLayerNode) ' Check the text of the item clicked Select Case args.Item.Text Case "Zoom To Selected Features" If graphicsLayerNode Is Nothing OrElse Me.MapInstance Is Nothing Then Return End If Dim hasFeaturesSelected As Boolean = False ' Get the GraphicsLayer associated with the node Dim graphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer = graphicsLayerNode.Layer ' Declare an envelope to store the combined extent of all features in the layer Dim adfEnvelope As New ESRI.ArcGIS.ADF.Web.Geometry.Envelope() ' Loop through the rows (i.e. features) of the graphics layer, adding the envelope of each to the ' combined extent envelope For i As Integer = 0 To graphicsLayer.Rows.Count - 1 If CBool(graphicsLayer.Rows(i)(graphicsLayer.IsSelectedColumn)) Then hasFeaturesSelected = True Dim rowGeometry As ESRI.ArcGIS.ADF.Web.Geometry.Geometry = graphicsLayer.GeometryFromRow(graphicsLayer.Rows(i)) adfEnvelope.Union(rowGeometry) End If Next i If (Not hasFeaturesSelected) Then Return End If ' If combined envelope width or height is zero, zoom in the amount specified by the ' ZoomToPointFactor property If adfEnvelope.Width = 0 OrElse adfEnvelope.Height = 0 Then Dim adfPoint As New ESRI.ArcGIS.ADF.Web.Geometry.Point(adfEnvelope.XMax, adfEnvelope.YMax) Dim fullExtentEnvelope As ESRI.ArcGIS.ADF.Web.Geometry.Envelope = Me.MapInstance.GetFullExtent() Dim widthMargin As Double = (fullExtentEnvelope.Width / TaskResultsInstance.ZoomToPointFactor) / 2 Dim heightMargin As Double = (fullExtentEnvelope.Height / TaskResultsInstance.ZoomToPointFactor) / 2 Dim zoomToEnvelope As New ESRI.ArcGIS.ADF.Web.Geometry.Envelope() zoomToEnvelope.XMax = adfPoint.X + widthMargin zoomToEnvelope.XMin = adfPoint.X - widthMargin zoomToEnvelope.YMax = adfPoint.Y + heightMargin zoomToEnvelope.YMin = adfPoint.Y - heightMargin Me.MapInstance.Extent = zoomToEnvelope Else ' Apply the combined feature extent to the map Me.MapInstance.Extent = adfEnvelope End If ' Copy the map's callback results to the context menu so the extent change is processed on the client _graphicsLayerContextMenu.CallbackResults.CopyFrom(Me.MapInstance.CallbackResults) Case "Remove" If Me.MapInstance Is Nothing OrElse graphicsLayerNode Is Nothing Then Return End If ' Check whether there is a GraphicsLayer associated with the node If graphicsLayerNode.Layer IsNot Nothing Then ' Remove the GraphicsLayer associated with the node from the map and refresh the layer's ' parent resource Dim graphicsResourceName As String = graphicsLayerNode.RemoveFromMap(Me.TaskResultsInstance) Me.MapInstance.RefreshResource(graphicsResourceName) ' Copy the map's callback results to the context menu so the map is updated on the client _graphicsLayerContextMenu.CallbackResults.CopyFrom(Me.MapInstance.CallbackResults) End If ' Remove the node and refresh the buddied TaskResults control graphicsLayerNode.Remove() Me.TaskResultsInstance.Refresh() ' Copy the buddied TaskResults control's callback results to the context menu so the node removal ' is processed on the client _graphicsLayerContextMenu.CallbackResults.CopyFrom(TaskResultsInstance.CallbackResults) Case "View Attribute Table" ' Construct JavaScript to call the client-side Web ADF function to display the TaskResultsPanel Dim taskResultsPanelClientID As String = String.Format("{0}_{1}_TaskResultsPanel", Me.ClientID, args.Context) Dim showTaskResultsPanelJavaScript As String = String.Format("showFloatingPanel('{0}', false);", taskResultsPanelClientID) Dim showTaskResultsPanelCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(showTaskResultsPanelJavaScript) _graphicsLayerContextMenu.CallbackResults.Add(showTaskResultsPanelCallbackResult) End Select End Sub #End Region #Region "ICallbackEventHandler Overrides - GetCallbackResults" Public Overrides Function GetCallbackResult() As String ' Convert the callback argument string into a name-value collection using the Web ADF's callback ' argument parsing utility Dim callbackArgsCollection As System.Collections.Specialized.NameValueCollection = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(Me.CallbackEventArgument) ' Get the task's job ID _taskFrameworkJobID = callbackArgsCollection("taskJobID") ' Get the callback event argument Dim eventArg As String = callbackArgsCollection("EventArg") Select Case eventArg ' Check whether the event argument indicates that the user has modified the search distance Case "updateSearchArea" ' Get the updated search distance and make sure it is valid Dim searchDistance As String = callbackArgsCollection("searchDistance") Dim units As String = callbackArgsCollection("units") ' Make sure a search distance was entered If (Not String.IsNullOrEmpty(searchDistance)) Then Dim newSearchDistance As Single If Single.TryParse(searchDistance, newSearchDistance) Then Me.TaskInput.SearchDistance = newSearchDistance End If Me.TaskInput.Units = units ' Update the graphics layer showing the search area Me.UpdateInputGraphicsLayers() ' Copy the callback results from the map so the graphics layer update is processed ' on the client Me.CallbackResults.CopyFrom(MapInstance.CallbackResults) End If ' Create callback result to hide the task's activity indicator Dim hideActivityIndicatorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript("hideUpdateAreaIndicator();") Me.CallbackResults.Add(hideActivityIndicatorCallbackResult) Case "toggleSelectByTaskResult" ' Set the flag indicating wheteher the define search area by task result tool Me.SearchAreaByTaskResult = Boolean.Parse(callbackArgsCollection("Value")) Case "toggleAddToInput" ' Set the flag indicating whether newly defined geometries are to be added to those already defined Me.TaskInput.AddToInputGeometry = Not Me.TaskInput.AddToInputGeometry Case "updateSearchLayer" ' Get the map resource and layer ID for the layer clicked. These values are stored as the value of ' the tree view plus node and are comma delimited. Dim searchLayerParameters() As String = callbackArgsCollection("searchLayerParameters").Split(New Char() {","c}) ' Update the task's input parameters with the node's information Me.TaskInput.SearchResource = searchLayerParameters(0) Me.TaskInput.SearchLayer = searchLayerParameters(1) End Select Return MyBase.GetCallbackResult() End Function ' Updates the geometries of the user input and buffer graphics layers Friend Sub UpdateInputGraphicsLayers() ' If there are not defined input geometries, exit the function If Me.TaskInput.UserInputGeometries Is Nothing OrElse Me.TaskInput.UserInputGeometries.Length = 0 Then Return End If ' Get the graphics layer displaying the user defined geometries and clear it Dim inputGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer = TryCast(Me.TaskInputGraphicsResource.GetUserInputLayer(Me.MapInstance.MapResourceManagerInstance), ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer) Dim adfSearchGeometries() As ESRI.ArcGIS.ADF.Web.Geometry.Geometry = Me.TaskInput.UserInputGeometries inputGraphicsLayer.Clear() ' Get the search distance Dim searchDistance As Single = TaskInput.SearchDistance ' Make sure the user specified geometries and distance are valid If adfSearchGeometries IsNot Nothing AndAlso (Not Single.IsNaN(searchDistance)) AndAlso searchDistance > 0.0 Then Dim inputGraphicElement As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement = Nothing ' Create a symbol for the user specified geometry For i As Integer = 0 To adfSearchGeometries.Length - 1 If TypeOf adfSearchGeometries(i) Is ESRI.ArcGIS.ADF.Web.Geometry.Point Then Dim adfSearchPointSymbol As New ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol(System.Drawing.Color.Green, 10, ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Star) ' Create a graphic element for the search point and add it to the graphics layer inputGraphicElement = New ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement(adfSearchGeometries(i), adfSearchPointSymbol) ElseIf TypeOf adfSearchGeometries(i) Is ESRI.ArcGIS.ADF.Web.Geometry.Polyline Then Dim adfSearchLineSymbol As New ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleLineSymbol(System.Drawing.Color.Green, 4, ESRI.ArcGIS.ADF.Web.Display.Symbol.LineType.Solid) inputGraphicElement = New ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement(adfSearchGeometries(i), adfSearchLineSymbol) ElseIf TypeOf adfSearchGeometries(i) Is ESRI.ArcGIS.ADF.Web.Geometry.Polygon Then Dim adfSearchFillSymbol As New ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleFillSymbol(System.Drawing.Color.Green, System.Drawing.Color.Black, 50, 20, ESRI.ArcGIS.ADF.Web.Display.Symbol.PolygonFillType.Solid) inputGraphicElement = New ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement(adfSearchGeometries(i), adfSearchFillSymbol) End If inputGraphicsLayer.Add(inputGraphicElement) Next i ' Get the buffer geometry for the search geometry and distance Me.TaskInput.BufferGeometry = Me.BufferGeometries(adfSearchGeometries, searchDistance, Me.TaskInput.Units) ' Create a graphic element for the buffer and add it to the graphics layer Dim bufferElement As New ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement(Me.TaskInput.BufferGeometry, System.Drawing.Color.Red, 75) Dim bufferGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer = Me.TaskInputGraphicsResource.GetBufferLayer(Me.MapInstance.MapResourceManagerInstance) bufferGraphicsLayer.Clear() bufferGraphicsLayer.Add(bufferElement) End If ' Refresh the resource containing the input graphics layer MapInstance.RefreshResource(Me.TaskInputGraphicsResource.ResourceName) ' Check whether the map is the control that initiated the request. If not, copy the Map's callback results to the ' initiating control so the map's updates are processed on the client. If Me.GetCallingControl(Me.Page).UniqueID <> Me.MapInstance.UniqueID Then Me.CopyCallbackResultsToCaller(Me.MapInstance.CallbackResults) End If End Sub ' Clears the user input and buffer graphics layers Friend Sub ClearTaskInput() ' Temporarily store AddToInputGeometry Dim addToInputGeometry As Boolean = Me.TaskInput.AddToInputGeometry ' Set AddToInputGeometry to false and pass null to SetUserInputGeometries to clear the input ' geometries Me.TaskInput.AddToInputGeometry = False Me.TaskInput.SetUserInputGeometries(Nothing) ' Revert the value of AddToInputGeometry Me.TaskInput.AddToInputGeometry = addToInputGeometry ' Set the buffer geometry to null Me.TaskInput.BufferGeometry = Nothing ' Retrieve and clear the user input and buffer graphics layers Dim elementGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer = Me.TaskInputGraphicsResource.GetUserInputLayer(Me.MapInstance.MapResourceManagerInstance) elementGraphicsLayer.Clear() elementGraphicsLayer = Me.TaskInputGraphicsResource.GetBufferLayer(Me.MapInstance.MapResourceManagerInstance) elementGraphicsLayer.Clear() ' Update the resource containing the input graphics layers Me.MapInstance.RefreshResource(Me.TaskInputGraphicsResource.ResourceName) End Sub #End Region #Region "Web ADF Task Overrides - ExecuteTask, GetGISResourceItemDependencies" ' Called when the Find button is clicked Public Overrides Sub ExecuteTask() If Me.TaskInput.BufferGeometry Is Nothing Then Return End If ' Get the buddied map resource manager Dim mapResourceManager As ESRI.ArcGIS.ADF.Web.UI.WebControls.MapResourceManager = Me.MapInstance.MapResourceManagerInstance ' Get the map resource item containing the resource to be searched Dim mapResourceItem As ESRI.ArcGIS.ADF.Web.UI.WebControls.MapResourceItem = mapResourceManager.ResourceItems.Find(Me.TaskInput.SearchResource) ' Make sure the search resource is initialized If mapResourceItem.Resource Is Nothing OrElse (Not mapResourceItem.Resource.Initialized) Then mapResourceItem.InitializeResource() End If ' Get a reference to the resource item's map resource Dim commonMapResource As ESRI.ArcGIS.ADF.Web.DataSources.IMapResource = TryCast(mapResourceItem.Resource, ESRI.ArcGIS.ADF.Web.DataSources.IMapResource) ' Use the resource to create a query functionality Dim queryFunctionalityName As String = String.Format("{0}_QueryFunctionality", Me.ID) Dim queryFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality = TryCast(commonMapResource.CreateFunctionality(GetType(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), queryFunctionalityName), ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality) ' Instantiate a spatial filter with the buffer geometry Dim adfSpatialFilter As New ESRI.ArcGIS.ADF.Web.SpatialFilter() adfSpatialFilter.Geometry = Me.TaskInput.BufferGeometry ' Specify that the query return the geometries of result features adfSpatialFilter.ReturnADFGeometries = True ' Set the spatial reference of the query results to match that of the map adfSpatialFilter.OutputSpatialReference = MapInstance.SpatialReference ' Execute the query Dim resultsDataTable As System.Data.DataTable = queryFunctionality.Query(Nothing, TaskInput.SearchLayer, adfSpatialFilter) ' Make sure results were found and they can be shown as a graphics layer If resultsDataTable Is Nothing OrElse Not (TypeOf resultsDataTable Is ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer) Then Return End If ' Convert query results to a graphics layer Dim resultsGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer = ESRI.ArcGIS.ADF.Web.Converter.ToGraphicsLayer(resultsDataTable) ' Retrieve and apply the layer format of the search layer to the results Dim layerFormat As ESRI.ArcGIS.ADF.Web.UI.WebControls.LayerFormat = ESRI.ArcGIS.ADF.Web.UI.WebControls.LayerFormat.FromMapResourceManager(mapResourceManager, Me.TaskInput.SearchResource, Me.TaskInput.SearchLayer) layerFormat.Apply(resultsGraphicsLayer) ' Set RenderOnClient to true so highlighting and maptips are enabled on the results resultsGraphicsLayer.RenderOnClient = True ' Select all features so that they are visible by default For Each dataRow As System.Data.DataRow In resultsGraphicsLayer.Rows dataRow(resultsGraphicsLayer.IsSelectedColumn) = True Next dataRow ' Create a graphics dataset and add the results graphics layer to it Dim resultsGraphicsDataSet As New ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet() resultsGraphicsDataSet.DataSetName = String.Format("{0} Results ({1})", Me.Title, resultsGraphicsLayer.Rows.Count) resultsGraphicsDataSet.Tables.Add(resultsGraphicsLayer) ' Get the number of searches performed and append the ordinal suffix Dim searchCount As String = Me.SearchCount.ToString() Dim searchCountDescription As String Select Case searchCount.Substring(searchCount.Length - 1) Case "1" searchCount &= "st" Case "2" searchCount &= "nd" Case "3" searchCount &= "rd" Case Else searchCount &= "th" End Select ' Create a count description with the search count searchCountDescription = String.Format("{0} search", searchCount) ' Create the results GraphicsLayer's table name from the ADF generated table name, the number of ' rows, and the search count string resultsGraphicsLayer.TableName = String.Format("{0} ({1} found, {2})", resultsGraphicsLayer.TableName, resultsGraphicsLayer.Rows.Count, searchCountDescription) ' increment the search count Me.SearchCount += 1 ' If the tabular results are to be formatted in a tree view in the task results container, ' assign the graphics dataset to the task's results. Otherwise, call the method to create ' a custom task results node and assign that method's return value as the task's results. If TabularResultOptions = FindNearTask_VBNet.TabularResultOptions.TreeViewInTaskResults Then Me.Results = resultsGraphicsDataSet ElseIf Me.TabularResultOptions = FindNearTask_VBNet.TabularResultOptions.TableInFloatingPanel Then Me.Results = Me.CreateCustomTaskResultsNode(resultsGraphicsDataSet) If resultsGraphicsLayer.Rows.Count > 0 Then Me._newTaskResultsPanel = True Me._originalDataSetName = resultsGraphicsDataSet.DataSetName End If End If 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 null. Public Overrides Function GetGISResourceItemDependencies() As System.Collections.Generic.List(Of ESRI.ArcGIS.ADF.Web.UI.WebControls.GISResourceItemDependency) Return Nothing End Function #End Region #Region "Private Methods" ' Retrieves queryable layers from all resources in the passed-in MapResourceManager Private Sub GetQueryableLayers(ByVal mapResourceManager As ESRI.ArcGIS.ADF.Web.UI.WebControls.MapResourceManager, <System.Runtime.InteropServices.Out()> ByRef layerNamesByResources As System.Collections.Generic.Dictionary(Of String, String()), <System.Runtime.InteropServices.Out()> ByRef layerIDsByResources As System.Collections.Generic.Dictionary(Of String, String())) layerNamesByResources = New System.Collections.Generic.Dictionary(Of String, String())() layerIDsByResources = New System.Collections.Generic.Dictionary(Of String, String())() Dim initializedResourceManager As Boolean = False Try ' If the MapResourceManager is not initialize, do so here If (Not mapResourceManager.Initialized) Then mapResourceManager.Initialize() initializedResourceManager = True End If Dim mapResourceItem As ESRI.ArcGIS.ADF.Web.UI.WebControls.MapResourceItem ' Loop through the resources in the MapResourceManager For i As Integer = 0 To mapResourceManager.ResourceItems.Count - 1 mapResourceItem = mapResourceManager.ResourceItems(i) ' If the current resource is not displayed in the Toc, skip to the next If (Not mapResourceItem.DisplaySettings.DisplayInTableOfContents) Then Continue For End If ' Ensure the resource is initialized mapResourceItem.InitializeResource() ' Get the map resource from the resource item Dim commonMapResource As ESRI.ArcGIS.ADF.Web.DataSources.IMapResource = TryCast(mapResourceItem.Resource, ESRI.ArcGIS.ADF.Web.DataSources.IMapResource) If commonMapResource Is Nothing Then Continue For End If ' If the resource does not support querying, skip to the next If (Not commonMapResource.SupportsFunctionality(GetType(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality))) Then Continue For End If ' Create a query functoinality form the resource Dim commonQueryFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality = TryCast(commonMapResource.CreateFunctionality(GetType(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), System.Guid.NewGuid().ToString("N")), ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality) ' Get arrays containing the resources queryable layer names and IDs Dim layerIDs() As String = Nothing Dim layerNames() As String = Nothing commonQueryFunctionality.GetQueryableLayers(Nothing, layerIDs, layerNames) ' Add the arrays to the layer names and IDs dictionaries, along with the name of the current resource item layerNamesByResources.Add(mapResourceItem.Name, layerNames) layerIDsByResources.Add(mapResourceItem.Name, layerIDs) Next i Catch Finally ' If the MapResourceManager was initialized in this method, call Dispose to restore it to its initial state If initializedResourceManager Then mapResourceManager.Dispose() End If End Try Return End Sub #Region "Task Results Setup Methods" ' Creates a TaskResultNode customized for use with a TaskResultsPanel Private Function CreateCustomTaskResultsNode(ByVal graphicsDataSet As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet) As ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResultNode ' Instantiate a TaskResultNode Dim taskResultNode As New ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResultNode() ' Set the node's text to be the name of the passed-in dataset taskResultNode.Text = graphicsDataSet.DataSetName ' Iterate through the tables in the dataset, creating a node for each For i As Integer = 0 To graphicsDataSet.Tables.Count - 1 ' Check whether the current table contains data for a GraphicsLayer If TypeOf graphicsDataSet.Tables(i) Is ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer Then ' Create a GraphicsLayerNode with the data from the current table. Make it so the node only ' contains the legend swatch. Dim graphicsLayerNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.GraphicsLayerNode = TryCast(Me.TaskResultsInstance.CreateDataTableNode(graphicsDataSet.Tables(i), False, True, False, graphicsDataSet.Tables(i).TableName, graphicsDataSet.Tables(i).TableName), ESRI.ArcGIS.ADF.Web.UI.WebControls.GraphicsLayerNode) ' Associate a custom context menu with the node. This allows opening the associated TaskResultsPanel. Me.SetupContextMenu(graphicsLayerNode) ' Add the node to the buddied TaskResults control taskResultNode.Nodes.Add(graphicsLayerNode) Else ' Since the table does not represent a GraphicsLayer, create a node that includes the table's data Dim treeViewPlusNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode = TaskResultsInstance.CreateDataTableNode(graphicsDataSet.Tables(i), True, True, True, graphicsDataSet.Tables(i).TableName, graphicsDataSet.Tables(i).TableName) ' Add the node to the TaskResults control taskResultNode.Nodes.Add(treeViewPlusNode) End If Next i ' Call SetupTaskResultNode to initialize the functionality of the parent node TaskResultsInstance.SetupTaskResultNode(Me, _taskFrameworkJobID, Me.TaskInput, taskResultNode) Return taskResultNode End Function ' Creates a TaskResultsPanel with the passed-in ID and title Private Function CreateTaskResultsPanel(ByVal ID As String, ByVal title As String) As FindNearTask_VBNet.TaskResultsPanel ' Initialize the TaskResultsPanel Dim taskResultsPanel As New FindNearTask_VBNet.TaskResultsPanel() taskResultsPanel.ID = ID taskResultsPanel.Visible = False taskResultsPanel.CopyAppearance(Me) taskResultsPanel.Style(System.Web.UI.HtmlTextWriterStyle.Position) = "absolute" taskResultsPanel.Style(System.Web.UI.HtmlTextWriterStyle.Left) = "200px" taskResultsPanel.Style(System.Web.UI.HtmlTextWriterStyle.Top) = "200px" taskResultsPanel.ExpandCollapseButton = True taskResultsPanel.WidthResizable = True taskResultsPanel.HeightResizable = True taskResultsPanel.Title = title taskResultsPanel.Docked = False taskResultsPanel.InitialMaxHeight = New System.Web.UI.WebControls.Unit(300, System.Web.UI.WebControls.UnitType.Pixel) taskResultsPanel.InitialMaxWidth = New System.Web.UI.WebControls.Unit(500, System.Web.UI.WebControls.UnitType.Pixel) ' Add the panel to the task's controls collection Me.Controls.Add(taskResultsPanel) ' Since we are adding the taskResultsPanel dynamically at run time, script must be created and ' returned to the client that initializes the panel client-side. InitializeOnClient creates ' this script and adds it to the panel as a callback result. taskResultsPanel.InitializeOnClient(Me, Me.CallbackFunctionString) Return taskResultsPanel End Function ' Instantiates and initializes the context menu to show on task results if results are being displayed in a ' TaskResultsPanel. Private Sub CreateTaskResultsPanelContextMenu() ' Instantiate and initialize the context menu _graphicsLayerContextMenu = New ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenu() _graphicsLayerContextMenu.ID = "graphicsLayerContextMenu" _graphicsLayerContextMenu.BorderColor = System.Drawing.Color.Silver _graphicsLayerContextMenu.BorderStyle = System.Web.UI.WebControls.BorderStyle.Solid _graphicsLayerContextMenu.BorderWidth = New System.Web.UI.WebControls.Unit(1, System.Web.UI.WebControls.UnitType.Pixel) _graphicsLayerContextMenu.HoverColor = System.Drawing.Color.Gainsboro _graphicsLayerContextMenu.BackColor = System.Drawing.Color.White _graphicsLayerContextMenu.ForeColor = ForeColor _graphicsLayerContextMenu.Font.CopyFrom(Me.Font) _graphicsLayerContextMenu.UseDefaultWebResources = Me.UseDefaultWebResources ' Wire item clicked and menu dismissed event handlers AddHandler _graphicsLayerContextMenu.ItemClicked, AddressOf GraphicsLayerContextMenu_ItemClicked AddHandler _graphicsLayerContextMenu.Dismissed, AddressOf GraphicsLayerContextMenu_Dismissed ' Add a menu item to zoom to selected features Dim contextMenuItem As New ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem() contextMenuItem.ImageUrl = ResourceUtility.GetImage("contextMenuZoomTo.gif", Me, GetType(FindNearTask)) contextMenuItem.Text = "Zoom To Selected Features" _graphicsLayerContextMenu.Items.Add(contextMenuItem) ' Add a menu item to remove the GraphicsLayer corresponding to the node on which the context menu was shown contextMenuItem = New ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem() contextMenuItem.ImageUrl = ResourceUtility.GetImage("contextMenuRemove.gif", Me, GetType(FindNearTask)) contextMenuItem.Text = "Remove" _graphicsLayerContextMenu.Items.Add(contextMenuItem) ' Add a menu item to show the corresponding TaskResultsPanel contextMenuItem = New ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem() contextMenuItem.ImageUrl = ResourceUtility.GetImage("contextMenuViewTable.gif", Me, GetType(FindNearTask)) contextMenuItem.Text = "View Attribute Table" _graphicsLayerContextMenu.Items.Add(contextMenuItem) ' Add the context menu to the task's controls collection Me.Controls.Add(_graphicsLayerContextMenu) End Sub ' Method that hooks up the context menu to graphics layer node. Private Sub SetupContextMenu(ByVal graphicsLayerNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.GraphicsLayerNode) TaskResultsInstance.SetupContextMenu(_graphicsLayerContextMenu, graphicsLayerNode) End Sub #End Region #Region "User Interface Creation Methods" ' Instantiates and populates FindNearTask's toolbar Private Sub CreateTaskToolbar() ' Instantiate the toolbar and add it to the cell _taskToolbar = New ESRI.ArcGIS.ADF.Web.UI.WebControls.Toolbar() ' Initialize toolbar properties _taskToolbar.UseDefaultWebResources = Me.UseDefaultWebResources _taskToolbar.ID = "FindNearTaskToolbar" _taskToolbar.WebResourceLocation = Me.WebResourceLocation _taskToolbar.BuddyControlType = ESRI.ArcGIS.ADF.Web.UI.WebControls.BuddyControlType.Map _taskToolbar.ToolbarStyle = ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolbarStyle.ImageOnly _taskToolbar.Height = New System.Web.UI.WebControls.Unit("32px") _taskToolbar.Width = New System.Web.UI.WebControls.Unit("192px") ' Create the add search point tool and add it to the toolbar _taskToolbar.ToolbarItems.Add(CreateSearchPointTool()) ' Create the add search polyline tool and add it to the toolbar _taskToolbar.ToolbarItems.Add(CreateSearchPolylineTool()) ' Create the add search polygon tool and add it to the toolbar _taskToolbar.ToolbarItems.Add(CreateSearchPolygonTool()) ' Create the select input by task results tool and add it to the toolbar _taskToolbar.ToolbarItems.Add(CreateInputByTaskResultTool()) ' Create the select input by map tool and add it to the toolbar _taskToolbar.ToolbarItems.Add(CreateInputByMapTool()) ' Create the clear input tool and add it to the toolbar _taskToolbar.ToolbarItems.Add(CreateClearInputCommand()) ' Get the names of the toolbar groups buddied to the map Dim toolbarGroupNamesArray() As String = ESRI.ArcGIS.ADF.Web.UI.WebControls.Toolbar.FindToolbarGroupsBuddiedTo(MapInstance.UniqueID, Page) ' If the map is not buddied to any toolbar groups, create a new toolbar group for it. Otherwise, use an ' existing one. If toolbarGroupNamesArray Is Nothing OrElse toolbarGroupNamesArray.Length < 1 Then _taskToolbar.Group = String.Format("{0}_FindNearTaskToolbarGroup", MapInstance.UniqueID) Else _taskToolbar.Group = toolbarGroupNamesArray(0) End If ' Encapsulate the map in a BuddyControl and add it to the toolbar's buddy control collection Dim mapBuddyControl As New ESRI.ArcGIS.ADF.Web.UI.WebControls.BuddyControl(MapInstance.UniqueID) _taskToolbar.BuddyControls.Add(mapBuddyControl) End Sub ' Creates the tool to define search area by drawing a point Private Function CreateSearchPointTool() As ESRI.ArcGIS.ADF.Web.UI.WebControls.Tool Dim addSearchPointTool As New ESRI.ArcGIS.ADF.Web.UI.WebControls.Tool() addSearchPointTool.Name = "SearchAreaByPoint" addSearchPointTool.ServerActionAssembly = "FindNearTask_VBNet" addSearchPointTool.ServerActionClass = "FindNearTask_VBNet.SearchAreaByPoint" addSearchPointTool.ToolTip = "Draw a point to search near" addSearchPointTool.ClientAction = ESRI.ArcGIS.ADF.Web.UI.WebControls.MapClientToolAction.Point.ToString() addSearchPointTool.DefaultImage = ResourceUtility.GetImage("point.gif", Me, GetType(FindNearTask)) addSearchPointTool.SelectedImage = ResourceUtility.GetImage("point_selected.gif", Me, GetType(FindNearTask)) addSearchPointTool.HoverImage = ResourceUtility.GetImage("point_hover.gif", Me, GetType(FindNearTask)) Return addSearchPointTool End Function ' Creates the tool to define search area by drawing a polyline Private Function CreateSearchPolylineTool() As ESRI.ArcGIS.ADF.Web.UI.WebControls.Tool Dim addSearchPolylineTool As New ESRI.ArcGIS.ADF.Web.UI.WebControls.Tool() addSearchPolylineTool.Name = "SearchAreaByLine" addSearchPolylineTool.ServerActionAssembly = "FindNearTask_VBNet" addSearchPolylineTool.ServerActionClass = "FindNearTask_VBNet.AddSearchPolyline" addSearchPolylineTool.ToolTip = "Draw a polyline to search near" addSearchPolylineTool.ClientAction = ESRI.ArcGIS.ADF.Web.UI.WebControls.MapClientToolAction.Polyline.ToString() addSearchPolylineTool.DefaultImage = ResourceUtility.GetImage("polyline.gif", Me, GetType(FindNearTask)) addSearchPolylineTool.SelectedImage = ResourceUtility.GetImage("polyline_selected.gif", Me, GetType(FindNearTask)) addSearchPolylineTool.HoverImage = ResourceUtility.GetImage("polyline_hover.gif", Me, GetType(FindNearTask)) Return addSearchPolylineTool End Function ' Creates the tool to define search area by drawing a polygon Private Function CreateSearchPolygonTool() As ESRI.ArcGIS.ADF.Web.UI.WebControls.Tool Dim addSearchPolygonTool As New ESRI.ArcGIS.ADF.Web.UI.WebControls.Tool() addSearchPolygonTool.Name = "SearchAreaByPolygon" addSearchPolygonTool.ServerActionAssembly = "FindNearTask_VBNet" addSearchPolygonTool.ServerActionClass = "FindNearTask_VBNet.AddSearchPolygon" addSearchPolygonTool.ToolTip = "Draw a polygon to search near" addSearchPolygonTool.ClientAction = ESRI.ArcGIS.ADF.Web.UI.WebControls.MapClientToolAction.Polygon.ToString() addSearchPolygonTool.DefaultImage = ResourceUtility.GetImage("polygon.gif", Me, GetType(FindNearTask)) addSearchPolygonTool.SelectedImage = ResourceUtility.GetImage("polygon_selected.gif", Me, GetType(FindNearTask)) addSearchPolygonTool.HoverImage = ResourceUtility.GetImage("polygon_hover.gif", Me, GetType(FindNearTask)) Return addSearchPolygonTool End Function ' Creates the tool to define search area by selecting a task result Private Function CreateInputByTaskResultTool() As ESRI.ArcGIS.ADF.Web.UI.WebControls.Tool Dim selectInputByTaskResultTool As New ESRI.ArcGIS.ADF.Web.UI.WebControls.Tool() selectInputByTaskResultTool.Name = "SearchAreaByTaskResult" selectInputByTaskResultTool.ServerActionAssembly = "FindNearTask_VBNet" selectInputByTaskResultTool.ServerActionClass = "FindNearTask_VBNet.SearchAreaByTaskResult" selectInputByTaskResultTool.ToolTip = "Select a task result to search near" selectInputByTaskResultTool.ClientAction = ESRI.ArcGIS.ADF.Web.UI.WebControls.MapClientToolAction.Point.ToString() selectInputByTaskResultTool.DefaultImage = ResourceUtility.GetImage("selectTaskResult.gif", Me, GetType(FindNearTask)) selectInputByTaskResultTool.SelectedImage = ResourceUtility.GetImage("selectTaskResult_selected.gif", Me, GetType(FindNearTask)) selectInputByTaskResultTool.HoverImage = ResourceUtility.GetImage("selectTaskResult_hover.gif", Me, GetType(FindNearTask)) Return selectInputByTaskResultTool End Function ' Creates the tool to define search area by selecting features from the map Private Function CreateInputByMapTool() As ESRI.ArcGIS.ADF.Web.UI.WebControls.Tool Dim selectInputByMapTool As New ESRI.ArcGIS.ADF.Web.UI.WebControls.Tool() selectInputByMapTool.Name = "SearchAreaBySelection" selectInputByMapTool.ServerActionAssembly = "FindNearTask_VBNet" selectInputByMapTool.ServerActionClass = "FindNearTask_VBNet.SearchAreaBySelection" selectInputByMapTool.ToolTip = "Select features to search near" selectInputByMapTool.ClientAction = ESRI.ArcGIS.ADF.Web.UI.WebControls.MapClientToolAction.DragRectangle.ToString() selectInputByMapTool.DefaultImage = ResourceUtility.GetImage("selectFeature.gif", Me, GetType(FindNearTask)) selectInputByMapTool.SelectedImage = ResourceUtility.GetImage("selectFeature_selected.gif", Me, GetType(FindNearTask)) selectInputByMapTool.HoverImage = ResourceUtility.GetImage("selectFeature_hover.gif", Me, GetType(FindNearTask)) Return selectInputByMapTool End Function ' Creates the command for clearing task input geometry from the map Private Function CreateClearInputCommand() As ESRI.ArcGIS.ADF.Web.UI.WebControls.Command Dim clearInputCommand As New ESRI.ArcGIS.ADF.Web.UI.WebControls.Command() clearInputCommand.Name = "ClearInput" clearInputCommand.ServerActionAssembly = "FindNearTask_VBNet" clearInputCommand.ServerActionClass = "FindNearTask_VBNet.ClearInput" clearInputCommand.ToolTip = "Clear search area features and buffers from the map" clearInputCommand.DefaultImage = ResourceUtility.GetImage("clearInput.gif", Me, GetType(FindNearTask)) clearInputCommand.SelectedImage = ResourceUtility.GetImage("clearInput_selected.gif", Me, GetType(FindNearTask)) clearInputCommand.HoverImage = ResourceUtility.GetImage("clearInput_hover.gif", Me, GetType(FindNearTask)) Return clearInputCommand End Function ' Creates the controls for specifying the layer to select features from for task input Private Sub CreateSelectionLayerControls() _selectionLayerLabel = New System.Web.UI.WebControls.Label() _selectionLayerLabel.ID = "SelectionLayerLabel" _selectionLayerLabel.Text = "Selection Layer:" _selectionLayerLabel.Style(System.Web.UI.HtmlTextWriterStyle.WhiteSpace) = "nowrap" _selectionLayerLabel.Style(System.Web.UI.HtmlTextWriterStyle.PaddingRight) = "5px" _selectionLayerLabel.Style(System.Web.UI.HtmlTextWriterStyle.Display) = "none" _selectionLayerDropDownList = New System.Web.UI.WebControls.DropDownList() _selectionLayerDropDownList.ID = "SelectionLayerDropDownList" _selectionLayerDropDownList.Style(System.Web.UI.HtmlTextWriterStyle.Display) = "none" End Sub ' Creates the checkbox determining whether newly defined search areas are merged with those previously defined Private Function CreateAddToInputCheckbox() As System.Web.UI.WebControls.CheckBox Dim addToInputCheckbox As New System.Web.UI.WebControls.CheckBox() addToInputCheckbox.ID = "AddToInputCheckbox" addToInputCheckbox.Text = "Add New Search Areas to Previous" addToInputCheckbox.Checked = True addToInputCheckbox.Font.Bold = False addToInputCheckbox.Style(System.Web.UI.HtmlTextWriterStyle.WhiteSpace) = "nowrap" addToInputCheckbox.Attributes("onclick") = "addToInputClicked()" Return addToInputCheckbox End Function ' Creates the label for the search distance textbox Private Function CreateSearchDistanceLabel() As System.Web.UI.WebControls.Label Dim label As New System.Web.UI.WebControls.Label() label.Text = "Search Distance:" label.Style(System.Web.UI.HtmlTextWriterStyle.PaddingRight) = "5px" label.Style(System.Web.UI.HtmlTextWriterStyle.WhiteSpace) = "nowrap" Return label End Function ' Creates and populates the search distance textbox and units drop-down list Private Sub CreateSearchDistanceControls() ' Instantiate the search distance textbox _searchDistanceTextBox = New System.Web.UI.WebControls.TextBox() _searchDistanceTextBox.ID = "SearchDistanceTextBox" _searchDistanceTextBox.Width = New System.Web.UI.WebControls.Unit(75, System.Web.UI.WebControls.UnitType.Pixel) ' If the search distance has been defined, use it to initialize the textbox. Otherwise, ' leave it empty. _searchDistanceTextBox.Text = If(Single.IsNaN(TaskInput.SearchDistance), String.Empty, TaskInput.SearchDistance.ToString()) _searchDistanceTextBox.Attributes.Add("onclick", "updateSearchArea()") _searchDistanceTextBox.Attributes.Add("onchange", "updateSearchArea()") ' Get the map functionality for the primary map resource Dim primaryResourceMapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality = Me.MapInstance.GetFunctionality(MapInstance.PrimaryMapResource) ' Set the task's input units to those of the primary map resource If Me.TaskInput.Units Is Nothing Then Me.TaskInput.Units = primaryResourceMapFunctionality.Units.ToString() End If _unitsDropDownList = New System.Web.UI.WebControls.DropDownList() _unitsDropDownList.ID = "UnitsDropDownList" ' Add all the ArcGIS Server unit types to the units drop-down list except for unknown, points, ' and decimal degress Dim adfUnitArray As System.Array = System.Enum.GetValues(GetType(ESRI.ArcGIS.ADF.Web.DataSources.Units)) Dim selectedIndex As Integer = 0 Dim dropDownIndex As Integer = -1 For Each i As Integer In adfUnitArray Dim unit As String = adfUnitArray.GetValue(i).ToString() If (unit <> "Unknown") AndAlso (unit <> "DecimalDegrees") AndAlso (unit <> "Points") Then _unitsDropDownList.Items.Add(unit) dropDownIndex += 1 End If If unit = Me.TaskInput.Units Then selectedIndex = dropDownIndex End If Next i _unitsDropDownList.SelectedIndex = selectedIndex ' Specify JavaScript functions to call when the drop-down list is clicked and a new item is selected _unitsDropDownList.Attributes.Add("onchange", "updateSearchArea()") End Sub ' Creates the label for the search layer drop-down list Private Function CreateSearchLayerLabel() As System.Web.UI.WebControls.Label Dim label As New System.Web.UI.WebControls.Label() label.ID = "SearchLayerLabel" label.Text = "Search Layer:" label.Style(System.Web.UI.HtmlTextWriterStyle.WhiteSpace) = "nowrap" label.Style(System.Web.UI.HtmlTextWriterStyle.PaddingRight) = "5px" Return label End Function ' Creates and populates the search layer drop-down list Private Sub CreateSearchLayerDropDownList() ' Instantiate the search layer drop-down list _searchLayerDropDownList = New System.Web.UI.WebControls.DropDownList() _searchLayerDropDownList.ID = "SearchLayerDropDownList" ' Wire the JavaScript function updateSearchLayer to the list's onchange event _searchLayerDropDownList.Attributes.Add("onchange", "updateSearchLayer(this);") ' Make sure the search layer hasn't already been initialized before adding layers to the drop-down list If Me.TaskInput.SearchLayer Is Nothing Then ' Dictionaries to hold the names and IDs of queryable layers Dim layerNamesByResourceDictionary As System.Collections.Generic.Dictionary(Of String, String()) Dim layerIDsByResourceDictionary As System.Collections.Generic.Dictionary(Of String, String()) ' Get the names and IDs of all the queryable layers referenced by the buddied map resource manager Me.GetQueryableLayers(MapInstance.MapResourceManagerInstance, layerNamesByResourceDictionary, layerIDsByResourceDictionary) ' Loop through all the items in the layer names dictionary, adding each to the search layer and ' selection layer lists For Each layerNamesPair As System.Collections.Generic.KeyValuePair(Of String, String()) In layerNamesByResourceDictionary ' Get the name of the resource from the current key value pair Dim resourceName As String = layerNamesPair.Key ' Get the array of layer names for the current resource Dim layerNamesArray() As String = layerNamesPair.Value ' Loop through the names, creating a tree view plus node below the current resource node for each For i As Integer = 0 To layerNamesArray.Length - 1 ' Get the layer ID for the current layer Dim layerID As String = layerIDsByResourceDictionary(resourceName)(i) If _searchLayerDropDownList.Items.Count = 0 Then ' Set the layer and resource input parameters based on the current node TaskInput.SearchResource = resourceName TaskInput.SearchLayer = layerID End If ' Create an item for the current layer and add it to the selection layer and search layer ' drop-down lists. Specify the item's text as the layer name, and the item's value as the ' name of the resource containing the layer and the layer ID, delimited by a comma. Dim layerListItem As New System.Web.UI.WebControls.ListItem() layerListItem.Text = layerNamesArray(i) layerListItem.Value = String.Format("{0},{1}", resourceName, layerID) _selectionLayerDropDownList.Items.Add(layerListItem) _searchLayerDropDownList.Items.Add(layerListItem) Next i Next layerNamesPair End If End Sub ' Creates the Find button Private Sub CreateFindButton() ' Instantiate the Find button and specify its text _findButton = New System.Web.UI.HtmlControls.HtmlInputButton() _findButton.ID = "FindButton" _findButton.Value = "Find" ' Construct JavaScript to execute the task Dim executeTaskJavaScript As String = String.Format("" & ControlChars.CrLf & " executeTask('',""{0}"");", Me.CallbackFunctionString, _taskToolbar.ClientID, MapInstance.ClientID) ' Wire the JavaScript to execute when the Find button is clicked _findButton.Attributes.Add("onclick", executeTaskJavaScript) End Sub ' Creates the activity indicator div, which contains the image and label to be shown when the search ' area is being updated Private Sub CreateActivityIndicatorDiv() ' Create a div to hold the activity indicator image and label _activityIndicatorDiv = New System.Web.UI.HtmlControls.HtmlGenericControl("div") _activityIndicatorDiv.ID = "ActivityIndicatorDiv" _activityIndicatorDiv.Style(System.Web.UI.HtmlTextWriterStyle.Display) = "none" ' Create an HTML image control and initialize it with the activity indicator gif Dim activityIndicator As New System.Web.UI.HtmlControls.HtmlImage() Dim activityIndicatorUrl As String = ESRI.ArcGIS.ADF.Web.UI.WebControls.ResourceUtility.GetImage("callbackActivityIndicator.gif", Me, GetType(ESRI.ArcGIS.ADF.Web.UI.WebControls.FloatingPanel), "Runtime") activityIndicator.Src = activityIndicatorUrl activityIndicator.Style(System.Web.UI.HtmlTextWriterStyle.PaddingRight) = "5px" ' Add the image to the div _activityIndicatorDiv.Controls.Add(activityIndicator) ' Create the activity label and add it to the div Dim label As New System.Web.UI.WebControls.Label() label.Font.Bold = False label.ForeColor = System.Drawing.Color.Gray label.Font.Italic = True label.Text = "Updating Search Area..." _activityIndicatorDiv.Controls.Add(label) End Sub #End Region #Region "GeoSpatial Utility Methods" ' Calculates the buffer of the input geometries Private Function BufferGeometries(ByVal adfInputGeometryArray() As ESRI.ArcGIS.ADF.Web.Geometry.Geometry, ByVal bufferDistance As Single, ByVal units As String) As ESRI.ArcGIS.ADF.Web.Geometry.Geometry ' Put the ArcGIS Server SOAP polygon in an ArcGIS Server SOAP geometry array to pass to the ' buffer operation Dim agsSoapInputGeometryArray(adfInputGeometryArray.Length - 1) As ESRI.ArcGIS.ADF.ArcGISServer.Geometry For i As Integer = 0 To adfInputGeometryArray.Length - 1 agsSoapInputGeometryArray(i) = ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.FromAdfGeometry(adfInputGeometryArray(i)) Next i ' Get a reference to an ArcGIS Server Geometry service Dim geometryServerProxy As New ESRI.ArcGIS.ADF.ArcGISServer.GeometryServerProxy(Me.GeometryServiceUrl) ' Get a spatial reference in which to perform the buffer operation. This spatial reference ' is explicitly intialized based on the user-drawn polygon so that there is minimal projection ' related buffer distortion Dim agsSoapBufferSpatialReference As ESRI.ArcGIS.ADF.ArcGISServer.SpatialReference = Me.CreateOperationSpatialReference(agsSoapInputGeometryArray, geometryServerProxy) ' Use the units specified by the user to create an ArcGIS Server LinearUnit object Dim agsSoapBufferUnits As New ESRI.ArcGIS.ADF.ArcGISServer.LinearUnit() agsSoapBufferUnits.WKID = Me.GetWkidByUnitName(units) agsSoapBufferUnits.WKIDSpecified = True ' Get the user-specified buffer distance and put it in an array to pass to the buffer ' operation. If the user did not specify a distance, initialize the distance to zero. Dim bufferDistances(0) As Double bufferDistances(0) = System.Convert.ToDouble(bufferDistance) Dim agsSoapInputSpatialReference As ESRI.ArcGIS.ADF.ArcGISServer.SpatialReference = Me.GetSpatialReference(agsSoapInputGeometryArray(0)) ' Execute the buffer operation via the geometry service Dim agsBufferGeometryArray() As ESRI.ArcGIS.ADF.ArcGISServer.Geometry = geometryServerProxy.Buffer(agsSoapInputSpatialReference, agsSoapBufferSpatialReference, agsSoapInputSpatialReference, bufferDistances, agsSoapBufferUnits, True, agsSoapInputGeometryArray) ' Retrieve the buffer polygon from the array of result geometries Dim adfBufferGeometry As ESRI.ArcGIS.ADF.Web.Geometry.Geometry = ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.ToAdfGeometry(agsBufferGeometryArray(0)) If adfBufferGeometry.SpatialReference Is Nothing Then adfBufferGeometry.SpatialReference = adfInputGeometryArray(0).SpatialReference End If Return adfBufferGeometry End Function ' Returns the well-known ID of the passed-in unit Private Function GetWkidByUnitName(ByVal unitName As String) As Integer Dim wkid As Integer = -1 Select Case unitName Case "Inches" wkid = 109009 Case "Feet" wkid = 9003 Case "Yards" wkid = 109002 Case "Miles" wkid = 9035 Case "NauticalMiles" wkid = 9030 Case "Millimeters" wkid = 109007 Case "Centimeters" wkid = 109006 Case "Meters" wkid = 9001 Case "Kilometers" wkid = 9036 Case "Decimeters" wkid = 109005 Case Else ' default is Kilometers wkid = 9036 End Select Return wkid End Function ' Creates a spatial reference that minimizes distortion in the vicinity of the passed-in geometriess Private Function CreateOperationSpatialReference(ByVal agsSoapGeometryArray() As ESRI.ArcGIS.ADF.ArcGISServer.Geometry, ByVal geometryServerProxy As ESRI.ArcGIS.ADF.ArcGISServer.GeometryServerProxy) As ESRI.ArcGIS.ADF.ArcGISServer.SpatialReference ' Get the polygon's minimum enclosing rectangle (MER) Dim agsSoapBoundingEnvelope As ESRI.ArcGIS.ADF.ArcGISServer.EnvelopeN = GetBoundingExtent(agsSoapGeometryArray) ' If the input polygon's spatial reference uses a projected coordinate system, project the MER to a ' geographic coordinate system (WGS 1984 in this case). We do this because the MER's coordinates ' will be used to initialize the datum of the operation spatial reference Dim agsSoapSpatialReference As ESRI.ArcGIS.ADF.ArcGISServer.SpatialReference = Me.GetSpatialReference(agsSoapGeometryArray(0)) If TypeOf agsSoapSpatialReference Is ESRI.ArcGIS.ADF.ArcGISServer.ProjectedCoordinateSystem Then ' Create an ArcGIS Server spatial reference initalized to use the WGS 1984 coordinate system Dim agsSoapGeographicSpatialReference As ESRI.ArcGIS.ADF.ArcGISServer.SpatialReference = New ESRI.ArcGIS.ADF.ArcGISServer.GeographicCoordinateSystem() agsSoapGeographicSpatialReference.WKID = 4326 agsSoapGeographicSpatialReference.WKIDSpecified = True ' Place the input MER in an array for the project operation Dim agsSoapInputGeometryArray(0) As ESRI.ArcGIS.ADF.ArcGISServer.Geometry agsSoapInputGeometryArray(0) = agsSoapBoundingEnvelope ' Execute the projection Dim agsSoapOutputGeometryArray() As ESRI.ArcGIS.ADF.ArcGISServer.Geometry = geometryServerProxy.Project(agsSoapSpatialReference, agsSoapGeographicSpatialReference, True, Nothing, Nothing, agsSoapInputGeometryArray) ' Retrieve the projected MER from the results array agsSoapBoundingEnvelope = TryCast(agsSoapOutputGeometryArray(0), ESRI.ArcGIS.ADF.ArcGISServer.EnvelopeN) End If ' Get the latitude (Y coordinate) at the center of the MER Dim centerLatitude As Double = agsSoapBoundingEnvelope.YMax - (agsSoapBoundingEnvelope.YMax - agsSoapBoundingEnvelope.YMin) / 2 ' Create the definition string for the operation spatial reference's coordinate system. We will use ' the Hotine Oblique Mercator coordinate system because it lends itself well to minimizing operational ' distortion anywhere on the earth Dim hotineObliqueMercatorDefinition As String = "" & ControlChars.CrLf & " PROJCS[""World_Hotine""," & ControlChars.CrLf & " GEOGCS[""GCS_WGS_1984""," & ControlChars.CrLf & " DATUM[""D_WGS_1984""," & ControlChars.CrLf & " SPHEROID[""WGS_1984"",6378137.0,298.257223563]]," & ControlChars.CrLf & " PRIMEM[""Greenwich"",0.0]," & ControlChars.CrLf & " UNIT[""Degree"",0.0174532925199433]]," & ControlChars.CrLf & " PROJECTION[""Hotine_Oblique_Mercator_Two_Point_Natural_Origin""]," & ControlChars.CrLf & " PARAMETER[""False_Easting"",0.0]," & ControlChars.CrLf & " PARAMETER[""False_Northing"",0.0]," & ControlChars.CrLf & " PARAMETER[""Latitude_Of_1st_Point"",{0}], " & ControlChars.CrLf & " PARAMETER[""Latitude_Of_2nd_Point"",{1}]," & ControlChars.CrLf & " PARAMETER[""Scale_Factor"",1.0]," & ControlChars.CrLf & " PARAMETER[""Longitude_Of_1st_Point"",{2}]," & ControlChars.CrLf & " PARAMETER[""Longitude_Of_2nd_Point"",{3}]," & ControlChars.CrLf & " PARAMETER[""Latitude_Of_Center"",{4}]," & ControlChars.CrLf & " UNIT[""Meter"",1.0]]" ' Specify the relevant coordinates of the MER for the coordinate system's datum parameters Dim customHotineObliqueCylindricalMercator As String = String.Format(hotineObliqueMercatorDefinition, agsSoapBoundingEnvelope.YMin, agsSoapBoundingEnvelope.YMax, agsSoapBoundingEnvelope.XMin, agsSoapBoundingEnvelope.XMax, centerLatitude) ' Create the spatial reference Dim agsSoapBufferSpatialReference As ESRI.ArcGIS.ADF.ArcGISServer.SpatialReference = geometryServerProxy.FindSRByWKT(customHotineObliqueCylindricalMercator, Nothing, True, True) Return agsSoapBufferSpatialReference End Function ' Returns the spatial reference of an ArcGIS Server SOAP Geometry Private Function GetSpatialReference(ByVal agsSoapGeometry As ESRI.ArcGIS.ADF.ArcGISServer.Geometry) As ESRI.ArcGIS.ADF.ArcGISServer.SpatialReference Dim agsSoapSpatialReference As ESRI.ArcGIS.ADF.ArcGISServer.SpatialReference = Nothing If TypeOf agsSoapGeometry Is ESRI.ArcGIS.ADF.ArcGISServer.PolygonN Then Dim agsSoapPolygon As ESRI.ArcGIS.ADF.ArcGISServer.PolygonN = TryCast(agsSoapGeometry, ESRI.ArcGIS.ADF.ArcGISServer.PolygonN) agsSoapSpatialReference = agsSoapPolygon.SpatialReference ElseIf TypeOf agsSoapGeometry Is ESRI.ArcGIS.ADF.ArcGISServer.PolylineN Then Dim agsSoapPolyline As ESRI.ArcGIS.ADF.ArcGISServer.PolylineN = TryCast(agsSoapGeometry, ESRI.ArcGIS.ADF.ArcGISServer.PolylineN) agsSoapSpatialReference = agsSoapPolyline.SpatialReference ElseIf TypeOf agsSoapGeometry Is ESRI.ArcGIS.ADF.ArcGISServer.PointN Then Dim agsSoapPoint As ESRI.ArcGIS.ADF.ArcGISServer.PointN = TryCast(agsSoapGeometry, ESRI.ArcGIS.ADF.ArcGISServer.PointN) agsSoapSpatialReference = agsSoapPoint.SpatialReference End If Return agsSoapSpatialReference End Function ' Gets the bounding extent of the passed-in ArcGIS Server SOAP geometries Private Function GetBoundingExtent(ByVal agsSoapGeometryArray() As ESRI.ArcGIS.ADF.ArcGISServer.Geometry) As ESRI.ArcGIS.ADF.ArcGISServer.EnvelopeN ' Instantiate an envelope with max values minimized and min values maximized Dim agsSoapBoundingBox As New ESRI.ArcGIS.ADF.ArcGISServer.EnvelopeN() agsSoapBoundingBox.XMin = Double.MaxValue agsSoapBoundingBox.XMax = Double.MinValue agsSoapBoundingBox.YMin = Double.MaxValue agsSoapBoundingBox.YMax = Double.MinValue For i As Integer = 0 To agsSoapGeometryArray.Length - 1 Dim agsSoapGeometry As ESRI.ArcGIS.ADF.ArcGISServer.Geometry = agsSoapGeometryArray(i) If TypeOf agsSoapGeometry Is ESRI.ArcGIS.ADF.ArcGISServer.PolygonN Then Dim agsSoapPolygon As ESRI.ArcGIS.ADF.ArcGISServer.PolygonN = TryCast(agsSoapGeometry, ESRI.ArcGIS.ADF.ArcGISServer.PolygonN) ' Iterate through all the polygon's vertices For j As Integer = 0 To agsSoapPolygon.RingArray.Length - 1 Dim agsSoapRing As ESRI.ArcGIS.ADF.ArcGISServer.Ring = agsSoapPolygon.RingArray(j) For k As Integer = 0 To agsSoapRing.PointArray.Length - 1 ' For each vertex, expand the bounds of the minimum enclosing rectangle with the ' vertex's coordinates if they fall outside the rectangle's current bounds Dim agsSoapCurrentPoint As ESRI.ArcGIS.ADF.ArcGISServer.PointN = TryCast(agsSoapRing.PointArray(k), ESRI.ArcGIS.ADF.ArcGISServer.PointN) If agsSoapCurrentPoint.X < agsSoapBoundingBox.XMin Then agsSoapBoundingBox.XMin = agsSoapCurrentPoint.X ElseIf agsSoapCurrentPoint.X > agsSoapBoundingBox.XMax Then agsSoapBoundingBox.XMax = agsSoapCurrentPoint.X End If If agsSoapCurrentPoint.Y < agsSoapBoundingBox.YMin Then agsSoapBoundingBox.YMin = agsSoapCurrentPoint.Y ElseIf agsSoapCurrentPoint.Y > agsSoapBoundingBox.YMax Then agsSoapBoundingBox.YMax = agsSoapCurrentPoint.Y End If Next k Next j ElseIf TypeOf agsSoapGeometry Is ESRI.ArcGIS.ADF.ArcGISServer.PolylineN Then Dim agsSoapPolyline As ESRI.ArcGIS.ADF.ArcGISServer.PolylineN = TryCast(agsSoapGeometry, ESRI.ArcGIS.ADF.ArcGISServer.PolylineN) ' Iterate through all the polyline's vertices For j As Integer = 0 To agsSoapPolyline.PathArray.Length - 1 Dim agsSoapPath As ESRI.ArcGIS.ADF.ArcGISServer.Path = agsSoapPolyline.PathArray(j) For k As Integer = 0 To agsSoapPath.PointArray.Length - 1 ' For each vertex, expand the bounds of the minimum enclosing rectangle with the ' vertex's coordinates if they fall outside the rectangle's current bounds Dim agsSoapCurrentPoint As ESRI.ArcGIS.ADF.ArcGISServer.PointN = TryCast(agsSoapPath.PointArray(k), ESRI.ArcGIS.ADF.ArcGISServer.PointN) If agsSoapCurrentPoint.X < agsSoapBoundingBox.XMin Then agsSoapBoundingBox.XMin = agsSoapCurrentPoint.X ElseIf agsSoapCurrentPoint.X > agsSoapBoundingBox.XMax Then agsSoapBoundingBox.XMax = agsSoapCurrentPoint.X End If If agsSoapCurrentPoint.Y < agsSoapBoundingBox.YMin Then agsSoapBoundingBox.YMin = agsSoapCurrentPoint.Y ElseIf agsSoapCurrentPoint.Y > agsSoapBoundingBox.YMax Then agsSoapBoundingBox.YMax = agsSoapCurrentPoint.Y End If Next k Next j ElseIf TypeOf agsSoapGeometry Is ESRI.ArcGIS.ADF.ArcGISServer.PointN Then Dim agsSoapPoint As ESRI.ArcGIS.ADF.ArcGISServer.PointN = TryCast(agsSoapGeometry, ESRI.ArcGIS.ADF.ArcGISServer.PointN) agsSoapBoundingBox.XMin = agsSoapPoint.X - 0.1 agsSoapBoundingBox.XMax = agsSoapPoint.X + 0.1 agsSoapBoundingBox.YMin = agsSoapPoint.Y - 0.1 agsSoapBoundingBox.YMax = agsSoapPoint.Y + 0.1 End If Next i Return agsSoapBoundingBox End Function #End Region #Region "TaskResultNode Utility Methods" ' Retrieves a GraphicsLayerNode that is an ancestor or descendant of the passed-in node, if available Private Function GetRelatedGraphicsLayerNode(ByVal node As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode) As ESRI.ArcGIS.ADF.Web.UI.WebControls.GraphicsLayerNode ' Check whether the passed-in node is a GraphicsLayerNode Dim graphicsLayerNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.GraphicsLayerNode = TryCast(node, ESRI.ArcGIS.ADF.Web.UI.WebControls.GraphicsLayerNode) ' Check whether the passed-in node has an ancestor GraphicsLayerNode If graphicsLayerNode Is Nothing Then graphicsLayerNode = Me.FindParentGraphicsLayerNode(node) End If ' Check whether the passed-in node has a descendant GraphicsLayerNode If graphicsLayerNode Is Nothing Then graphicsLayerNode = Me.FindChildGraphicsLayerNode(node) End If Return graphicsLayerNode End Function ' Retrieves a GraphicsLayerNode that is a descendant of the passed-in node, if available Private Function FindChildGraphicsLayerNode(ByVal node As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode) As ESRI.ArcGIS.ADF.Web.UI.WebControls.GraphicsLayerNode Dim graphicsLayerNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.GraphicsLayerNode = TryCast(node, ESRI.ArcGIS.ADF.Web.UI.WebControls.GraphicsLayerNode) If graphicsLayerNode Is Nothing AndAlso node.Nodes.Count > 0 Then For Each childNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode In node.Nodes graphicsLayerNode = Me.FindChildGraphicsLayerNode(childNode) If graphicsLayerNode IsNot Nothing Then Exit For End If Next childNode End If Return graphicsLayerNode End Function ' Retrieves a GraphicsLayerNode that is an ancestor of the passed-in node, if available Private Function FindParentGraphicsLayerNode(ByVal node As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode) As ESRI.ArcGIS.ADF.Web.UI.WebControls.GraphicsLayerNode Dim graphicsLayerNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.GraphicsLayerNode = TryCast(node, ESRI.ArcGIS.ADF.Web.UI.WebControls.GraphicsLayerNode) If graphicsLayerNode Is Nothing AndAlso TypeOf node.Parent Is ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode Then graphicsLayerNode = Me.FindParentGraphicsLayerNode(TryCast(node.Parent, ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode)) End If Return graphicsLayerNode End Function ' Retrieves FeatureNodes that are descendants of the passed-in node if available Private Sub FindChildFeatureNodes(ByVal treeViewPlusNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode, ByRef featureNodes As System.Collections.Generic.List(Of ESRI.ArcGIS.ADF.Web.UI.WebControls.FeatureNode)) Dim featureNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.FeatureNode = TryCast(treeViewPlusNode, ESRI.ArcGIS.ADF.Web.UI.WebControls.FeatureNode) If featureNode IsNot Nothing Then featureNodes.Add(featureNode) End If If treeViewPlusNode.Nodes.Count > 0 Then For Each childNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode In treeViewPlusNode.Nodes Me.FindChildFeatureNodes(childNode, featureNodes) Next childNode End If Return End Sub #End Region #Region "Asynchronous Request Utility Methods" ' Retrieves the control that initiated the asynchronous request Private Function GetCallingControl(ByVal page As System.Web.UI.Page) As System.Web.UI.Control If page Is Nothing Then Return Nothing End If If page.IsCallback Then Dim controlID As String = page.Request.Params("__CALLBACKID") Dim control As System.Web.UI.Control = page.FindControl(controlID) Return control ' For 9.3 we could be using a partial postback instead ElseIf page.IsPostBack AndAlso System.Web.UI.ScriptManager.GetCurrent(page) IsNot Nothing AndAlso System.Web.UI.ScriptManager.GetCurrent(page).IsInAsyncPostBack Then Dim controlID As String = System.Web.UI.ScriptManager.GetCurrent(page).AsyncPostBackSourceElementID Dim control As System.Web.UI.Control = page.FindControl(controlID) Return control Else 'Not an asyncronous request Return Nothing End If End Function ' Copies the passed-in callback results to the callback results collection of the control that initiated ' the asynchronous request Private Sub CopyCallbackResultsToCaller(ByVal callbackResults As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection) Dim callingControl As System.Web.UI.Control = Me.GetCallingControl(Me.Page) If TypeOf callingControl Is ESRI.ArcGIS.ADF.Web.UI.WebControls.CompositeControl Then Dim compositeControl As ESRI.ArcGIS.ADF.Web.UI.WebControls.CompositeControl = TryCast(callingControl, ESRI.ArcGIS.ADF.Web.UI.WebControls.CompositeControl) compositeControl.CallbackResults.CopyFrom(callbackResults) ElseIf TypeOf callingControl Is ESRI.ArcGIS.ADF.Web.UI.WebControls.WebControl Then Dim webControl As ESRI.ArcGIS.ADF.Web.UI.WebControls.WebControl = TryCast(callingControl, ESRI.ArcGIS.ADF.Web.UI.WebControls.WebControl) webControl.CallbackResults.CopyFrom(callbackResults) End If End Sub #End Region #End Region End Class End Namespace