How to add custom tool and manage callbackresults from other Web ADF Controls


Summary This topic describes how to add custom tool to the toolbar and how Web ADF manages those callback results. The topic also explains how changes to other Web ADF controls can be packaged with the callback results of other the web ADF control.

In this topic

Adding a custom toolbar item to a toolbar control
Under the hood
Managing callbackResults from other Web ADF controls

Adding a custom toolbar item to a toolbar control

To create a custom tool, perform the following steps:
  1. Create a Web application using How to create a Web application with Web controls as a guide.
  2. In Solution Explorer, right-click the Web project and select Add New Item. The Add New Item dialog box opens.
  3. Under the Visual Studio Installed Templates section, select Class, set the class file name to CustomTool.cs, and ensure the language is Visual C#. Visual Studio prompts you to create an App_Code folder and place the new class file inside.
  4. Click Yes. The CustomTool.cs file opens so you can add content.
  5. At the top of the CustomTool.cs file, add the statements shown in the following code:
[C#]
using ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools;
using ESRI.ArcGIS.ADF.Web.UI.WebControls;
  1. Remove the CustomTool constructor and implement the IMapServerToolAction interface on the CustomTool class. Add a ServerAction method to explicitly implement the interface. The code for the class is as follows:
[C#]
public class CustomTool: IMapServerToolAction
{
    public void ServerAction(ToolEventArgs args){}
}
  1. In the ServerAction method, get a reference to the Map control from the ToolEventArgs.Control property as shown in the following code:
[C#]
Map map = (Map)args.Control;
  1. Since the ClientAction for the tool will be set to Point, cast the ToolEventArgs to PointEventArgs as shown in the following code:
[C#]
PointEventArgs pargs = (PointEventArgs)args;
  1. Call the CenterAt method on the Map object and provide the screen point as shown in the following code: 
[C#]
map.CenterAt(pargs.ScreenPoint);
This changes the extent of the map for the current session. Since the content of the map does not change, you do not need to refresh the map. More specifically, changes in map scale or extent do not require a call to map.Refresh(). Changes to layer visibility or rendering or adding and removing content (for example, graphics) require a call to map.Refresh().
The server-side code for the custom tool is finished. Now you need to add a tool item to the Toolbar control to trigger the action that executes the custom tool.
  1. Select the Toolbar control in design view or in the Properties window and click the ellipsis for the ToolbarItems property. The ToolbarCollectionEditorForm dialog box opens.
  2. In the Toolbar Items section, select Tool and click Add. The new Tool is listed under the Current Toolbar Contents section. The following screen shot reflects steps 11 and 12:

  3. Select the new tool and click the Show Properties button. A properties dialog box for the new tool opens.
     
  4. Set the following properties:
Property
Value
Description
Text
CenterAt tool
Label for the tool in the toolbar
ClientAction
Point
Client event passed to the server
ServerActionAssembly
App_Code
Class libraries associated with a Web site are compiled into an assembly named App_Code
ServerActionClass
CustomTool
The name of the custom class that implements IMapServerToolAction and that is executed when this tool is used in the map
  1. Run the application. Use the Center At tool by activating the tool in the toolbar and clicking the map. The initial mouse click triggers a callback to execute the code in the CustomTool class. The custom tool causes the Map control to generate a callback string telling the client to retrieve the map and a new extent. The callback response to the initial mouse click is processed by the Web ADF JavaScript libraries and triggers one or more additional callbacks to retrieve new map images. The Web ADF manages the callback messages for you. When finished, the map centers on the point clicked.

Under the hood

The following diagram illustrates a Web ADF toolbar initiated partial postback at runtime. The blue circles indicate the sequence of events for the initial tool action. 

  1. After the web page loads, the CenterAt tool is activated and the user clicks on the map.
  2. The onclick event for the map is triggered and mouseDown Javascript function in the ESRI.ADF.UI.Map.js is called .
  3. The postback is initiated via doCallback javascript function in ESRI.ADF.System.js. The properties of the postback request include the name of the control(Map Control) that triggered the request and the data associated with the user action (in this case click location in screen units).
  4. doCallback triggers the client-side PageRequestmanager's PageRequestManager$_doPostBack that submits the form to the server by calling PageRequestManager$_onFormSubmit(evt). Before the form gets submitted all the necessary information gets stored as hidden fields. In this case __EVENTTARTGET hold the id if the Mapcontrol (Map1) AND __EVENTARGUMENT holds the following info.
"EventArg=Point&coords=-100.02621109702774:39.9779244793861&Map1_mode=CenterAt"
 
 
  1. The Web ADF Map control implements the IPostBackEventHandler interface via its parent, the abstract WebControl class and hence when the page gets submitted to the server, it invokes RaisePostBackEvent with the current event argument string.
  2. RaisePostBackEvent calls GetCallbackResult() method to process the request. The bulk of the business logic for a callback in the Map control is present in the GetCallbackResult() method. The event argument is parsed to determine what type of action should be performed.
  3. Since the action involves a custom tool,  the ServerAction method is called for the appropriate tool. This method contains the custom code to work with Map control, depending on the user-defined action.
  4. The Map control generates one or more callback strings or CallbackResult objects to notify the client of any changes to the Map. The CallbackResult object contents consists of a simple JSON string. In this example string appears as follows:
[JavaScript]

    "[{\"id\":\"Map1\",\"type\":\"Map\",\"action\":\"setextent\",\"params\":[-133.24260529631866,-12.816344446639217,-42.392467519450094,75.174103763402968]}]"
  1. The generated CallbackResult(s) is\are registered as DataItem using ScriptManager.RegisterDataItem method. The data items that are registered by using the RegisterDataItem method can be accessed in client script during the pageLoading
  2. The pageLoading event is raised after the response from the server to an asynchronous postback is received but before any content on the page is updated.
  3. At this point the response text is sent to the client. The processCallbackResult function processes the response text and, depending on the content of the callback(s), calls another JavaScript function. In this example, the callback response indicates that the setExtent function on the client-side Map object will be called (in the JavaScript file ESRI.ADF.Map.js). This marks the completion of the asynchronous request.

Managing callbackResults from other Web ADF controls

This topic explains how to add the callbackresults generated by other web ADF control to the callback results of the control that triggered the partial postback. Essentially response gets sent to the browser only once as JSON string with all the content necessary for updating/rendering the page. Hence it becomes important to manage callback reults from other control and copy them to the callbackresults of the control initiating the partial postback.
To explain which we will add a floating panel to the web page being used in above steps and make it visible false. Please refer below for the mark-up of the floatingpanel and observe the visible attribute is set to false.
[XML]
<esri:FloatingPanel ID="FloatingPanel1" runat="server" BackColor="White" BorderColor="Gray"
BorderStyle="Solid" BorderWidth="1px" Font-Names="Verdana" Font-Size="8pt" ForeColor="Black"
Height="200px" Style="z-index: 1; left: 429px; top: 115px; position: absolute;
height: 227px; width: 200px" Title="Floating Panel" TitleBarColor="WhiteSmoke"
TitleBarHeight="20px" TitleBarSeparatorLine="False" Transparency="35" Visible="false"
Width="200px">
<asp:Label ID="lblMapCenterAt" runat="server" 
Text="The floating panel gets displayed when map is clicked after activating Center At tool. 
ADF framework will handle refresh of the map and also any callbacks from other ADF controls. 
We simply need to add callbackresults of other ADF control to Map's callbackresult property."></asp:Label> 
</esri:FloatingPanel>
Open the CustomTool.cs created in step 2 of topic Adding custom toolbar item to a toolbar and the code to make the floating panel visible on click of the tool. The complete code would look like as shown below:
[C#]
public class CustomTool: IMapServerToolAction
{
    public void ServerAction(ToolEventArgs args)
    {
        Map map = (Map)args.Control;
        PointEventArgs pargs = (PointEventArgs)args;
        map.CenterAt(pargs.ScreenPoint);
        //Find the floating panel
        FloatingPanel fp = (FloatingPanel)map.Page.FindControl("FloatingPanel1");
        //Call method to make it appear of the page. 
        //This will generate callback result for the floatingpanel
        fp.ShowFloatingPanel();
        //Floatingpanel callback results get added map callback results.
        map.CallbackResults.CopyFrom(fp.CallbackResults);
    }
}
Run the application again. At this point the floating panel is not visible. Activate the Center At tool and click on the map to center the map. The code to display the floating panel will get executed and its callback results will be copied to map's callback result. The JSON string formed after copying the results include response from both Map and the floating panel. In this case the JSON would look like as shown below.
[HTML]
"[{\"id\":\"Map1\",\"type\":\"Map\",\"action\":\"setextent\",\"params\":[-129.94296348844222,17.540360185825278,-84.517894600007864,61.535584290846444]},{\"id\":\"FloatingPanel1\",\"type\":\"FloatingPanel\",\"action\":\"javascript\",\"params\":[\"setTimeout(\\\"showFloatingPanel(\\u0027FloatingPanel1\\u0027,false);expandFloatingPanel(\\u0027FloatingPanel1\\u0027)\\\",0)\"]}]"


See Also:

ASP.NET script callback solutions
How to implement a custom solution to manage callback content
How to use the Web ADF callback framework to interact with non-Web ADF content