Common Partial Postback
Common_PartialPostback_CSharp\RegisterDataItemDemo.aspx.cs
// 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.
// 

public partial class RegisterDataItemDemo : System.Web.UI.Page
{
    #region ASP.NET Page Life Cycle Event Handlers

    protected void Page_Load(object sender, System.EventArgs eventArgs)
    {
        // Register the Zoom To Point button and Zoom To Menu to issue postbacks asynchronously.  Note that
        // controls registered in this way must implement either INamingContainer, IPostBackDataHandler, or 
        // IPostBackEventHandler
        ScriptManager1.RegisterAsyncPostBackControl(Button1);
        ScriptManager1.RegisterAsyncPostBackControl(Menu1);
    }

    protected void Page_PreRender(object sender, System.EventArgs eventArgs)
    {
        string scriptKeyCustom = "customDataItemScript";
        // Check whether a script block with the name stored in scriptKeyCustom has already
        // been registered on the client, and whether the page is in an asynchronous postback.
        // If neither of these is true, create and register the script block.  Note that replacing
        // ScriptManager1.IsInAsyncPostBack with Page.IsPostback will work initially, but if a
        // full page postback occurs, the script may be lost.
        if (!this.Page.ClientScript.IsClientScriptBlockRegistered(GetType(), scriptKeyCustom) &&
        !ScriptManager1.IsInAsyncPostBack)
        {
            // Construct the JavaScript block that will be responsible for processing data items.
            // 
            // onLoadFunction specifies AsyncResponseHandler as a handler for the pageLoading AJAX
            // client-side event.  This event fires during asynchronous postbacks after the response 
            // has been received from the server, but before any content on the page is updated.  
            // 
            // AsyncResponseHandler retrieves the data items thate were registered server-side during 
            // the asynchronous postback by accessing the dataItems property on the second argument 
            // passed to the handler.  It then gets the particular data item corresponding to the 
            // page by passing the page's client ID to the dataItems array as an array index.  This 
            // data item, assumed to be formatted as a Web ADF callback result, is then passed to 
            // ESRI.ADF.System.processCallbackResult - the client-side Web ADF function responsible 
            // for parsing callback results and updating Web ADF controls accordingly.
            //
            // Below the function declarations, onLoadFunction is added as a handler for the AJAX 
            // client-side event init, which is raised one time when the page is first rendered. 
            // This is therefore the appropriate place for onLoadFunction to be called, since the 
            // asynchronous pageLoading handler in this case can remain unchanged for the life
            // of the application.
            //
            // The functions are enclosed in an extra pair of curly braces to allow the subsequent
            // call to String.Format.  String.Format is designed to replace the contents of curly
            // braces with the parameters passed to the function call.  These extra braces "escape" 
            // the braces that must enclose a JavaScript function's logic, essentially telling 
            // String.Format to not replace the contents of these particular braces.
            string scriptBlock = @"
                
                function onLoadFunction(){{
                  Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(AsyncResponseHandler);
                }}

                function AsyncResponseHandler(sender, args) {{
                  var dataItems = args.get_dataItems();
                  if (dataItems['{0}'] != null)
                    ESRI.ADF.System.processCallbackResult(dataItems['{0}']);
                }}

                Sys.Application.add_init(onLoadFunction);";

            // Insert the client ID of the page into the script block.  
            scriptBlock = string.Format(scriptBlock, Page.ClientID);

            // Register the script on the client.  This will make the script block available client-side
            // and execute statements that are not function or object declarations, in this case adding
            // onLoadFunction as a handler for the init event.
            this.Page.ClientScript.RegisterStartupScript(GetType(), scriptKeyCustom, scriptBlock, true);
        }
    }

    #endregion

    #region ASP.NET WebControl Event Handlers

    // Fires when the Zoom To Point button is clicked
    protected void Button1_Click(object sender, System.EventArgs eventArgs)
    {
        // Get the values from the X and Y textboxes
        double xCenter = double.Parse(TextBoxX.Text);
        double yCenter = double.Parse(TextBoxY.Text);

        // Calculate 1/8 the width of the current map extent
        double adfMapWidthEighth = Map1.Extent.Width / 8;

        // Create an envelope with its center at the coordinates specified in the X and Y textboxes,
        // and with a width one quarter that of the current map extent.
        ESRI.ArcGIS.ADF.Web.Geometry.Envelope adfNewExtentEnvelope =
            new ESRI.ArcGIS.ADF.Web.Geometry.Envelope(xCenter - adfMapWidthEighth,
            yCenter - adfMapWidthEighth, xCenter + adfMapWidthEighth, yCenter + adfMapWidthEighth);

        // Update the map extent to the new envelope
        Map1.Extent = adfNewExtentEnvelope;

        // Register the map's callback results as a data item so they are processed on the client
        ScriptManager1.RegisterDataItem(Page, Map1.CallbackResults.ToString(), false);
    }

    // Fires when an item on the Zoom To menu is clicked
    protected void Menu1_MenuItemClick(object sender, System.Web.UI.WebControls.MenuEventArgs menuEventArgs)
    {
        // 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 (menuEventArgs.Item.Text)
        {
            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;

        // Register the map's callback results as a dataItem so that they are processed on the client
        ScriptManager1.RegisterDataItem(Page, Map1.CallbackResults.ToString(), false);
    }

    #endregion

    #region Web ADF Control Event Handlers

    // Fires whenever the map's extent changes
    protected void Map1_ExtentChanged(object sender, ESRI.ArcGIS.ADF.Web.UI.WebControls.ExtentEventArgs extentEventArgs)
    {
        // New extent is the explicit envelope the Map extent will be set to.  Note that the aspect ratio of the map 
        // extent has been adjusted to account for pixel image size / extent size discrepancies. 
        ESRI.ArcGIS.ADF.Web.Geometry.Envelope adfEnvelope = extentEventArgs.NewExtent;

        // Update extent boundary label values.  Note that we have to update the values on both the server (via
        // Label.Text) and the client (via CreateSetInnerContent callback results).  The update on the server
        // makes it so that the value persists across postbacks that don't fire the ExtentChanged event.  The
        // update on the client makes it so that the change is actually shown on the client.

        // Set label text on the server
        LabelN.Text = adfEnvelope.YMax.ToString("N");
        LabelE.Text = adfEnvelope.XMax.ToString("N");
        LabelS.Text = adfEnvelope.YMin.ToString("N");
        LabelW.Text = adfEnvelope.XMin.ToString("N");

        // Update label text on the client via the map control's callback results.  Since the event was fired by the
        // map control, the map's callback results - including any we choose to add - are processed on the client without
        // any further action (such as registering a script block or data item).
        ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult updateLabelCallbackResult =
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateSetInnerContent(LabelN, adfEnvelope.YMax.ToString("N"));
        Map1.CallbackResults.Add(updateLabelCallbackResult);
        updateLabelCallbackResult =
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateSetInnerContent(LabelE, adfEnvelope.XMax.ToString("N"));
        Map1.CallbackResults.Add(updateLabelCallbackResult);
        updateLabelCallbackResult =
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateSetInnerContent(LabelS, adfEnvelope.YMin.ToString("N"));
        Map1.CallbackResults.Add(updateLabelCallbackResult);
        updateLabelCallbackResult =
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateSetInnerContent(LabelW, adfEnvelope.XMin.ToString("N"));
        Map1.CallbackResults.Add(updateLabelCallbackResult);
    }

    #endregion
}