Av rating:
Total votes: 76
Total comments: 46


Jonas Stawski
Take Row-Level Control of Your GridView
27 September 2007

The GridView in ASP.NET seems to give the programmer few configurable options at first, but when you start using the DataBound events, then it starts to become surprisingly versatile.

Manipulate the GridView control in ASP.NET to display your data the right way

The GridView in ASP.NET is a very powerful control that provides an easy interface to add, update, delete, and display data. The GridView also lets you perform other tasks very easily, such as paging and sorting your data, but not everything is as straightforward as it seems. Most of the time, we would display the data exactly as it comes out of our datasources, but sometimes we may need to manipulate the text, cells, and rows to fit our needs. In this article I will explain how to use the events and properties of the GridView to allow us to customise the way the data appears.

Taking advantage of the GridView events and properties

GridView is great for very simple tables, but the real world is not always as straightforward as we would like it to be. Sometimes we need to specify the format of the data, and the way it is rendered in the table, more exactly. Many people will tell you to use other type of controls such as the DataList for this, because it gives the user more choices in the way that the grid is rendered. Unfortunately the DataList, unlike the Gridview, does not have all the features such as paging and sorting that are commonly required. So if you still need or want to use the GridView, but also need more control on the way that the table is rendered, you can use the GridView events and properties.

The most used event of the GridView is the RowDataBound. This event is fired every time a row is bound to data. What does this mean to us, the developers? This means that, whenever this event is fired, we will have access to the current row and all of its data, so we can manipulate the table, row, cells, and or controls of the table accordingly. I will come back to this later.

Other important events are the DataBound and the Load event. The Load event fires when the GridView is loaded and has not been attached to any data yet. In this event the user can set properties such as the color of the border, themes, or any other rendering options that are not dependent on the data itself. The DataBound is similar to the RowDataBound in that both are fired after a bound event has happened. The difference is that DataBound is fired once after the entire Grid has been bound; while the RowDataBound is fired every time a row is bound, meaning it will almost always be fired more than once. So you can use the DataBound to manipulate the table based on the data contained in it.

image


FIGURE 4: Events of the GridView

The RowDataBound is your friend.

Let’s look at the parameters needed for the RowDataBound event. Like every .NET event it has two parameters: sender of type object and e of type GridViewRowEventArgs. The sender parameter contains a reference of the GridView that is firing the event and e contains a very important property named Row which references the row that is being bound. The Row property is very important. Table 1 contains the most used properties of the GridViewRow taken from the MSDN documentation.

Property Description
Attributes Gets the collection of arbitrary attributes (for rendering only) that do not correspond to properties on the control.(inherited from WebControl)
Cells Gets a collection of TableCell objects that represent the cells of a row in a Table control.(inherited from TableRow)
DataItem Gets the underlying data object to which the GridViewRow object is bound.
RowIndex Gets the index of the GridViewRow object in the Rows collection of a GridView control.
RowType Gets the row type of the GridViewRow object.

Table 1: Most used properties of the Row

Imagine that your boss asks you to create a table of all the products with their price and Units in Stock and Units on Order. So you would simply create a GridView with a SqlDataSource with the following query: select ProductName, UnitPrice, UnitsInStock, UnitsOnOrder from Products. This is a very easy and straightforward task. Figure 5 displays the end result.

image

FIGURE 5: End result of the GridView displaying the products.

Your boss sees the page and says he would love to be able to quickly distinguish all the products that need to be reordered, and also the products that have already been reordered. So you could then simply tell him that not only will you display the numbers as they are, but also display the products that need to be reordered in red and the ones that have been reordered in blue. Your boss loves the idea, but you have no clue how to do that with a GridView. The way to do this is to use the RowDataBound event. The code on Figure 6 shows how to accomplish this simple, but not intuitive task.


protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//We're only interested in Rows that contain data
//get a reference to the data used to databound the row
DataRowView drv = (DataRowView)e.Row.DataItem;
if (Convert.ToInt32(drv["UnitsInStock"]) == 0)
{
//The current product has 0 items in stock
e.Row.Font.Bold = true; //Make the font bold
e.Row.ForeColor = System.Drawing.Color.Red; //Set the text color red
if (Convert.ToInt32(drv["UnitsOnOrder"]) > 0)
{
//The current out of stock item has already been ordered
//Make it blue
e.Row.ForeColor = System.Drawing.Color.Blue;
}
}
}
}

