Common_CustomTasks_VBNet\OptimizeTask_VBNet\AsyncOptimizer.vb
' Copyright 2011 ESRI ' ' All rights reserved under the copyright laws of the United States ' and applicable international laws, treaties, and conventions. ' ' You may freely redistribute and use this sample code, with or ' without modification, provided you include the original copyright ' notice and use restrictions. ' ' See the use restrictions. ' Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Text Imports ESRI.ArcGIS.ADF.Web.UI.WebControls Imports System.Collections.Specialized Public Class AsyncOptimizer Private task As CompositeControl Private stateManager As StateManager Public Sub New(ByVal task As CompositeControl) Me.task = task stateManager = task.StateManager End Sub #Region "Properties" ''' <summary> ''' Child controls of the task that handle async calls ''' </summary> Public Property ChildControlsHandlingAsyncCalls() As List(Of String) Get Dim list As List(Of String) = TryCast(stateManager.GetProperty("childControlsHandlingAsyncCalls"), List(Of String)) If list Is Nothing Then list = New List(Of String)() Me.ChildControlsHandlingAsyncCalls = list End If Return list End Get Set stateManager.SetProperty("childControlsHandlingAsyncCalls", Value) End Set End Property ''' <summary> ''' Names of the map tools on the task (Tool.Name) ''' </summary> Public Property MapToolsHandlingAsyncCalls() As List(Of String) Get Dim list As List(Of String) = TryCast(stateManager.GetProperty("mapToolsHandlingAsyncCalls"), List(Of String)) If list Is Nothing Then list = New List(Of String)() MapToolsHandlingAsyncCalls = list End If Return list End Get Set stateManager.SetProperty("mapToolsHandlingAsyncCalls", Value) End Set End Property ''' <summary> ''' The unique id of the map control associated with this task ''' </summary> Public Property MapUniqueID() As String Get Dim id As String = TryCast(stateManager.GetProperty("mapid"), String) If String.IsNullOrEmpty(id) Then Dim iTask As ITask = TryCast(task, ITask) Dim i As Integer = 0 Do While i < iTask.TaskResultsContainers.Count Dim _taskResults As ITaskResultsContainer = TryCast(Utility.FindControl(iTask.TaskResultsContainers(i).Name, task.Page), ITaskResultsContainer) If Not _taskResults Is Nothing AndAlso Not _taskResults.MapInstance Is Nothing Then id = _taskResults.MapInstance.UniqueID MapUniqueID = id Exit Do End If i += 1 Loop End If Return id End Get Set stateManager.SetProperty("mapid", Value) End Set End Property ''' <summary> ''' Whether child control creation is required for a page life cycle ''' </summary> Public ReadOnly Property RequiresChildControls() As Boolean Get 'if not an async call, need to create child controls If (Not task.IsAsync) Then Return True End If 'if this control is handling the async call, create child controls Dim callingControl As String = GetCallingControlID() If callingControl = task.UniqueID Then Return True End If 'if the child is handling the call, create child controls If ChildControlsHandlingAsyncCalls.Contains(callingControl) Then Return True End If 'if the call is handled by a tool on a toolbar on this control, create child controls If callingControl = MapUniqueID Then 'call to map associated with this task? Dim tool As String = GetCallingMapTool(MapUniqueID) If Not tool Is Nothing AndAlso MapToolsHandlingAsyncCalls.Contains(tool) Then 'call from tool action from this control's toolbar? Return True End If End If Return False End Get End Property #End Region ''' <summary> ''' Gets the Unique ID of the control that created the asynchronous call. ''' </summary> ''' <returns>Unique ID of the control that initiated the asynchronous call, ''' or null if not asynchronous or not found.</returns> Public Shared Function GetCallingControlID() As String ' Get the context of the current request Dim httpContext As System.Web.HttpContext = System.Web.HttpContext.Current If httpContext Is Nothing Then Return Nothing End If ' Get the current page from the context Dim page As System.Web.UI.Page = TryCast(httpContext.CurrentHandler, System.Web.UI.Page) If page Is Nothing Then Return Nothing End If ' Check whether the request was generated by a callback or partial postback If page.IsCallback Then ' Since the request was issued by a callback, the ID of the calling control ' will be stored in the __CALLBACKID request parameter Dim controlID As String = httpContext.Request.Params("__CALLBACKID") Return controlID ' Check whether the request was generated by a partial postback ElseIf page.IsPostBack AndAlso Not System.Web.UI.ScriptManager.GetCurrent(page) Is Nothing AndAlso System.Web.UI.ScriptManager.GetCurrent(page).IsInAsyncPostBack Then ' Use ScriptManager.ClientID as argument to retrieve control which initiated partial postback. Dim postValue As String = httpContext.Request(System.Web.UI.ScriptManager.GetCurrent(page).ClientID) ' Use the vertical bar in the argument value to divide items. The item before the bar is the ClientID of either the ScriptManager ' or an UpdatePanel (depending on how the async control is registered). The UniqueID of the control that initiated the async ' request (partial postback) is located after the bar. Dim index As Integer = postValue.IndexOf("|"c) Dim controlID As String = postValue.Substring(index + 1) Return controlID Else ' Not an asynchronous request Return Nothing End If End Function ''' <summary> ''' Gets the control that created the asynchronous call. ''' </summary> ''' <returns>Control that initiated the asynchronous call, ''' or null if not asynchronous or not found.</returns> Public Shared Function GetCallingControl() As System.Web.UI.Control ' Get the context of the current request Dim httpContext As System.Web.HttpContext = System.Web.HttpContext.Current If httpContext Is Nothing Then Return Nothing End If ' Get the current page from the context Dim page As System.Web.UI.Page = TryCast(httpContext.CurrentHandler, System.Web.UI.Page) If page Is Nothing Then Return Nothing End If Dim controlID As String = GetCallingControlID() If (Not String.IsNullOrEmpty(controlID)) Then Dim control As System.Web.UI.Control = page.FindControl(controlID) Return control Else ' Not an asynchronous request Return Nothing End If End Function ''' <summary> ''' Gets the name of the map tool that created the asynchronous call. ''' </summary> ''' <param name="mapUniqueID">The unique id of the map control</param> ''' <returns>The name of the tool</returns> Public Shared Function GetCallingMapTool(ByVal mapUniqueID As String) As String ' Get the context of the current request Dim httpContext As System.Web.HttpContext = System.Web.HttpContext.Current If httpContext Is Nothing Then Return Nothing End If ' Get the current page from the context Dim page As System.Web.UI.Page = TryCast(httpContext.CurrentHandler, System.Web.UI.Page) If page Is Nothing Then Return Nothing End If ' Check whether the request was generated by a callback or partial postback If page.IsCallback Then Dim keyValColl As NameValueCollection = CallbackUtility.ParseStringIntoNameValueCollection(page.Request.Form("__CALLBACKPARAM")) Dim mapModeKey As String = mapUniqueID & "_mode" Dim mapModeVal As String = keyValColl(mapModeKey) Return mapModeVal ' Check whether the request was generated by a partial postback ElseIf page.IsPostBack AndAlso Not System.Web.UI.ScriptManager.GetCurrent(page) Is Nothing AndAlso System.Web.UI.ScriptManager.GetCurrent(page).IsInAsyncPostBack Then Dim keyValColl As NameValueCollection = CallbackUtility.ParseStringIntoNameValueCollection(page.Request.Form("__EVENTARGUMENT")) Dim mapModeKey As String = mapUniqueID & "_mode" Dim mapModeVal As String = keyValColl(mapModeKey) Return mapModeVal End If Return Nothing End Function End Class