Common_CustomTasks_CSharp\OptimizeTask_CSharp\OptimizeTask.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. // namespace OptimizeTask_CSharp { // Specifies the default markup inserted when the task is dragged from the toolbox onto a // page in Visual Studio [System.Web.UI.ToolboxData("<{0}:OptimizeTask_CSharp runat=\"server\" Width=\"100px\" BorderWidth=\"1px\"><TaskResultsContainers><esri:BuddyControl Name=\"TaskResults1\" /></TaskResultsContainers> </{0}:OptimizeTask_CSharp>")] public class OptimizeTask : ESRI.ArcGIS.ADF.Web.UI.WebControls.FloatingPanelTask { #region Instance Variable Declarations private CustomCallbackButton _handleCallbackButton; private System.Web.UI.WebControls.Button _handlePartialPostBackButton; private ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResults _taskResults; private string m_taskTextKey = "textValue"; #endregion #region Instance Properties public string ButtonText { get { // Attempt to retrieve the button text from state object buttonTextObject = StateManager.GetProperty("buttonText"); // If no button text was stored in state, return the default value. Otherwise, // return the text as a string. return (buttonTextObject == null) ? "Execute" : buttonTextObject as string; } set { // Store the passed-in value in state StateManager.SetProperty("buttonText", value); } } // Convenient access to the first TaskResults control in the Task's TaskResultsContainers collection internal ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResults TaskResultsInstance { get { // Retrieve the TaskResults control if it has not already been if ((_taskResults == null) && (this.TaskResultsContainers[0] != null)) _taskResults = ESRI.ArcGIS.ADF.Web.UI.WebControls.Utility.FindControl( this.TaskResultsContainers[0].Name, this.Page) as ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResults; return _taskResults; } } #endregion // Configures the task's interface - NOTE: AsyncOptimizer is used in this method protected override void CreateChildControls() { Controls.Clear(); base.CreateChildControls(); // Determine calling control if an async request. // If not this task or child component within this task, skip creating // child controls. AsyncOptimizer asyncOptimizer = new AsyncOptimizer(this); if (!asyncOptimizer.RequiresChildControls) return; // Clear list of task child controls that make async calls (readd controls if necessary below) asyncOptimizer.ChildControlsHandlingAsyncCalls.Clear(); // If there is no ScriptManager on the page, initialize and add custom callback button to the task. // Otherwise, add a partial postback button. Both controls will initiate an async request that // does not execute the task, but is processed by an event on the control. As a result, // task content must be recreated to process the request. if (this.ScriptManager == null) { #region Custom Callback Button Instantiation // Initialize a custom callback button and add it to the task's controls collection _handleCallbackButton = new CustomCallbackButton(); _handleCallbackButton.ID = "CallbackButton"; _handleCallbackButton.Text = "Handle Callback"; _handleCallbackButton.UseSubmitBehavior = false; _handleCallbackButton.TaskInstance = this; Controls.Add(_handleCallbackButton); #endregion // Register this control with the AsyncOptimizer as a control that may initiate an async request. // If it does, CreateChildControls in this task will execute normally. Note, the list of control ids // is stored in session. asyncOptimizer.ChildControlsHandlingAsyncCalls.Add(_handleCallbackButton.UniqueID); } else { #region Partial PostBack Button Instantiation // Initialize a button that will trigger a partial postback _handlePartialPostBackButton = new System.Web.UI.WebControls.Button(); _handlePartialPostBackButton.ID = "partialPostBackButton"; _handlePartialPostBackButton.Text = "Handle Partial PostBack"; //_handlePartialPostBackButton.UseSubmitBehavior = false; // Wire a handler for the button's click event _handlePartialPostBackButton.Click += new System.EventHandler(HandlePartialPostBackButton_Click); // Regiester the button as an asyncrhonous postback control so it triggers a partial postback // when clicked ScriptManager.RegisterAsyncPostBackControl(_handlePartialPostBackButton); // Add the button to the task's controls collection Controls.Add(_handlePartialPostBackButton); #endregion // Register this control with the AsyncOptimizer as a control that may initiate an async request. // If it does, CreateChildControls in this task will execute normally. Note, the list of control ids // is stored in session. asyncOptimizer.ChildControlsHandlingAsyncCalls.Add(_handlePartialPostBackButton.UniqueID); } #region Textbox containing value to pass during task execution // Create a textbox and add it to the task's controls collection System.Web.UI.WebControls.TextBox textBox = new System.Web.UI.WebControls.TextBox(); textBox.ID = "PostBackTaskTextBox"; Controls.Add(textBox); // Define an argument to return when executing the task string customArguments = string.Format("'{0}=' + ESRI.ADF.System.escapeForCallback($get('{1}').value)", m_taskTextKey,textBox.ClientID); #endregion #region Button Initiating Task Execution via Web ADF Task Framework // Create a button for task execution System.Web.UI.WebControls.Button executeTaskButton = new System.Web.UI.WebControls.Button(); executeTaskButton.Text = "Execute Task"; // Construct JavaScript that calls the Web ADF's executeTask function. This will initiate // a callback that invokes the task's ExecuteTask method on the server. string executeTaskJavaScript = string.Format("ESRI.ADF.Tasks.executeTask({0}, \"{1}\");return false;", customArguments, CallbackFunctionString); // Wire the JavaScript to execute when the button is clicked executeTaskButton.OnClientClick = executeTaskJavaScript; // Add the button to the task's controls colleciton Controls.Add(executeTaskButton); #endregion } protected override void OnPreRender(System.EventArgs e) { base.OnPreRender(e); #region Partial PostBack Response Handling // Create the JavaScript necessary to pass the result of a partial postback to the Web ADF // JavaScript library's processCallbackResult function string scriptKeyCustom = "customDataItemScript"; if (!this.Page.ClientScript.IsStartupScriptRegistered(GetType(), scriptKeyCustom) && this.ScriptManager != null) { string processDataItemJavaScript = @" 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);"; processDataItemJavaScript = string.Format(processDataItemJavaScript, this.Page.ClientID); // Register the script as a startup script so the result handling code is wired during // applicaton initialization this.Page.ClientScript.RegisterStartupScript(GetType(), scriptKeyCustom, processDataItemJavaScript, true); } #endregion } #region Task Overrides // Fires first when the task is executed. Retrieves the values needed to perform the necessary // server-side action. public override string GetCallbackResult() { // Set the task's Input member to the value of the task's textbox System.Collections.Specialized.NameValueCollection keyValColl = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection( CallbackEventArgument); Input = keyValColl[m_taskTextKey]; return base.GetCallbackResult(); } // Fires second when the task is executed. Performs the necessary server-side logic. public override void ExecuteTask() { // Clear any left-over task results and make sure task input exists Results = null; if (Input == null) return; // Get the task's textbox value from the Input property string textBoxValue = Input as string; // Format the heading of the task result to display the current time on the server string taskResultHeading = string.Format("The time on the server is {0}", System.DateTime.Now.ToShortTimeString()); // Format the detail of the task result to display the value of the task's textbox when // the task was executed string taskResultDetail = string.Format("The value in the text box is: {0}", textBoxValue); // Create a simple task result with the heading and detail ESRI.ArcGIS.ADF.Web.UI.WebControls.SimpleTaskResult simpleTaskResult = new ESRI.ArcGIS.ADF.Web.UI.WebControls.SimpleTaskResult(taskResultHeading, taskResultDetail); // Set the task's Results property to the simple task result. The contents of this property // will be passed to the task's results container. Results = simpleTaskResult; } // Overriden to return an empty list, indicating that the task has no resource dependencies. public override System.Collections.Generic.List< ESRI.ArcGIS.ADF.Web.UI.WebControls.GISResourceItemDependency> GetGISResourceItemDependencies() { System.Collections.Generic.List<ESRI.ArcGIS.ADF.Web.UI.WebControls.GISResourceItemDependency> list = new System.Collections.Generic.List< ESRI.ArcGIS.ADF.Web.UI.WebControls.GISResourceItemDependency>(); return list; } #endregion #region UI Event Handlers - HandlePartialPostBackButton_Click // Fires when the Handle Partial PostBack button is clicked void HandlePartialPostBackButton_Click(object sender, System.EventArgs e) { // Zoom the map if (TaskResultsInstance.MapInstance != null) TaskResultsInstance.MapInstance.Zoom(2); // Copy the map's callback results to the task results container's callback results collection TaskResultsInstance.CallbackResults.CopyFrom(TaskResultsInstance.MapInstance.CallbackResults); // Register the task results container's callback results as a data item. This will pass the // callback results to the client-side AsyncResponseHandler function that was registered in // OnPreRender. This function, in turn, will pass the callback results to the Web ADF's // processCallbackResults function. this.ScriptManager.RegisterDataItem(Page, TaskResultsInstance.CallbackResults.ToString(), false); } #endregion } public class CustomCallbackButton : System.Web.UI.WebControls.Button, System.Web.UI.ICallbackEventHandler { #region Instance Variable Declarations private string _callbackArg; private OptimizeTask _task; #endregion protected override void OnPreRender(System.EventArgs e) { base.OnPreRender(e); #region Custom Callback Button Click Handling // Get the JavaScript syntax for invoking a callback to the callback button string callbackInvocationString = Page.ClientScript.GetCallbackEventReference( this, "argument", "processCallbackResult", "context"); // Construct JavaScript to create an argument string containing the browser's dimensions // and execute a callback to pass the argument to the server. string callbackJavaScript = @" var argument = 'callbackArgument=ZoomMap'; var context = null; {0}; return; "; // Substitute the callback invocation into the callback packaging JavaScript callbackJavaScript = string.Format(callbackJavaScript, callbackInvocationString); // Wire the script to the callback button's click event OnClientClick = callbackJavaScript; #endregion } #region ICallbackEventHandler Members - RaiseCallbackEvent, GetCallbackResult // The first method to execute on the server when a callback is invoked from the client. The string // containing the callback's parameters is passed to this method. public void RaiseCallbackEvent(string eventArgument) { // Store the callback argument string in an instance variable for reference in GetCallbackResult _callbackArg = eventArgument; } // Fires when a callback string referencing a CustomCallbackButton instance is invoked from the client. // In the PostBackTask implementation above, the JavaScript needed to do that is wired to a // CustomCallbackButton instance in the OnPreRender method. public string GetCallbackResult() { // Use the Web ADF's callback parsing utility to split the callback argument string into a // collection of name-value pairs. System.Collections.Specialized.NameValueCollection callbackArgsCollection = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection( _callbackArg); // Get the callback argument from the collection string callbackArguments = callbackArgsCollection["callbackArgument"]; if (!string.IsNullOrEmpty(callbackArguments)) { if (callbackArguments == "ZoomMap") { // Zoom the map buddied to the callback button's parent PostBackTask if (this.TaskInstance.TaskResultsInstance.MapInstance != null) this.TaskInstance.TaskResultsInstance.MapInstance.Zoom(2); // Copy the map's callback results to the task results container's results collection this.TaskInstance.TaskResultsInstance.CallbackResults.CopyFrom( this.TaskInstance.TaskResultsInstance.MapInstance.CallbackResults); } } return TaskInstance.TaskResultsInstance.CallbackResults.ToString(); } #endregion #region Instance Properties - PostBackTaskInstance // Provides access to the parent task internal OptimizeTask TaskInstance { get { return _task; } set { _task = value; } } #endregion } }