FIGURE 6: Code for setting fore color of each row.

The GridView fires the RowDataBound event on every row, including the header and footer. Therefore we need to make sure, when the event is fired, that it is fired on a DataRow. If it is, then we get a reference to the DataRowView, which represents the row of the datasource to which the row of the GridView was tied to. In our case this represents a row from the database result set. Please note that the e.Row.DataItem returns an object. The reason for that is that you can bind a GridView to any item that implements the ICollection interface: DataTable, DataSet, List, Array, etc. The type of the DataItem will vary with the DataSource used. Once we get a reference to the DataRowView, we then check to see if that Product is out of stock or if it is in the process of restocking and set the ForeColor of the row equal to the correct color. Figure 7 shows the end result.

image

Figure 7: The new GridView with the color change

Your boss is now in a good mood, and knows that you can do a lot for him: He therefore wants a new report. This new report will include all the products by Category. He does not want to see the category repeated every time. Your data comes in the format displayed in Figure 8.

image

FIGURE 8: Data from datasource

The idea is the same as in the previous example. We need to implement the RowDataBound event and check when the CategoryName changes. If it does, then we will display it, if it does not, then we hide it. But to make it more complicated, not only are we going to hide it, but we are going merge the rows together. Figure 9 displays the code needed to make this happened and Figure 10 displays the end result.


string previousCat = "";
int firstRow = -1;
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//We're only interested in Rows that contain data
//get a reference to the data used to databound the row
DataRowView drv = ((DataRowView)e.Row.DataItem);

if (previousCat == drv["CategoryName"].ToString())
{
//If it's the same category as the previous one
//Increment the rowspan
if (GridView1.Rows[firstRow].Cells[0].RowSpan == 0)
GridView1.Rows[firstRow].Cells[0].RowSpan = 2;
else
GridView1.Rows[firstRow].Cells[0].RowSpan += 1;
//Remove the cell
e.Row.Cells.RemoveAt(0);
}
else //It's a new category
{
//Set the vertical alignment to top
e.Row.VerticalAlign = VerticalAlign.Top;
//Maintain the category in memory
previousCat = drv["CategoryName"].ToString();
firstRow = e.Row.RowIndex;
}
}
}

FIGURE 9: Code to get rid of the repeated category

image

FIGURE 10: Products by Category

The code is very similar to the previous example. This time we are using the help of two global variables: previousCat and firstRow. The variable previousCat is used to save the category of the previous row, so if the category is the same we increment the row span of the row containing the category and then delete the first cell of the current row. Whenever a new category arrives we leave the row intact and save the previousCat and firstRow to their corresponding values. Please note that this code will only work correctly if the data is sorted by the category name.

Your boss is now ecstatic; he knows he had made a great investment by hiring you. He knows you are on a roll and that is why he wants to change the first report by adding an image right next to the discontinued products. Figure 11 shows the code to accomplish the task and Figure 12 shows the end result.


protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//We're only interested in Rows that contain data
//get a reference to the data used to databound the row
DataRowView drv = (DataRowView)e.Row.DataItem;
if (Convert.ToInt32(drv["UnitsInStock"]) == 0)
{
//The current product has 0 items in stock
e.Row.Font.Bold = true; //Make the font bold
e.Row.ForeColor = System.Drawing.Color.Red; //Set the text color red
if (Convert.ToInt32(drv["UnitsOnOrder"]) > 0)
{
//The current out of stock item has already been ordered
//Make it blue
e.Row.ForeColor = System.Drawing.Color.Blue;
}
}
if ((bool)drv["Discontinued"])
{
//Discontinued product
//Add the image
Image img = new Image();
img.AlternateText = "Discontinued Product";
img.ImageAlign = ImageAlign.AbsMiddle;
img.ImageUrl = "arrow_down.gif";
img.Width = Unit.Pixel(10);
img.Height = Unit.Pixel(11);
e.Row.Cells[0].Controls.Add(img);

//Add the text as a control
e.Row.Cells[0].Controls.Add(new LiteralControl(" " + e.Row.Cells[0].Text));
}
}
}

