Common Callback
Common_Callback_CSharp\Default.aspx.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.
// 


public partial class Default : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
{
    #region Instance Variable Declarations

    private string m_ADFCallbackFunctionString;
    private string m_CallbackResults;

    #endregion

    #region ASP.NET Page Event Handlers

    protected void Page_Load(object sender, System.EventArgs e)
    {
        // Define the parameters for a browser call to the WebForm_DoCallback JavaScript function
        // via the GetCallbackEventReference function.  The GetCallbackEventReference function returns 
        // the syntax for initiating a callback (i.e a call to WebForm_DoCallback) with the passed-in 
        // parameters.  Here the parameters are defined as follows:
        // this - the Page will handle the callback request
        // "message" - a JavaScript variable named "message" will contain argument value pairs in 
        //             the callback
        // "processCallbackResult" - name of the JavaScript function to process the callback 
        //                           response from the Page.  This function is included with 
        //                           the Web ADF JavaScript Library.
        // "context" - a JavaScript variable named "context" which can be used by the browser to
        //             indicate the origin of the callback
        // "postBackError" - name of the JavaScript function to process errors returned during 
        //                   callback processing.
        // true - define whether the callback is synchronous or asynchronous.  True is asynchronous.        
        m_ADFCallbackFunctionString = Page.ClientScript.GetCallbackEventReference(this, "message", 
            "processCallbackResult", "context", "postBackError", true);
    }

    #endregion

    #region Web ADF Control Event Handlers

    // Event that fires when the map extent changes.  Wired to the map in the map control's HTML declaration
    protected void Map1_ExtentChanged(object sender, 
        ESRI.ArcGIS.ADF.Web.UI.WebControls.ExtentEventArgs extentEventArgs)
    {
        try
        {
            // Get the new extent of the map (extent after the extent changed) and store in a Web ADF envelope
            ESRI.ArcGIS.ADF.Web.Geometry.Envelope adfEnvelope = extentEventArgs.NewExtent;

            // Create a SortedList object containing four key-value pairs, each containing one bound of the
            // new extent and the id of the HTML div that will be updated to display that bound.  "N" is
            // passed to double.ToString to specify a numeric format in converting the coordinate.
            System.Collections.Generic.SortedList<string, string> extentList =
                new System.Collections.Generic.SortedList<string, string>();
            extentList.Add("LabelN", adfEnvelope.YMax.ToString("N"));
            extentList.Add("LabelE", adfEnvelope.XMax.ToString("N"));
            extentList.Add("LabelS", adfEnvelope.YMin.ToString("N"));
            extentList.Add("LabelW", adfEnvelope.XMin.ToString("N"));

            // Iterate through each pair in the list and create a callback result to update the extent divs
            foreach (System.Collections.Generic.KeyValuePair<string, string> keyValuePair in extentList)
            {
                // Get the extent bound coordinate of the current list item
                string extentBound = keyValuePair.Value.ToString();
                // Get the div ID that should be updated with extentBound from the current list item
                string extentDivId = keyValuePair.Key.ToString();

                // Create a callback result that will update the div specified by extentDivId with the
                // value specified by extentBound.  To do this, we pass the CallbackResult constructor the
                // following parameters:
                // "div" - the type of control/element we want updated
                // extentDivId - the client-side ID of the control/element we want updated
                // "innercontent" - the type of action we want to be performed.  "innercontent" specifies that
                //      we want to replace the inner HTML (what's inside the element tags) of the specified 
                //      control/element
                // extentBound - the value to use in the specified action.  In this case, it is the value
                //      to replace the div's inner HTML with.
                ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult callbackResult =
                    ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateSetInnerContent(extentDivId, 
                    extentBound);

                // Add the callback result to the map.  Since the map control initiated the callback when
                // its extent changed, it is the map control's callback results that will be processed when
                // the callback returns to the client.
                Map1.CallbackResults.Add(callbackResult);
            }
        }
        catch (System.Exception exception)
        {
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult =
                ErrorHandling.GetErrorCallback(exception);
            Map1.CallbackResults.Add(errorCallbackResult);
        }
    }

    #endregion

    #region ICallbackEventHandler Members

    // The Zoom To Point button is wired to invoke the JavaScript function ZoomToPointClient
    // (defined in Default.aspx), which in turn invokes the JavaScript callback function.  So when
    // the button is clicked, a callback is initiated, causing RaiseCallbackEvent and
    // GetCallbackResult to be called.  
    //
    // The items on the Zoom To Location menu are wired similarly, as on click they call the JavaScript 
    // function ZoomToLocationClient (also defined in Default.aspx), which also in turn calls the 
    // JavaScript callback.
    //
    // We therefore add code to RaiseCallbackEvent and GetCallbackResult to parse the arguments
    // passed in the callbacks, take action accordingly, and return a callback response to the client.
    public void RaiseCallbackEvent(string eventArgs)
    {
        try
        {
            // Parse the callback string passed from the client to the server into separate
            // arguments using the Web ADF's callback parsing utility.
            System.Collections.Specialized.NameValueCollection nameValueCollection =
                ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(eventArgs);

            // Check the value of the main event argument (EventArg) and take action accordingly
            if (nameValueCollection["EventArg"] == "ZoomToPoint")
            {
                // Call the method that will center the map at the passed-in coordinates and zoom by a factor
                // of four.
                ZoomToPointServer(nameValueCollection["X"], nameValueCollection["Y"]);
            }
            else if (nameValueCollection["EventArg"] == "ZoomToLocation")
            {
                // Call the method that will zoom the map to the passed-in location
                ZoomToLocationServer(nameValueCollection["Location"]);
            }
        }
        catch (System.Exception exception)
        {
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult =
                ErrorHandling.GetErrorCallback(exception);
            Map1.CallbackResults.Add(errorCallbackResult);
            m_CallbackResults = Map1.CallbackResults.ToString();
        }
    }

