Common Custom tasks
Common_CustomTasks_CSharp\OptimizeTask_CSharp\AsyncOptimizer.cs
// Copyright 2010 ESRI
// 
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
// 
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
// 
// See the use restrictions.
// 

using System;
using System.Collections.Generic;
using System.Text;
using ESRI.ArcGIS.ADF.Web.UI.WebControls;
using System.Collections.Specialized;

public class AsyncOptimizer
{
    CompositeControl task;
    StateManager stateManager;
    public AsyncOptimizer(CompositeControl task)
    {
        this.task = task;
        stateManager = task.StateManager;
    }
    #region Properties
    /// <summary>
    /// Child controls of the task that handle async calls
    /// </summary>
    public List<string> ChildControlsHandlingAsyncCalls
    {
        get
        {
            List<string> list = stateManager.GetProperty("childControlsHandlingAsyncCalls") as List<string>;
            if (list == null)
            {
                list = new List<string>();
                this.ChildControlsHandlingAsyncCalls = list;
            }
            return list;
        }
        set
        {
            stateManager.SetProperty("childControlsHandlingAsyncCalls", value);
        }
    }

    /// <summary>
    /// Names of the map tools on the task (Tool.Name)
    /// </summary>
    public List<string> MapToolsHandlingAsyncCalls
    {
        get
        {
            List<string> list = stateManager.GetProperty("mapToolsHandlingAsyncCalls") as List<string>;
            if (list == null)
            {
                list = new List<string>();
                MapToolsHandlingAsyncCalls = list;
            }
            return list;
        }
        set
        {
            stateManager.SetProperty("mapToolsHandlingAsyncCalls", value);
        }
    }

    /// <summary>
    /// The unique id of the map control associated with this task
    /// </summary>
    public string MapUniqueID
    {
        get 
        {
            string id = stateManager.GetProperty("mapid") as string; 
            if (string.IsNullOrEmpty(id))
            {
                ITask iTask = task as ITask;
                for (int i = 0; i < iTask.TaskResultsContainers.Count; i++)
                {
                    ITaskResultsContainer _taskResults = Utility.FindControl(iTask.TaskResultsContainers[i].Name, task.Page) as ITaskResultsContainer;
                    if (_taskResults != null && _taskResults.MapInstance != null)
                    {
                        id = _taskResults.MapInstance.UniqueID;
                        MapUniqueID = id;
                        break;
                    }
                }
            }
            return id; 
        }
        set { stateManager.SetProperty("mapid", value); }
    }

    /// <summary>
    /// Whether child control creation is required for a page life cycle
    /// </summary>
    public bool RequiresChildControls
    {
        get
        {
            //if not an async call, need to create child controls
            if (!task.IsAsync)
                return true;

            //if this control is handling the async call, create child controls
            string callingControl = GetCallingControlID();
            if (callingControl == task.UniqueID)
                return true;

            //if the child is handling the call, create child controls
            if (ChildControlsHandlingAsyncCalls.Contains(callingControl))
                return true;

            //if the call is handled by a tool on a toolbar on this control, create child controls
            if (callingControl == MapUniqueID) //call to map associated with this task?
            {
                string tool = GetCallingMapTool(MapUniqueID);
                if (tool != null && MapToolsHandlingAsyncCalls.Contains(tool)) //call from tool action from this control's toolbar?
                    return true;
            }
            return false;
        }
    }
    #endregion


    /// <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 static string GetCallingControlID()
    {
        // Get the context of the current request
        System.Web.HttpContext httpContext = System.Web.HttpContext.Current;
        if (httpContext == null) return null;

        // Get the current page from the context
        System.Web.UI.Page page = httpContext.CurrentHandler as System.Web.UI.Page;
        if (page == null) return null;

        // Check whether the request was generated by a callback or partial postback
        if (page.IsCallback)
        {
            // Since the request was issued by a callback, the ID of the calling control
            // will be stored in the __CALLBACKID request parameter
            string controlID = httpContext.Request.Params["__CALLBACKID"];
            return controlID;
        }
        // Check whether the request was generated by a partial postback
        else if (page.IsPostBack && System.Web.UI.ScriptManager.GetCurrent(page) != null &&
            System.Web.UI.ScriptManager.GetCurrent(page).IsInAsyncPostBack)
        {
            // Use ScriptManager.ClientID as argument to retrieve control which initiated partial postback.
            string postValue = 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.              
            int index = postValue.IndexOf('|');
            string controlID = postValue.Substring(index + 1);
            return controlID;
        }
        else return null; // Not an asynchronous request
    }

    /// <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 static System.Web.UI.Control GetCallingControl()
    {
        // Get the context of the current request
        System.Web.HttpContext httpContext = System.Web.HttpContext.Current;
        if (httpContext == null) return null;

        // Get the current page from the context
        System.Web.UI.Page page = httpContext.CurrentHandler as System.Web.UI.Page;
        if (page == null) return null;
        string controlID = GetCallingControlID();

        if (!string.IsNullOrEmpty(controlID))
        {
            System.Web.UI.Control control = page.FindControl(controlID);

            return control;
        }
        else return null; // Not an asynchronous request
    }

    /// <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 static string GetCallingMapTool(string mapUniqueID)
    {
        // Get the context of the current request
        System.Web.HttpContext httpContext = System.Web.HttpContext.Current;
        if (httpContext == null) return null;

        // Get the current page from the context
        System.Web.UI.Page page = httpContext.CurrentHandler as System.Web.UI.Page;
        if (page == null) return null;

        // Check whether the request was generated by a callback or partial postback
        if (page.IsCallback)
        {
            NameValueCollection keyValColl = CallbackUtility.ParseStringIntoNameValueCollection(page.Request.Form["__CALLBACKPARAM"]);
            string mapModeKey = mapUniqueID + "_mode";
            string mapModeVal = keyValColl[mapModeKey];
            return mapModeVal;
        }
        // Check whether the request was generated by a partial postback
        else if (page.IsPostBack && System.Web.UI.ScriptManager.GetCurrent(page) != null &&
            System.Web.UI.ScriptManager.GetCurrent(page).IsInAsyncPostBack)
        {
            NameValueCollection keyValColl = CallbackUtility.ParseStringIntoNameValueCollection(page.Request.Form["__EVENTARGUMENT"]);
            string mapModeKey = mapUniqueID + "_mode";
            string mapModeVal = keyValColl[mapModeKey];
            return mapModeVal;
        }
        return null;
    }

}