Common_PartialPostback_CSharp\AJAXDemo.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 AJAXDemo : System.Web.UI.Page { #region Instance Variable Declarations // Variables defining what resource, layer, and field name to use for the drop-down list and listbox private string m_queryResourceItemName = "MapResourceItem0"; private string m_queryLayerName = "States"; private string m_queryFieldName = "STATE_NAME"; #endregion #region ASP.NET Page Life Cycle Event Handlers protected void Page_PreRender(object sender, System.EventArgs e) { 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 protected void DropDownList1_SelectedIndexChanged(object sender, System.EventArgs eventArgs) { ZoomToFeatureByValue(DropDownList1.SelectedValue); } protected void ListBox1_SelectedIndexChanged(object sender, System.EventArgs eventArgs) { ZoomToFeatureByValue(ListBox1.SelectedValue); } #endregion #region Web ADF Control Event Handlers protected void Map1_ExtentChanged(object sender, ESRI.ArcGIS.ADF.Web.UI.WebControls.ExtentEventArgs args) { // 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 = args.NewExtent; // Get the map resource to query ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisResource = Map1.GetFunctionality(m_queryResourceItemName).Resource; // Create a Common Data Source API query functionality from the resource ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality commonQueryFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisResource.CreateFunctionality (typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null); // Get arrays containing the layer IDs and names of the resource's queryable layers string[] layerIDs = null; string[] layerNames = null; commonQueryFunctionality.GetQueryableLayers(null, out layerIDs, out layerNames); // Create a Web ADF spatial filter with the new map extent as the filter geometry ESRI.ArcGIS.ADF.Web.SpatialFilter adfSpatialFilter = new ESRI.ArcGIS.ADF.Web.SpatialFilter(); adfSpatialFilter.ReturnADFGeometries = false; adfSpatialFilter.Geometry = adfEnvelope; // Loop through the layer names array until the query layer name is found. When found, use the layer // ID at the current index to execute a query on the resource System.Data.DataTable queryResultsDataTable = null; for (int i = 0; i < layerNames.Length; i++) { if (layerNames[i] == m_queryLayerName) { queryResultsDataTable = commonQueryFunctionality.Query(commonQueryFunctionality.Name, layerIDs[i], adfSpatialFilter); break; } } // Populate an ArrayList with the value of the query field for each row in the query results System.Collections.ArrayList arrayList = new System.Collections.ArrayList(); foreach (System.Data.DataRow dataRow in queryResultsDataTable.Rows) { string dataRowValue = dataRow[m_queryFieldName].ToString(); arrayList.Add(dataRowValue); } arrayList.Sort(); ListBox1.Items.Clear(); foreach (string item in arrayList) { // If the ScriptManager is not in an asynchronous postback, then the page is in initial load. // We therefore add the current item to DropDownList1 since it has not yet been populated. // Otherwise, we skip this step and clear ListBox1 since that control will be re-populated with // the query results (i.e. features that intersect the new extent) if (!ScriptManager1.IsInAsyncPostBack) DropDownList1.Items.Add(item); // Add the current item to the listbox ListBox1.Items.Add(item); } } #endregion #region Instance Methods private void ZoomToFeatureByValue(string value) { // Get the resource to be queried and use it to create a Web ADF Common Data Source API // query functionality ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisResource = Map1.GetFunctionality(m_queryResourceItemName).Resource; ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality commonQueryFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisResource.CreateFunctionality (typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null); // Get arrays containing the names and IDs of the resource's queryable layers string[] layerIDs = null; string[] layerNames = null; commonQueryFunctionality.GetQueryableLayers(null, out layerIDs, out layerNames); // Create a Web ADF query filter with a where clause that will select features according // to the class-level field name variable and the passed-in value. Note that the code here // assumes the field has a string data type. ESRI.ArcGIS.ADF.Web.QueryFilter adfQueryFilter = new ESRI.ArcGIS.ADF.Web.QueryFilter(); adfQueryFilter.ReturnADFGeometries = true; adfQueryFilter.WhereClause = string.Format("{0} = '{1}'", m_queryFieldName, value); // Loop through the layer names array until the query layer name is found. When found, use // the layer ID at the current index to execute a query on the resource. System.Data.DataTable queryResultsDataTable = null; for (int i = 0; i < layerNames.Length; i++) { if (layerNames[i] == m_queryLayerName) { queryResultsDataTable = commonQueryFunctionality.Query(commonQueryFunctionality.Name, layerIDs[i], adfQueryFilter); break; } } if (queryResultsDataTable != null) { // Get the results as a Web ADF GraphicsLayer ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer adfGraphicsLayer = queryResultsDataTable as ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer; // Get the envelope of the geometry of the first row in the data table and use it to set // the map extent. Note that this code assumes we always want to zoom to the first row // in the table. ESRI.ArcGIS.ADF.Web.Geometry.Geometry adfGeometry = adfGraphicsLayer.GeometryFromRow(adfGraphicsLayer.Rows[0]); ESRI.ArcGIS.ADF.Web.Geometry.Envelope adfEnvelope = ESRI.ArcGIS.ADF.Web.Geometry.Geometry.GetMinimumEnclosingEnvelope(adfGeometry).Expand(10); Map1.Extent = adfEnvelope; // Register the Map's callback results as a data item so they are processed on the client ScriptManager1.RegisterDataItem(Page, Map1.CallbackResults.ToString(), false); } } #endregion }