Extend the GridView Control

Handling Data Binding Events in GridView

Thiru Thangarathinam

October 30, 2009

12 Min Read
ITPro Today logo in a gray background | ITPro Today

The server-side data binding techniques introduced inASP.NET 1.x revolutionized the way developers build pages that access data.With the introduction of data-bound controls in ASP.NET 2.0, you now have awhole range of features at your disposal that can be used for filtering,sorting and paging, editing, and deleting data. GridView is one of theimportant data-bound controls that automatically handles these operations aslong as the bound data source control supports these capabilities. In additionto GridView s out-of-the-box features, you also have the option of extendingthese built-in capabilities by intercepting the various events of the GridViewcontrol. Specifically, by handling the data binding events, you can supportrich data-bound scenarios when the out-of-the-box capabilities fall short ofyour requirements. This article takes a detailed look at the data bindingevents supported by the GridView control and discusses the steps involved inimplementing these events. To this end, you ll see advanced examples on usingthese events to create sophisticated ASP.NET Web applications.

 

Introduction to Data Binding

The main reason for using data binding is to save you codethrough a declarative approach. For example, you can use the simple databinding features of GridView to retrieve and display data with no code at all.Although this approach works for many simple scenarios, there are times whenyou might want to extend this data binding when the simple data binding outputdoesn t meet your needs. Consider the scenario wherein you want to displayembedded GridViews that display master-detail data in an ASP.NET page. Toaccomplish this, you need to intercept one of the GridView data binding eventsand write code to retrieve the right data to display the parent and childGridView controls. When displaying data in the GridView, the main bindingevents fire in the order shown in Figure 1.

 

Event Name

Description

DataBinding

Raised when the GridView control binds to a data source.

RowCreated

Enables you to affect the row before the GridView has been bound to the fields.

RowDataBound

Enables you to affect the row after the GridView has been bound, and evaluate the GridView that has been bound.

DataBound

Raised after the GridView control binds to a data source.

Figure 1: Whendisplaying data in the GridView, the main binding events fire in this order.

 

Note that the RowCreated and RowDataBound events fire foreach row bound to the GridView control. The rich event model allows you tointercept the render of your view control at any point in the binding process.For selecting objects, the RowDataBound event is useful, because you can gainaccess to both the bound row and your object, which is useful for applyingformatting to your row. For adding custom content to the data rows, such asinjecting client-side script, use the RowCreated event.

To demonstrate the data binding events supported by theGridView control, consider the following scenarios wherein you expose rich databinding capabilities:

  • Using embedded GridView controls for displaying parent-child data

  • Injecting client-side script

  • Displaying a summary row using the GridView control

 

Using Embedded GridView Controls

In this section, you ll see an example for creating aparent/child report that shows all the records from the child table, organizedby parent. For the purposes of this example, consider displaying a completelist of products organized by category in the AdventureWorks database. Thebasic technique is to create a GridView for the parent table that contains anembedded GridView for each row. These child GridView controls are inserted intothe parent GridView using a TemplateField. The only trick is that you cannotbind the child GridView controls at the same time that you bind the parentGridView, because the parent rows have not been created yet. Instead, you mustwait for the GridView.RowDataBound event to fire in the parent. The coderequired to achieve this output is shown in Listing One.

In this example, the parent GridView defines two columns,both of which are the TemplateField type. The first column combines the categoryid and category name (see Figure 2); the second contains an embedded GridViewof products, with two bound columns (see Figure 3).

     
<%# Eval("ProductSubcategoryID") %>   

<%# Eval("Name") %>
  

Figure 2: Theparent GridView defines two columns; this one combines the category id andcategory name.

                                  

Figure 3: The parentGridView defines two columns; this one contains an embedded GridView ofproducts.

Now all you need to do is create two data sources, one forretrieving the list of categories and the other for retrieving all products ina specified category. The first query fills the parent GridView; the secondquery is called multiple times to fill the child GridView. You can bind thefirst grid directly to the data source, as shown here:

 

This part of the code is typical. The trick is to bind thechild GridView controls. If you omit this step, the child GridView controlswill not appear.

To bind the child GridView controls, you must react to theGridView.RowDataBound event, which fires every time a row is generated andbound to the parent GridView. At this point, you can retrieve the childGridView control from the second column and bind it to the product informationby programmatically calling the Select method of the data source. To ensurethat you show only the products in the current category, you must also retrievethe CategoryID field for the current item and pass it as a parameter. The codeyou need is shown in Figure 4; Figure 5 shows the resultant output generated.

