Click here to Skip to main content
15,881,139 members
Articles / Web Development / ASP.NET
Article

Advanced DataGrid Formating with ItemDataBound

Rate me:
Please Sign up or sign in to vote.
4.39/5 (25 votes)
14 Mar 20052 min read 225.5K   4   116   34
Use ItemDataBound to spice up your DataGrid and have it look cool.

Sample image

Introduction

I was looking to produce DataGrids that had the same functionality as printed reports and that looked like some very expensive reporting management systems I was tasked with replacing, with .NET. The end product had to draw the users' attention to the data they wanted, not fluff the user with extra fields and details. This article helps you get started, in using a few simple tricks to spice up the look and feel of your DataGrids.

I'll show you how to:

  • Create groupings for columns
  • Highlight sub totals and grand totals
  • Highlight single cells based on data values

SQL Data and Database

I used Northwind and SQL Server DB to produce the data for this article with a sub total for each product category and a grand total at the end. The code will work for any data source. I have included the SQL stored procedure for those who are interested in recreating exactly what's shown.

I tend to do nearly all my business logic on the database side and use the DataGrid for display purposes, so all sorting and totals are done here.

SQL
CREATE PROCEDURE usp_sales_by_cate AS

create table #temp ( Sorty int, CategoryName varchar(50), 
                  ProductName varchar(50), ProductSales real)

-- Get Base Sales
INSERT INTO #temp
SELECT 0, dbo.Categories.CategoryName, dbo.Products.ProductName, 
SUM(dbo.[Order Details Extended].ExtendedPrice) 
AS ProductSales
FROM dbo.Categories INNER JOIN
dbo.Products INNER JOIN
dbo.Orders INNER JOIN
dbo.[Order Details Extended] ON dbo.Orders.OrderID = 
             dbo.[Order Details Extended].OrderID ON 
dbo.Products.ProductID = 
  dbo.[Order Details Extended].ProductID ON dbo.Categories.CategoryID = 
                                   dbo.Products.CategoryID
WHERE (dbo.Orders.OrderDate BETWEEN '19970101' AND '19971231')
GROUP BY dbo.Categories.CategoryName, dbo.Products.ProductName
ORDER BY dbo.Categories.CategoryName

-- Build SubTotal
INSERT INTO #temp
SELECT 1 , CategoryName, 'SubTotal', sum( ProductSales)
from #temp

group by CategoryName
-- Build Grand Total
INSERT INTO #temp
SELECT 2 , 'XXXXX', 'Grand Total', sum( ProductSales)
from #temp  
Where sorty = 0  

-- Display Values
SELECT CategoryName, ProductName, ProductSales from #temp
order by CategoryName, Sorty

Creating Groupings

What I don't want is that every category be displayed on every first column, I only want the category to be displayed when it changes. This gives a nice and clean look to the DataGrid, allowing users to find items easily and quickly.