FIGURE 11: Code for setting fore color and discontinued image.

image

FIGURE 12: End result of the discontinued product

The code is the same code as in the first example with the addition of the discontinued part. We first have to check whether the current product is discontinued. If it is, then we create a new image and add it to the controls collection of the cell. Since we are adding a control to the collection, the GridView gives priority to the controls and ignores the text property, which is why we need to add the text as a control. This makes the GridView render the cell as an image with text right next to it.

Conclusion

From design time to run time formatting, from declarative programming to imperative programming, the GridView is one of the most complex and simple controls in the ASP.NET arsenal. It allows you to create simple tables with very little programming and also allows you to have full control of its formatting to create very complicated grids. Not only is the GridView a very powerful control for normal day to day functions such as displaying, adding, updating, and deleting data or for nice features such as paging and sorting, but also is a very powerful control in that it enables you to have full control of how it renders itself. I hope the next time you are creating a grid for your boss you can play around with the GridView Events and properties to come up with a neat solution.

Happy Programming!

The source files for this project can be downloaded by clicking on CODE DOWNLOAD in the speech bubble at the top of the page



This article has been viewed 19750 times.
Jonas Stawski

Author profile: Jonas Stawski

Jonas Stawksi works as a consultant for ASPSOFT, Inc (www.aspsoft.com). Jonas is a Microsoft Most Valuable Professional (MVP) in Visual C# and Microsoft Certified Application Developer (MCAD) with over 5 years of experience building and architecting .NET applications and over 7 years of professional experience using Microsoft development technologies such as ASP, Visual Basic, and SQL Server. Jonas has worked in several markets such as Insurance, Real Estate, Leasing, Medical, Restaurant Management, among others. You can visit his blog at www.jstawski.com.

Search for other articles by Jonas Stawski

Rate this article:   Avg rating: from a total of 76 votes.


Poor

OK

Good

Great

Must read
 
Have Your Say
Do you have an opinion on this article? Then add your comment below:


