Alternate by Value

Use field values to alternate rows in a DataGrid.



TECHNOLOGIES: Data Binding | DataSet | DataGrid


Alternate by Value

Use field values to alternate rows in a DataGrid.


By Dino Esposito


In ASP.NET, both the DataGrid and the DataList controls let you set style properties for alternating items in the list. Once you set the ItemStyle and AlternatingItemStyle properties, the control applies different styles to the items drawn in even and odd positions automatically. The ItemStyle property governs the appearance of items in the odd rows, while the AlternatingItemStyle property controls the appearance of items in the even rows.


This feature is designed specifically to enhance the controls' look and feel and make them more user friendly, particularly when you need to display long data reports with dozens of rows. Common style attributes you might want to configure to distinguish rows and alternating rows include the foreground and background colors, and sometimes font and text alignment. The internal methods responsible for rendering the contents of DataGrid and DataList to HTML detect and handle the alternating style automatically. Alternate rows always are displayed every other row and there is no programmatic way to alter this predefined behavior.


In this article, I'll discuss some techniques to customize the DataGrid output so the style of the rows is alternated according to value rather than position. The net effect is that all the rows sharing the same value on a specific field will share the same style. Although the code shown next is geared toward DataGrid, adapting it to DataList controls is trivial. (You can download this article's sample application).


How is a DataGrid Rendered?

The output generated by a DataGrid control is always an HTML table. As a result, the core of the work being done when a DataGrid is rendered consists of creating the internal table - a DataGridTable object. Once fully set up, such an object is simply instructed to output its content to HTML. The DataGridTable object loops through its internal collection of table rows and recursively asks each row to render itself. The internal DataGridTable is composed of as many rows as there are rows in the bound data source page, as well as some helper rows such as those representing the header, footer, and pager. Each row is mapped to an instance of the DataGridItem class and assigned a type. The ListItemType enumeration gathers all the feasible types (see Figure 1).


Item Type



A data-bound item in an even-indexed row.


A data-bound item currently in edit mode.


The footer for the control; not data-bound.


The header for the control; not data-bound.


A data-bound item in an odd-indexed row.


The pager that displays the controls to navigate to different pages associated with the DataGrid control; not data-bound and not supported by DataList controls.


The control's selected data-bound item.


The separator between items in a DataList control.

Figure 1. These are the allowable item types for DataGrid and DataList controls.


The DataGridTable object - the core of the DataGrid control - is composed of a collection of items, each of which belongs to one of the categories in Figure 1. The DataGrid control renders each item type in a different way and according to different styles. In particular, Item and AlternatingItem types are rendered as normal items but with a different set of Cascading Style Sheet (CSS) attributes.


Notice that the final set of CSS styles for a grid item is obtained cumulatively by summing the current styles and those inherited from other style properties. Style properties form a hierarchy (see Figure 2). For example: The actual properties of an alternating item are given by uniting the default styles set by the ControlStyle property and the ItemStyle property with the styles overridden by the AlternatingItemStyle property itself.


Figure 2. Item style properties in a list control are inherited from one item style property to another through a hierarchy.


By default, items and alternating items share the same style. But by leveraging the AlternatingItemStyle property on the DataGrid object, you can differentiate them at will. More importantly, the application of item styles is a process that takes place internally and cannot be controlled programmatically. So how can you alter the procedure to alternate rows based on the values of a field rather than by position? Figure 3 shows the standard look of a DataGrid control with default item alternation enabled; this is the DataGrid you will produce by the end of this article.


Figure 3. This is how a DataGrid control looks when using the position-based style alternation (left) and the value-based technique (right) discussed in this article.


Reset Style Attributes

You need to take two basic steps to have value-based alternating rows in a DataGrid. First, you must set the name of the data-bound field whose values should be used. If you plan to incorporate the new functionality in a derived DataGrid class, the name of the field can be exposed easily as a read-write property; otherwise, define a protected data member in the ASPX file or in the code-behind class. The second step consists of defining a handler for the ItemCreated event. The handler will override the way in which the items and alternating items are rendered. More exactly, the handler uses either ItemStyle or AlternatingItemStyle as appropriate to set the Style property of the DataGridItem element being drawn. The style switches whenever the value in the specified field changes. For a better result, I assume the data source displayed through the DataGrid is sorted on that field, although the feature itself works irrespective of the sort. The following code snippet illustrates the structure of the code-behind class for a page that implements this feature:


public class MyPage : Page {

   protected DataGrid grid;

   private object m_lastKeyFound = new object();

   private string m_alternateField = "customerid";

   private Style m_currentStyle;