    // The last server-side method called before the callback returns to the browser, GetCallbackResult
    // is where the server-side result of the callback is passed back to the browser as a string for
    // processing by the client.
    public string GetCallbackResult()
    {
        // Return the instance variable containing the callback results
        return m_CallbackResults;
    }

    #endregion

    #region Instance Properties

    // Property allowing client-side access to the client callback function string.  This string
    // contains the necessary JavaScript syntax to initiate a callback with the parameters specified
    // in GetCallbackEventReference (in Page_Load).
    public string ADFCallbackFunctionString
    {
        get
        {
            return m_ADFCallbackFunctionString;
        }
        set
        {
            m_ADFCallbackFunctionString = value;
        }
    }

    #endregion

    #region Instance Methods

    // Method that centers the map at the passed-in coordinates and zooms by a factor of 4
    public void ZoomToPointServer(string xString, string yString)
    {
        try
        {
            // Convert the passed-in coordinates from strings to doubles
            double xCenter = double.Parse(xString);
            double yCenter = double.Parse(yString);

            // Create a Web ADF point from the passed-in coordinates
            ESRI.ArcGIS.ADF.Web.Geometry.Point adfCenterPoint =
                new ESRI.ArcGIS.ADF.Web.Geometry.Point(xCenter, yCenter);

            // Center the map at the point
            Map1.CenterAt(adfCenterPoint);

            // Zoom the map by a factor of 4
            Map1.Zoom(4);
        }
        catch (System.Exception exception)
        {
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult =
                ErrorHandling.GetErrorCallback(exception);
            Map1.CallbackResults.Add(errorCallbackResult);
        }

        // Update the instance variable storing callback results with the callback results of the
        // map control.  Since we've manipulated the map, its callback results must be returned
        // to the client for our changes to show up.  And since it was not the map control that
        // intitiated the callback, but rather a custom JavaScript function, the map control is
        // not checked for callback results when the callback returns to the client.
        m_CallbackResults = Map1.CallbackResults.ToString();
    }

    // Method that zooms the map to the passed-in location
    public void ZoomToLocationServer(string location)
    {
        try
        {
            // Declare and initialze a variable to store whether the passed-in location is
            // one listed on the Zoom To Location menu
            bool validLocation = false;

            // Get the root menu item of the Zoom To Menu
            System.Web.UI.WebControls.MenuItem rootMenuItem = Menu1.Items[0];

            // Iterate through the items directly below the root item
            foreach (System.Web.UI.WebControls.MenuItem menuItem in rootMenuItem.ChildItems)
            {
                // Check whether the current menu item's text matches the passed-in location
                if (menuItem.Text == location)
                {
                    // the text matches the location, meaning the location is valid
                    validLocation = true;
                    break;
                }
            }

            if (validLocation)
            {
                // Declare and initialize variables to store the bounds of the new map extent
                double minX = 0;
                double minY = 0;
                double maxX = 0;
                double maxY = 0;

                // Check the passed-in location and initialize the extent parameters accordingly
                switch (location)
                {
                    case "California":
                        minX = -128.0;
                        minY = 31.0;
                        maxX = -111.0;
                        maxY = 43.0;
                        break;
                    case "New York":
                        minX = -80.0;
                        minY = 40.5;
                        maxX = -73.0;
                        maxY = 45.5;
                        break;
                    case "Kansas":
                        minX = -103.0;
                        minY = 35.0;
                        maxX = -93.0;
                        maxY = 42.0;
                        break;
                    default:
                        break;
                }
                // Create a Web ADF envelope with the new extent parameters
                ESRI.ArcGIS.ADF.Web.Geometry.Envelope adfNewExtentEnvelope =
                    new ESRI.ArcGIS.ADF.Web.Geometry.Envelope(minX, minY, maxX, maxY);

                // Update the map control's extent with the newly created envelope
                Map1.Extent = adfNewExtentEnvelope;

                // Update the instance variable storing callback results with the callback results of the
                // map control.  Since we've manipulated the map, its callback results must be returned
                // to the client for our changes to show up.  And since it was not the map control that
                // intitiated the callback, but rather a custom JavaScript function, the map control is
                // not checked for callback results when the callback returns to the client.
                m_CallbackResults = Map1.CallbackResults.ToString();
            }
            else
            {
                // The location was not valid, so we don't need to pass any callback results to the client
                m_CallbackResults = "";
            }
        }
        catch (System.Exception exception)
        {
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult =
                ErrorHandling.GetErrorCallback(exception);
            Map1.CallbackResults.Add(errorCallbackResult);
            m_CallbackResults = Map1.CallbackResults.ToString();
        }
    }

    #endregion

}