Subject: Fantastic Article
Posted by: Atom.i.nous (not signed in)
Posted on: Monday, October 01, 2007 at 11:28 AM
Message: What a great piece. The gridview can be a developer's best friend and most evil enemy. Although it it often overused for things which shouldn't be displayed in table format (if you're concerned with semantic mark-up) it is delciously easy an quick to implement advanced functionality. Your article REALLY helps on taming this sometimes out-of-control beast.

Subject: Good article!
Posted by: John Papa (not signed in)
Posted on: Monday, October 01, 2007 at 3:00 PM
Message: Nice job on the article. Brief, keeps the interest and has value in teaching how some of the features work.

Subject: On Color Setting
Posted by: Mustafa Basgun (not signed in)
Posted on: Wednesday, October 03, 2007 at 8:26 AM
Message: In order to have some flexibility with the color setting, followings can also be used instead of "System.Drawing.Color.Red;":

// If you know the hex value
System.Drawing.Color.FromName("#FF0000");
// If you know the ARGB value
System.Drawing.Color.FromArgb(255, 0, 0);

If you'd prefer to set it at the global.asax within an Application event, you can call it by the same way as well:

Sub Application_Start(...)
Application("ForeColor") = "Red"
End Sub

System.Drawing.Color.FromName(Application("ForeColor"));

Thanks for the article by the way!

Subject: Great Article
Posted by: Donna McDaniel (not signed in)
Posted on: Wednesday, October 03, 2007 at 11:12 AM
Message: This exactly what I needed to finish my project. Thanks for taking the time to write the article.

Subject: Typed Data Set
Posted by: Judah Sali (not signed in)
Posted on: Wednesday, October 03, 2007 at 10:04 PM
Message: Excelent article Jonas.

And, if you're using a typed dataset you can get a reference to your typed data row this way (VB):

Dim dr As MyDataSet.MyDataTableRow = CType(CType(e.Row.DataItem, System.Data.DataRowView).Row, MyDataSet.MyDataTableRow)

Then you can use the typed fields of your data row:

If dr.MyField = 0 Then ...

Thanks again.

Subject: Great article
Posted by: John Cross (not signed in)
Posted on: Sunday, October 14, 2007 at 6:19 PM
Message: Thanks! I love it when things are explained clearly.

Subject: Wonderful Article
Posted by: Anonymous (not signed in)
Posted on: Friday, October 19, 2007 at 2:47 AM
Message: This is really what we are in need of to complete a module in our project. Very Good explanation with a real time example. Thanks for the article.

Subject: reading data from gridview
Posted by: Anonymous (not signed in)
Posted on: Monday, October 29, 2007 at 1:03 AM
Message: i want to read data from the gridview to textboxes on selecting row and redisplay after changing it in grid.

Subject: RowSpan and post backs
Posted by: Anonymous (not signed in)
Posted on: Wednesday, October 31, 2007 at 3:03 PM
Message: I found the article helpful. I would like to add that the code to span cells over multiple rows doesn't work with post backs.

I have found that using
e.Row.Cells[0].Visible = false;
instead of
e.Row.Cells.RemoveAt(0);
does the trick.

Subject: RowSpan and post backs
Posted by: Anonymous (not signed in)
Posted on: Wednesday, October 31, 2007 at 3:56 PM
Message: I found the article helpful. I would like to add that the code to span cells over multiple rows doesn't work with post backs.

I have found that using
e.Row.Cells[0].Visible = false;
instead of
e.Row.Cells.RemoveAt(0);
does the trick.

Subject: setting gridView row height?
Posted by: Henry C (not signed in)
Posted on: Friday, November 30, 2007 at 8:55 AM
Message: Good Article!

I've tried many times to set the height of the rows but have not been successful, do you know how to do this? thanks.

Subject: great article
Posted by: Priya (view profile)
Posted on: Tuesday, December 04, 2007 at 1:14 AM
Message: its very nice article,helped me to learn more about grid view events

Subject: XML and Gridview
Posted by: Anonymous (not signed in)
Posted on: Thursday, January 31, 2008 at 1:38 PM
Message: Very nice article. Well articulated. Love such articles

Can u show an example of xml and gridview. Especially rendering an html tag inside a gridview row

Subject: Newbie Thanks.
Posted by: John Alvarez (not signed in)
Posted on: Saturday, February 02, 2008 at 5:40 PM
Message: I looked through 30 or 40 posts to find what was written. JONAS ROCKS..

thanks!!!!!!!!!!!

Subject: Regarding Gridview
Posted by: Lakshmi (view profile)
Posted on: Saturday, February 02, 2008 at 9:17 PM
Message: Can you plz tell me whether paging and sorting works when the rowdatabound event is used? I am not using datasource controls to bind the data. I am using gridview.datasource=dataset
gridview.databind()
Can you plz guide me?

Thanx

Subject: Regarding Gridview
Posted by: Lakshmi (view profile)
Posted on: Sunday, February 03, 2008 at 12:02 AM
Message: Can you plz tell me whether paging and sorting works when the rowdatabound event is used? I am not using datasource controls to bind the data. I am using gridview.datasource=dataset
gridview.databind()
Can you plz guide me?

Thanx

Subject: gooooooood
Posted by: Anonymous (not signed in)
Posted on: Thursday, February 21, 2008 at 4:20 AM
Message: too gud:):)

Subject: very nice artical
Posted by: Ramanaji (not signed in)
Posted on: Friday, February 29, 2008 at 1:21 PM
Message: Its very nice artical

Subject: Good one!!!
Posted by: Swapnil Mohod (not signed in)
Posted on: Thursday, March 20, 2008 at 2:54 AM
Message: Good one!!!

Subject: excellent, excellent, excellent
Posted by: Anonymous (not signed in)
Posted on: Thursday, March 20, 2008 at 6:42 PM
Message: Thank you so much for sharing this. It was exactly what I was looking for.

Subject: Need your help
Posted by: Anonymous (not signed in)
Posted on: Monday, March 24, 2008 at 11:37 AM
Message: Great paper. Could you help me to get rid of repeated Category and ProductNames in the same time.
Thank you.

Subject: Need your help
Posted by: Anonymous (not signed in)
Posted on: Monday, March 24, 2008 at 12:06 PM
Message: Great paper. Could you help me to get rid of repeated Category and ProductNames in the same time.
Thank you.