   void ItemCreated(Object sender, DataGridItemEventArgs e) {

      if (itemType==ListItemType.Item ||






The m_lastKeyFound internal member tracks the last displayed value for the alternate field - customerid in the previous code sample and in Figure 3. Whenever the content of m_lastKeyFound does not match the field value for the item being displayed, the style for the item is toggled from ItemStyle to AlternatingItemStyle or vice versa. The m_currentStyle member tracks the current style object.


Before going any further with the implementation details of the ItemCreated method, let's discuss how you assign and manipulate style objects. To override the DataGridItem's system-provided style, you need to set the Style property with a user-defined object. The rub is that the Style property is marked as read-only, so this code simply won't work:


if (m_keyIsChanged)

    gridItem.Style = grid.ItemStyle;


    gridItem.Style = grid.AlternatingItemStyle;


Although you can't replace a style object altogether, you can modify the attributes of a Style object through the ApplyStyle method. This method copies any nonblank elements of the input style to the caller style object that overwrites any existing style attributes. You should rewrite the previous code like this:


if (m_keyIsChanged)





Another subtle problem to fix entails the overall role of the AlternatingItemStyle property. The alternating style always is assigned to all DataGrid items whose type is AlternatingItem. The type of the item is a built-in value and cannot be altered programmatically, so any item that happens to occupy an even position will always be assigned alternating style attributes. This means that from the DataGrid's standpoint, an alternating row always will occur every other item. In light of this, how can we ensure that, say, three consecutive items have the same style when this style must be ItemStyle?


This pseudo code shows how the DataGrid runtime determines the style for the item being displayed:


Style styleOfCurrentItem = new TableItemStyle();



if (ItemType == ListItemType.AlternatingItem)



As you can see, if the item is marked as alternating (this is not a feature you can control programmatically) the runtime irrevocably adds to its style objects the attributes of the AlternatingItemStyle object. This behavior represents a clear problem. Fortunately, you have a few workarounds for the issue.


You could consider only the background color of the alternating style and disregard all other attributes. The background color is a read-write property you can set at will and, more importantly, it is what you really want to change in most cases.


The approach I suggest, however, is more systematic. Upon loading the page, you make an internal copy of the AlternatingItemStyle object, then reset the original one to all blank values:


protected override void OnLoad(EventArgs e)


   // Replace AlternatingItemStyle

   m_alternatingStyle = new TableItemStyle();





In this way, the DataGrid runtime code ends up working with an empty AlternatingItemStyle object as if no tag were ever indicated in the DataGrid declaration. Thus, by default - that is, unless you enter your style changes dynamically - both items and alternating items are rendered in the same way. You must obtain a deep copy of the AlternatingItemStyle object, whose native type is TableItemStyle. So you first create a new TableItemStyle object, then copy all the settings from the current (and user-defined) AlternatingItemStyle object. Next, you empty the DataGrid property using the Reset method.


Alternate Values

So far you have the original user-defined AlternatingItemStyle duplicated in the internal member m_alternatingStyle. In addition, the grid renders all of its elements as ordinary items. By hooking the ItemCreated event, you can change the style of each Item and AlternatingItem element dynamically in the page. This code retrieves the data associated with the DataGrid item being displayed:


DataRowView drv = (DataRowView) gridItem.DataItem;

if (drv == null)



I assume the underlying data source is a DataView object. Consequently, the particular data item can be an object only of type DataRowView. To decide which style to apply, you extract the row value for the tracked field and compare it to the last value found:


// m_alternateField is the key field to consider

if (m_lastKeyFound.Equals(drv[m_alternateField]))




    m_currentStyle = (m_currentStyle==grid.ItemStyle




    m_lastKeyFound = drv[m_alternateField];



When a new value is going to be displayed in the monitored column, the current style for the item is toggled and applied. The last key value found is also updated.


The alternation of styles is a powerful feature that the DataGrid and the DataList controls support in a rather rigid way. They are flexible enough to let you configure the CSS styles at will, but then they consider only row alternation by position - that is, one row is an item, the other row is an alternating item. As I've demonstrated in this article, the concept of row alternation is a bit more general and can also be obtained using field values to distinguish items. Because the controls do not support the feature natively, a bit of extra work is needed, but the results are worth the effort.


The sample code in this article is available for download.


Dino Esposito is a trainer and consultant for Wintellect (, where he manages the ADO.NET and XML classes. Author of Building Web Solutions with ASP.NET and ADO.NET and Applied XML Programming for Microsoft .NET (Microsoft Press), Dino also is a co-founder of E-mail him at mailto:[email protected].


Tell us what you think! Please send any comments about this article to [email protected]. Please include the article title and author.




Hide comments


  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.