Applies To:

Studio Enterprise


John Juback

Published On:


Asynchronous JavaScript and XML (AJAX) is a technique for optimizing the communication between Web pages and server-resident data. An AJAX-enabled application can execute server-side logic and update various page elements without reloading the entire page, which reduces server traffic while increasing the perceived responsiveness of the user interface.

This article summarizes the AJAX support introduced in the 2006 v2 release of ComponentOne Studio Enterprise, which encompasses the following ASP.NET 2.0 controls: C1WebGrid, C1WebTreeView, C1WebTabStrip, C1WebTopicBar, and C1WebReport. To see these components in action, click the following link:


AJAX is a development technique for creating rich, interactive Web applications that feel more like desktop applications, where users are accustomed to immediate responses. In a conventional Web application, user input is sent to the server, which then acts upon the data and responds by sending back an updated Web page in its entirety, a process known as a postback. In an AJAX-enabled application, small amounts of data are exchanged with the server behind the scenes, so that only the affected portions of the page need to be refreshed. To the user, the page seems faster and more responsive.

In the documentation for Visual Studio 2005, this behind-the-scenes exchange is referred to as a client callback. (You may encounter the terms script callback and out-of-band callback in older articles.)

The key advantage of AJAX is that it does not require a full postback when communicating with the server. Instead of requesting a full Web page from the server, the browser loads an AJAX engine that requests XML data from the server asynchronously. That is, the server performs the work in the background, then sends the XML to the AJAX engine when it is finished. The AJAX engine completes the transaction by raising a client-side event, generally written in JavaScript, that causes the browser to update the appropriate elements of the current page. This avoids the screen flicker associated with normal postbacks.

It is important to note that AJAX is not a technology in itself, but rather a group of technologies that work in concert:

  • XHTML or HTML, for defining page elements.
  • CSS (Cascading Style Sheets), for applying display attributes to page elements.
  • The DOM (Document Object Model), accessed with a client-side scripting language such as JavaScript, for dynamically displaying and modifying page elements and document content.
  • The XMLHttpRequest object, for exchanging data asynchronously with the web server. In Internet Explorer, this is surfaced as an ActiveX object called XMLHTTP.
  • XML, for transferring data between the server and client. If desired, other formats can be used for data transfer, including preformatted HTML or even plain text.

Note that none of the underlying technologies are proprietary; in fact, they are all widely accepted standards. AJAX exists apart from ASP.NET, yet it can be merged with ASP.NET to deliver more responsive applications. In particular, ASP.NET 2.0 introduces new functionality that simplifies the implementation of AJAX-enabled pages, including the ClientScriptManager class and the ICallbackEventHandler interface.

Although the low-level details can be rather involved, the AJAX implementation in ComponentOne controls is straightforward. You don't need to understand the inner workings of the DOM or the XMLHttpRequest object. Typically, all you need to do is set a property or two, and the control will handle the rest.

Let's examine each of the AJAX-enabled controls for ASP.NET 2.0 in detail, starting with C1WebGrid.

The C1WebGrid control, part of ComponentOne WebGrid for ASP.NET, optionally supports AJAX for all of its end-user interactions. By setting the grid's CallbackOptions property to one or more of the following options, you can control the level of AJAX support on a per-component basis:


All actions on the grid are performed via callbacks.


Column moving is performed via callbacks. This refers to both column reordering (when AllowColMoving is True) and dragging columns to/from the grouping area (when AllowGrouping is True).


Row editing and deleting are performed via callbacks. For grids with command button columns, this refers only to the edit, update, cancel, and delete links.


Group expanding and collapsing are performed via callbacks. This refers to Outlook-style grouping (when AllowGrouping is True), columns grouped at design time (in the Grouping tab of the Property Builder), and columns grouped in code (using the GroupInfo property).


All actions on the grid are performed via postback.


Paging is performed via callbacks (when AllowPaging is True).


Row selection is performed via callbacks. For grids with command button columns, this refers to the select links.


Sorting is performed via callbacks (when AllowSorting is True).

At design time, the CallbackOptions property exposes a checklist for setting and clearing individual options. In the following illustration, the ColMove and Sorting options are set.

C1WebGrid CallbackOptions Property

You can also specify multiple options in C# code as follows:

C1WebGrid1.CallbackOptions = CallbackOptionsEnum.ColMove | CallbackOptionsEnum.Sorting;

Or, in Visual Basic:

C1WebGrid1.CallbackOptions = CallbackOptionsEnum.ColMove Or CallbackOptionsEnum.Sorting

For C1WebGrid, one of the most common scenarios where you can use AJAX to improve application performance is the case of a grouped grid that starts out collapsed. The first time the user expands the plus sign for a grouped row, the grid makes an AJAX callback to retrieve the child rows as XML.

Expanding Grouped Rows in C1WebGrid

While the callback is executing, the grid displays a default spinner icon to provide a visual cue for the user that a background operation is in progress.

Default Icon for AJAX Callbacks

You can use a different image or control to provide feedback, if desired. See the section Providing Visual Cues During Callbacks at the end of this article for details.

Upon completion of the callback transaction, the grid hides the spinner icon and injects the requested child rows into the grid immediately below the row that was clicked. Depending upon the level of the clicked row within the grouping hierarchy, the newly retrieved child rows may contain group links (plus signs) that initiate their own AJAX callbacks when clicked.

Expanded Grouped Rows in C1WebGrid

Note that if the user collapses then re-expands a grouped row, the spinner icon will not reappear, and no server interaction will occur. In this case, the child rows will be displayed immediately, since they have already been retrieved.