Subject: well done Jonass
Posted by: prami (not signed in)
Posted on: Monday, March 31, 2008 at 3:28 PM
Message: well done Jonass ---n thnks a lot for this article n code ---my works done perfect--

can u explain how to get textbox values in a gridview for updating purpose all at once
in vb.net

Subject: setting gridView row height?
Posted by: DaveC (view profile)
Posted on: Friday, April 11, 2008 at 3:15 PM
Message: Setting the row height declaratively requires you to set a style trigger on the ListView so you can set the MaxHeight of the ListViewItems in the ListView. You want to set MaxHeight, not Height, because Height is just the initial height of the row and could change if a large amount of data is added.

<ListView.Resources>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="MaxHeight" Value="18" />
</Style>
</ListView.Resources>

Subject: rowspan
Posted by: thomas (view profile)
Posted on: Monday, April 14, 2008 at 1:58 AM
Message: merge cell when categoryname is same as it is --

this is not working properly

the 3rd row seems to be push forward and populate in the 2nd colunm

Subject: Changing the row color
Posted by: Anonymous (not signed in)
Posted on: Thursday, May 01, 2008 at 10:52 AM
Message: Great article Jonas! How would I go about changing the row color as in figures 6 and 7 but using a windows.form.gridview? It seems the windows form version of gridview doesn't have the same features as the web.ui version.

Thanks,
Brian

Subject: Max Row Height Again?
Posted by: Starbuck (not signed in)
Posted on: Thursday, May 08, 2008 at 3:45 PM
Message: DaveC, that's very interesting and I'd like to make use of the advice, but how does it apply to the GridView? I have gridview rows that are very difficult to size and the various standard properties and declarative elements don't seem to provide enough control. TIA