First, I create a public variable that will work across the whole page, and more importantly, remember something each time the <Itemdatabound> is run for each row of the DataGrid. On Page Load, it is also preset (I've had a few strange issues not doing this).

C#
public class WebForm1 : System.Web.UI.Page
{
  public string LastColumn;
..
..

private void Page_Load(object sender, System.EventArgs e)
{
// Set LastColumn to blank. 
if (!IsPostBack) LastColumn = "";

Then I use the <LastColumn> variable to track the changes in the data being written to the DataGrid. If the cell value for cell[0] has not changed, the text of the cell is deleted and the border of the cell is removed:

C#
e.Item.Cells[0].Style.Add("BORDER", "none").

To ignore the DataGrid header:

C#
if( ( e.Item.ItemType.ToString()!= "Header"))
       {.....

This can also be used for items, alternative items and footers on a DataGrid to specialize your code.

Below is the full code to group the first column on the DataGrid.

C#
private void DataGrid1_ItemDataBound(object sender, 
       System.Web.UI.WebControls.DataGridItemEventArgs e)
{
         //Get the current column 0 text
            string CurrentColumn = e.Item.Cells[0].Text;

     // Skip Headers 
     if( ( e.Item.ItemType.ToString()!= "Header"))
       {
            // Has there been a change 
           if (CurrentColumn == LastColumn)
             {
               // No Change in Column 0 
               //blank and remove boarder
               e.Item.Cells[0].Text = "";
               e.Item.Cells[0].Style.Add("BORDER", "none"); 
             }
           else
               {
                 // this is the first of the series
                 // set LastColumn to current colums
                 LastColumn = CurrentColumn;
                // Add a little back colour to the Cell[0]
                e.Item.Cells[0].BackColor = 
                              System.Drawing.Color.WhiteSmoke;
               }
}

Highlighting Subtotals and Grand Totals

This is fairly simple, it tests if cell text is "Sub Total" / "Grand Total", then sets the font, bold, colors etc. to what you want.

C#
// Check to see if its a SubTotal
string MyCol2 = e.Item.Cells[1].Text;

if (MyCol2 == "SubTotal")
  {
    e.Item.Font.Bold = true;
    e.Item.BackColor = Color.DimGray;
    e.Item.ForeColor = Color.White;

   // blank out Column 0 so its approves 
    e.Item.Cells[0].Text = "";
    e.Item.Cells[0].Style.Add("BORDER", "none"); 
    e.Item.Cells[0].BackColor = Color.Transparent;
  }

if (MyCol2 == "Grand Total")
   {
     e.Item.Font.Bold = true;
     e.Item.BackColor = Color.Red;
     e.Item.ForeColor = Color.White;
     e.Item.Cells[0].Style.Add("BORDER", "none"); 
     e.Item.Cells[0].BackColor = Color.Transparent;
}

Highlighting Single Cells

I use this all the time to show negative values in red (the way accountants like them). I find that parsing string to a number can produce some weird errors so I generally wrap it in a try, catch to ignore any errors that may crop up.

C#
// Make some items standout if below 5000 in sales
string MyStr = e.Item.Cells[2].Text;

try
{
    double MyValue = double.Parse(MyStr);
      
    if (MyValue < 5000 )
    {
        e.Item.Cells[2].ForeColor = Color.Red;
        e.Item.Cells[2].Font.Bold = true;
    }
}
catch(Exception)
{
  // its not a valid number
}

That's the end, hope you like it, if you have any questions or queries please ask.

History

V10.0 11th-March-2005

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
United Kingdom United Kingdom
Frank Kerrigan

Currently developing Insurance systems with SQL Server, ASP.NET, C#, ADO for a company in Glasgow Scotland. Very keen on OOP and NUNIT testing. Been in IT forever (20 years) in mix of development and supporting applications / servers. Worked for companies big and small and enjoyed both.

Developed in (newest first) : C#, Progress 4GL, ASP.NET, SQL TSQL, HTML, VB.NET, ASP, VB, VBscript, JavaScript, Oracle PSQL, perl, Access v1-2000, sybase/informi, Pic Controllers, 6502 (ask your dad).

Msc .Net Development Evenings www.gcu.ac.uk
MCAD Passed
MCP C# ASP.NET Web Applications
MCP SQL Server 2000
HND Computing
OND / HNC Electrical Engineering,

Comments and Discussions

 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey15-Mar-12 20:48
professionalManoj Kumar Choubey15-Mar-12 20:48 
QuestionMy vote of 5 Pin
alican_23-Jun-11 4:11
alican_23-Jun-11 4:11 
AnswerRe: My vote of 5 Pin
Frank Kerrigan11-Oct-11 5:08
Frank Kerrigan11-Oct-11 5:08 
GeneralMake a particular value Bold Pin
Nirene24-Jul-08 23:21
Nirene24-Jul-08 23:21 
GeneralVery Very Useful... Pin
visitraajes17-Jun-08 4:02
visitraajes17-Jun-08 4:02 
GeneralRe: Very Very Useful... Pin
Frank Kerrigan17-Jun-08 4:22
Frank Kerrigan17-Jun-08 4:22 
GeneralI wrote a similar article about Nested GridView controls Pin
azamsharp24-Jan-08 16:10
azamsharp24-Jan-08 16:10 
Questionthanks alot and i have another question Pin
MJ.MF2-Nov-07 8:03
MJ.MF2-Nov-07 8:03 
Questionan advanced datagrid Pin
MJ.MF31-Oct-07 23:00
MJ.MF31-Oct-07 23:00 
AnswerRe: an advanced datagrid Pin
Frank Kerrigan1-Nov-07 12:26
Frank Kerrigan1-Nov-07 12:26 
QuestionChange Header Change Pin
| Muhammad Waqas Butt |13-Jul-07 21:13
professional| Muhammad Waqas Butt |13-Jul-07 21:13 
Generalpls help Pin
Lee Chin Meng23-Apr-07 17:41
Lee Chin Meng23-Apr-07 17:41 
Questionhow can Implements my Functional? [modified] Pin
jame_peng15-Oct-06 2:54
jame_peng15-Oct-06 2:54 
AnswerRe: how can Implements my Functional? Pin
Frank Kerrigan20-Nov-06 5:53
Frank Kerrigan20-Nov-06 5:53 
GeneralRe: how can Implements my Functional? Pin
Colin Angus Mackay6-Dec-06 3:22
Colin Angus Mackay6-Dec-06 3:22 
GeneralRe: how can Implements my Functional? Pin
Frank Kerrigan6-Dec-06 3:24
Frank Kerrigan6-Dec-06 3:24 
GeneralGreat Article Pin
parasJ4-Apr-06 19:16
parasJ4-Apr-06 19:16 
Questionhow about in VB Pin
Guerven8-Mar-06 14:21
Guerven8-Mar-06 14:21 
AnswerRe: how about in VB Pin
Frank Kerrigan9-Mar-06 8:45
Frank Kerrigan9-Mar-06 8:45 
QuestionFormating the currency data Pin
Hendrik (Chrysonite)19-Jan-06 23:22
Hendrik (Chrysonite)19-Jan-06 23:22 
AnswerRe: Formating the currency data Pin
JJ Saito17-Jan-07 8:42
JJ Saito17-Jan-07 8:42 
Try to use Regular Expressions. Search here in codeproject.;)

JJ Saito

Generalproject Pin
sood_is_in5-Jan-06 0:57
sood_is_in5-Jan-06 0:57 
GeneralRe: project Pin
Frank Kerrigan5-Jan-06 13:20
Frank Kerrigan5-Jan-06 13:20 
GeneralBetter way to highlight cells Pin
Anonymous27-Jul-05 4:02
Anonymous27-Jul-05 4:02 
GeneralGreat Article! Pin
ChingB30-May-05 23:20
ChingB30-May-05 23:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.