AJAX support in the C1WebTreeView control, part of ComponentOne WebMenus and WebBars for ASP.NET, is similar to grouped row expansion in C1WebGrid. Instead of preloading the entire tree, you can configure the control to expand child nodes through AJAX callbacks, enabling it to handle large amounts of data without affecting performance. As with C1WebGrid, the control provides visual feedback that an asynchronous operation is pending.

Node Expansion in C1WebTreeView

A single boolean property, PopulateOnDemand, controls whether AJAX is used for expanding tree nodes (True to use client callbacks, False to perform a full postback). However, this property is not exposed by the C1WebTreeView control itself, but by an object that represents a level in the node hierarchy:


For data-bound tree views, this object controls the mapping between data fields and tree node attributes such as text, images, and navigation URLs.


For tree views that are populated statically at design time using the Edit verb, or dynamically at run time using the ItemPopulate event, this object specifies tree node attributes such as text, images, styles, and navigation URLs.

Data Binding Example

C1WebTreeView supports data binding via an XmlDataSource or SiteMapDataSource. In the preceding illustration, the tree control consumes an XML file with the following structure:

To define the number of node levels and their behaviors, use the DataBindings property (or Edit Bindings verb) to open the Bindings Collection Editor.

Bindings Collection Editor

Use the dropdown list and the adjacent Add button to specify the data field corresponding to each tree node level. If necessary, use the blue up/down arrow buttons to move the selected item within the list, or the red X button to remove an item from the list. For each node level, use the property grid on the right to specify the bindings between XML attributes and tree node characteristics such as text and images. For example, the Country binding sets the following properties:









Omitting font and style settings, the final markup for the C1WebTreeView control in the .aspx page looks like this:

Note that the Depth property is set to 1 for the XML root node (SalesTotals), which keeps it from being displayed in the tree. This is a commonly used technique, since the XmlDataSource control requires a single root node, which may not contain any useful attributes for display purposes.

Dynamic Example

For cases where child nodes are determined programmatically at run time, you can still set the PopulateOnDemand property to True to specify AJAX callbacks. The difference is that instead of working with C1WebBinding objects in the Bindings Collection Editor, you set the PopulateOnDemand property of one or more C1WebTreeViewItem objects created at design time or in code.

The following Page_Load event handler creates two top-level nodes, Group A and Group B, then enables AJAX callbacks for all top-level nodes in the tree:

protected void Page_Load(object sender, EventArgs e)  
    if (!this.IsPostBack)  
        C1WebTreeView1.Items.Add(new C1WebTreeViewItem("Group A"));  
        C1WebTreeView1.Items.Add(new C1WebTreeViewItem("Group B"));  

    foreach (C1WebTreeViewItem item in C1WebTreeView1.Items)   
        item.PopulateOnDemand = true;  

Note that the foreach loop modifies not only the two items created dynamically, but any pre-existing top-level items that were created at design time. To create child nodes for these items, handle the ItemPopulate event:

protected void C1WebTreeView1_ItemPopulate(object sender, C1.Web.Command.C1WebCommandEventArgs e)  
    C1WebTreeViewItem parent = (C1WebTreeViewItem)e.Item;  

    for (int i = 1; i <= 2; i  )  
        string txt = string.Format("{0} - Item {1}", parent.Text, i);  
        string url = string.Format("BLOCKED SCRIPTalert('You selected {0}');", txt);  
        C1WebTreeViewItem child = new C1WebTreeViewItem(txt, url);  

Child nodes are only created when the user clicks one of the top-level nodes. If the user subsequently clicks a child node, it navigates to the URL specified programmatically in the C1WebTreeViewItem constructor, which in this case executes a JavaScript fragment. If you need multiple levels of dynamic nodes, you can set the PopulateOnDemand property to True for items created at run time in the ItemPopulate event.

Since these controls, like C1WebTreeView, are part of ComponentOne WebMenus and WebBars for ASP.NET, they share similar object models and AJAX functionality. The PopulateOnDemand property controls whether AJAX is used to populate group elements (of type C1WebTabStripGroup or C1WebTopicBarGroup). Both controls support the GroupPopulate event for dynamically created items, which is similar to the ItemPopulate event of C1WebTreeView. Both controls also support AJAX when data bound via the Bindings Collections Editor, which manages a collection of C1WebBinding objects.

Dynamic Groups in C1WebTabStrip and C1WebTopicBar

The C1WebReport component, part of ComponentOne WebReports for ASP.NET, now uses AJAX for page navigation when its EnableCallback property is set to True.

AJAX-enabled Navigation Bar in C1WebReport

In addition to AJAX support, the 2006 v2 release includes an enhanced navigation bar with Goto Page and Export buttons, as well as improved export behavior with HttpHandler support.

Although AJAX greatly reduces the time it takes for data to be loaded, there may be some wait time due to heavy traffic on the server. Therefore, it is good practice to provide visual feedback, such as an image or label control that appears during the callback, to let the user know the data is being retrieved. All of the AJAX-enabled controls in ComponentOne Studio Enterprise provide a default spinner icon that appears during asynchronous activity.

You can specify a different image by changing the value of the CallbackWaitImageUrl property. The CallbackWaitControlID property functions the same way, except that it shows a control rather than an image.

Note: If both the CallbackWaitControlID and CallbackWaitImageURL properties are set, CallbackWaitControlID takes precedence over CallbackWaitImageURL, and only the control appears.

The AJAX-enabled controls in ComponentOne Studio Enterprise can load data without having to do a postback to the server, minimizing load time and greatly improving the end-user experience. Using asynchronous client callbacks, these components retrieve only the information that is requested, as opposed to refreshing the entire page, resulting in applications that are more responsive and efficient.

For more information on AJAX in general, see the following links:

[Wikipedia entry for AJAX](     [ASP.NET Spiced: AJAX (MSDN article)](