Subject: iJKHaDTNzRUyYQOgFOU
Posted by: aloykfef (not signed in)
Posted on: Thursday, May 29, 2008 at 5:45 AM
Message: D9q7zY <a href="http://qgxrbkrovynf.com/">qgxrbkrovynf</a>, [url=http://ogmryagiousv.com/]ogmryagiousv[/url], [link=http://bebpfsdxuxbs.com/]bebpfsdxuxbs[/link], http://vyyvgoyzqcxd.com/

Subject: lnAAnnaZHn
Posted by: bquyfcaq (not signed in)
Posted on: Thursday, May 29, 2008 at 5:45 AM
Message: XQUTyz <a href="http://blxcxhksyzsz.com/">blxcxhksyzsz</a>, [url=http://jxflvaoikjys.com/]jxflvaoikjys[/url], [link=http://fwtcudowgggt.com/]fwtcudowgggt[/link], http://dsvwzmlhmjjg.com/

Subject: ambien
Posted by: ambien (not signed in)
Posted on: Sunday, June 01, 2008 at 11:52 PM
Message: Article Opinion <a

Subject: xenical
Posted by: xenical (not signed in)
Posted on: Sunday, June 01, 2008 at 11:52 PM
Message: Article Opinion <a

Subject: ephedrine
Posted by: ephedrine (not signed in)
Posted on: Sunday, June 01, 2008 at 11:52 PM
Message: Article Opinion <a

Subject: lexapro
Posted by: lexapro (not signed in)
Posted on: Sunday, June 01, 2008 at 11:52 PM
Message: Article Opinion <a

Subject: viagra
Posted by: viagra (not signed in)
Posted on: Sunday, June 01, 2008 at 11:53 PM
Message: Article Opinion <a

Subject: link in gridview
Posted by: rakesh (not signed in)
Posted on: Monday, June 02, 2008 at 2:29 AM
Message: how make link in gridview,and link genrate the report please give me ans wiht exapmal and print
screen the program

Subject: GRIDVIEW Help
Posted by: Cat9150 (not signed in)
Posted on: Wednesday, June 04, 2008 at 12:21 PM
Message: what does this code do exactly? Am trying to learn what do to to change the values in gridview after built

Subject: Message to related articles
Posted by: Mohammad javed (not signed in)
Posted on: Tuesday, June 10, 2008 at 1:55 AM
Message: Sir, my name is Mohd Javed.i have done my BCA from GGSIP University Delhi(INDIA).I read your article i am fully satisfy.your articles is excellent.

Subject: Very Nice Articles
Posted by: Mohammad javed (not signed in)
Posted on: Tuesday, June 10, 2008 at 1:57 AM
Message: excellent excellent very excellent articles

Subject: very good article
Posted by: saju (view profile)
Posted on: Wednesday, June 11, 2008 at 12:54 PM
Message: continue to write more more articles

Subject: Wonderful Article
Posted by: Anonymous (not signed in)
Posted on: Thursday, June 12, 2008 at 6:05 AM
Message: It's simply wonderful!
Plz keep them coming!!!

Emmao.

Subject: Wonderful Article
Posted by: Anonymous (not signed in)
Posted on: Thursday, June 12, 2008 at 6:05 AM
Message: It's simply wonderful!
Plz keep them coming!!!

Emmao.

Subject: for VB.NET
Posted by: Enrique Tobias (not signed in)
Posted on: Friday, June 13, 2008 at 11:56 AM
Message: Como seria el codigo para VB.NET

Subject: Awesome Article
Posted by: Syed (view profile)
Posted on: Tuesday, June 17, 2008 at 12:47 PM
Message: Thanks for taking time to write, such a wonderful article and helping many of the programmers.

Subject: Awesome Article
Posted by: Syed (view profile)
Posted on: Tuesday, June 17, 2008 at 12:47 PM
Message: Thanks for taking time to write, such a wonderful article and helping many of the programmers.

Subject: Great Article for Row Level Control
Posted by: Santosh Kumar (not signed in)
Posted on: Monday, June 30, 2008 at 6:34 AM
Message: Thanks for giveing gridview rowlevel control article,such a exclent article for helping to gridview programming.

Santosh Kumar
http://www.operativesystems.com

Subject: How To?
Posted by: Shilpa (not signed in)
Posted on: Tuesday, July 01, 2008 at 12:58 AM
Message: Hi!
Am shilpa,i am using 1 girdview control for two deffernt table depends on condition in if statement!
now i 2 tables has defferent columns and primary key ! i have to hold primary keys of both! and don't have to show them in grid view!for that i set datakeysName to primarykey column that is same for both table!did the autogenaration of columns false. set bound columns according to one table !ran select * query !
NOW the problem begins!
i have to hide bound columns through the coding!!!!as 2nd table goes to fill in grid view with different columns!
IS THIS Possible ?


Enter your comment here:

  Name: 
  Subject: 
  Message: 
 
 






recommended site pinvoke

PInvoke.net is a user-driven wiki which provides .NET developers with native method signatures, so they don't have to spend time writing them from scratch.





Damon Armstrong
Customizing the Login Page in SharePoint 2007
 Damon shows how a few simple steps lead you to being able to include the login form in a consistent look and feel to...  Read more...


Silverlight-Speed Loop
 John Bower steps up a gear, produces a Lamborghini, and examines the process of using a high-speed... Read more...

Entity Framework: The Cribsheet
 Prasanna Amirthalingam provides an overview of Entity Framework and how it can be used. He shows that... Read more...

Updates to setup projects
 This article explains how to install a new version of your setup project using the Windows Installer... Read more...

Let there be Silverlight
 John Bower stays calm, and so will you, whilst guiding you to producing your first Silverlight... Read more...

Silverlight Skinnable User Interfaces
 John Bower demonstrates more of the features of Silverlight, and Expression Blend, and shows how one... Read more...

.NET Application Architecture: the Data Access Layer
 Find out how to design a robust data access layer for your .NET applications. Read more...

Web Parts in ASP.NET 2.0
 Most Web Parts implementations allow users to create a single portal page where they can personalize... Read more...

Visual Studio Setup - projects and custom actions
 This article describes the kinds of custom actions that can be used in your Visual Studio setup project. Read more...

A Complete URL Rewriting Solution for ASP.NET 2.0
 Ever wondered whether it's possible to create neater URLS, free of bulky Query String parameters?... Read more...

Getting started with setup projects
 This article describes the basics of Visual Studio setup and deployment projects. Subsequent articles... Read more...

Over 150,000 Microsoft professionals subscribe to the Simple-Talk technical journal. Join today, it's fast, simple, free and secure.

Join Simple Talk