void gridCategories_RowDataBound(object sender, GridViewRowEventArgs e){ if (e.Row.RowType == DataControlRowType.DataRow) { //Retrieve the GridView control in the second column GridView gridProducts = (GridView)e.Row.Cells[1].Controls[1]; //Set the CategoryID parameter to return the products //for the current category string categoryID=   gridCategories.DataKeys[e.Row.DataItemIndex].Value.ToString(); productSource.SelectParameters[0].DefaultValue = categoryID ; gridProducts.DataSource =   productSource.Select(DataSourceSelectArguments.Empty); gridProducts.DataBind(); }}

Figure 4: Retrievethe CategoryID field for the current item and pass it as a parameter ...


Figure 5: ... to show only theproducts in the current category.

 

Injecting Client-side Script

By default, GridView provides built-in support for singlerow selection. It is also possible for you to extend the single row selectionto multiple rows using a few lines of code. However, when you select multiplerows, it would be nice if you could change the background color of the selectedrow so that you can easily identify all the selected rows. To implement this,you need to be able to inject client-side script for each of the rows displayedthrough the GridView. The right place to do this is the GridView.RowCreatedevent. The complete code required to implement this solution is shown in Listing Two.

The key in the code shown in Listing Two is the RowCreatedevent handler, where you inject a block of code that does the job ofhighlighting the rows in the GridView whenever a row is selected. To injectthis block of code, use the RegisterStartupScript method of the ClientScriptManagerobject:

Page.ClientScript.RegisterStartupScript(this.GetType(), "RowCreatedScript", script, true); 

After inserting the code, you associate that with theJavaScript onclick event of the checkbox:

chkBox.Attributes.Add("onclick", "HighlightSelected(this,'" + Convert.ToString(e.Row.RowState) + "' );") ; 

If you navigate to the page in the browser, you should seean output that is somewhat similar to the screenshot shown in Figure 6.


Figure 6: Injecting client-sidescript through the RowCreated event handler.

If you select a couple of rows in the GridView, you ll seethe background color of the selected rows change to a different color, similarto that shown in Figure 7.


Figure 7: Selected rows in theGridView change color.

 

Displaying Summary Row Using the GridView Control

Although the prime purpose of a GridView is to show a setof records, you can also add more interesting information, such as summary data,by intercepting the RowDataBound event. The first step is to add the footer rowby setting the GridView.ShowFooter property to true. This displays a shadedfooter row (which you can customize freely), but it doesn t show any data. Totake care of that task, insert the content into the GridView.FooterRow.

For example, imagine you are dealing with a list ofspecial offers. A simple summary row could display the summary for each type ofspecial offer. The first step is to decide when to calculate this information.If you are using manual binding, you could retrieve the data object and use itto perform your calculations before binding it to the GridView. However, if youare using declarative binding, you need another technique. You have two basicoptions you can retrieve the data from the data object during the bindingoperation, or you can retrieve it from the grid itself after the grid has beenbound. The following example uses the former approach because it gives you thefreedom to use the same calculation code no matter what data source was used topopulate the control. It also gives you the ability to total only the recordsthat are displayed on the current page, if you have enabled paging. Thedisadvantage is that your code is tightly bound to the GridView, because youneed to pull out the information you want by position, using hard-coded columnindex numbers.

As in the previous examples, the basic strategy is toreact to the GridView.RowDataBound event. This occurs immediately after eachrow in the GridView is populated with data. At this point, you calculate thesummary by retrieving the type of discount type from the current row. Once thistotal is calculated, it is inserted into the footer row. ListingThree shows the complete code.

In the RowDataBound event, you check to see if the currentrow is a footer row using the DataRowControlType enumeration. Figure 8 showsthe output generated by the page.


Figure 8: Output generated by usingthe DataRowControlType enumeration.

 

Conclusion

This article provides a detailed discussion of the eventssupported by the GridView control. You have also been introduced to theadvanced data binding capabilities of GridView, through which you can createsophisticated Web sites. As you can see, the data binding events are veryextensible in that they provide you with hooks into the data binding lifecycle,making it extremely easy to build sophisticated ASP.NET applications.

The code accompanyingthis article is available for download.

Thiru Thangarathinamis an MVP who specializes in architecting, designing, and developingdistributed enterprise-class applications using .NET-related technologies. Heis the author of Professional ASP.NET 2.0 XMLfrom Wrox and has co-authored a number of books in .NET-related technologies.He has also been a frequent contributor to leading technology-related onlinepublications. He can be reached at mailto:[email protected].

 

Begin Listing One

<%@ Page Language="C#" %>                                              
<%# Eval("ProductSubcategoryID") %>           

<%# Eval("Name") %>
                                                                                                                                                                                             

End Listing One

 

Begin Listing Two

<%@ Page Language="C#" %>                                                                                                                          
<%# Eval("Name") %>
                                                        

<%# Eval("ProductNumber") %>
                                                    

<%# Eval("ListPrice") %>
                          

End Listing Two

 

Begin Listing Three

<%@ Page Language="C#" %>                                                                 

End Listing Three

Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like